From 92017817240861108e6ce731674f09b2e27d9c49 Mon Sep 17 00:00:00 2001 From: Jack Morgan Date: Thu, 17 Jun 2021 11:08:01 +1200 Subject: [PATCH 001/195] Update make_resources command to take parameters --- dev | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev b/dev index 8205b6fa8..8a56c97c4 100755 --- a/dev +++ b/dev @@ -161,7 +161,7 @@ defhelp makeresourcethumbnails 'Run Django makeresourcethumbnails command.' # Run Django makeresources command cmd_make_resources() { echo "Creating static resource PDFs..." - docker-compose -f docker-compose.local.yml run --rm django python ./manage.py makeresources + docker-compose -f docker-compose.local.yml run --rm django python ./manage.py makeresources "$@" } defhelp makeresources 'Run Django makeresources command.' From 4ddc1e12eb9541870943645178aabac4e1d7c165 Mon Sep 17 00:00:00 2001 From: Jack Morgan Date: Thu, 17 Jun 2021 11:08:31 +1200 Subject: [PATCH 002/195] Update makeresources command logging --- csunplugged/resources/management/commands/makeresources.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csunplugged/resources/management/commands/makeresources.py b/csunplugged/resources/management/commands/makeresources.py index bd81fa50c..1fd351888 100644 --- a/csunplugged/resources/management/commands/makeresources.py +++ b/csunplugged/resources/management/commands/makeresources.py @@ -78,7 +78,6 @@ def create_resource_pdf(self, resource, combination, language_code, base_path): language_code (str): Code for language. base_path (str): Base path for outputting P """ - print(" - Creating PDF in '{}'".format(language_code)) with translation.override(language_code): if resource.copies: combination["copies"] = settings.RESOURCE_COPY_AMOUNT @@ -94,3 +93,4 @@ def create_resource_pdf(self, resource, combination, language_code, base_path): pdf_file_output = open(os.path.join(pdf_directory, filename), "wb") pdf_file_output.write(pdf_file) pdf_file_output.close() + print(" - Created PDF '{}' in '{}'".format(filename, language_code)) From 9088fecd4d1dbbe5ff0d8bd90dd78474e0b2f6fd Mon Sep 17 00:00:00 2001 From: Jack Morgan Date: Thu, 17 Jun 2021 11:09:47 +1200 Subject: [PATCH 003/195] Update binary windows printable to use one page FIxes #1596 --- .../BinaryWindowsResourceGenerator.py | 243 ++++++++++++------ .../img/resources/binary-windows/dots-1.png | Bin 0 -> 9176 bytes .../img/resources/binary-windows/dots-128.png | Bin 0 -> 56499 bytes .../img/resources/binary-windows/dots-16.png | Bin 0 -> 28022 bytes .../img/resources/binary-windows/dots-2.png | Bin 0 -> 11377 bytes .../img/resources/binary-windows/dots-32.png | Bin 0 -> 34737 bytes .../img/resources/binary-windows/dots-4.png | Bin 0 -> 15086 bytes .../img/resources/binary-windows/dots-64.png | Bin 0 -> 45728 bytes .../img/resources/binary-windows/dots-8.png | Bin 0 -> 23895 bytes .../binary-windows/lightbulb-off.png | Bin 0 -> 55097 bytes .../resources/binary-windows/lightbulb-on.png | Bin 0 -> 63253 bytes 11 files changed, 171 insertions(+), 72 deletions(-) create mode 100755 csunplugged/static/img/resources/binary-windows/dots-1.png create mode 100755 csunplugged/static/img/resources/binary-windows/dots-128.png create mode 100755 csunplugged/static/img/resources/binary-windows/dots-16.png create mode 100755 csunplugged/static/img/resources/binary-windows/dots-2.png create mode 100755 csunplugged/static/img/resources/binary-windows/dots-32.png create mode 100755 csunplugged/static/img/resources/binary-windows/dots-4.png create mode 100755 csunplugged/static/img/resources/binary-windows/dots-64.png create mode 100755 csunplugged/static/img/resources/binary-windows/dots-8.png create mode 100644 csunplugged/static/img/resources/binary-windows/lightbulb-off.png create mode 100644 csunplugged/static/img/resources/binary-windows/lightbulb-on.png diff --git a/csunplugged/resources/generators/BinaryWindowsResourceGenerator.py b/csunplugged/resources/generators/BinaryWindowsResourceGenerator.py index 2a05007e8..4197624d0 100644 --- a/csunplugged/resources/generators/BinaryWindowsResourceGenerator.py +++ b/csunplugged/resources/generators/BinaryWindowsResourceGenerator.py @@ -10,9 +10,15 @@ FONT_PATH = "static/fonts/PatrickHand-Regular.ttf" FONT = ImageFont.truetype(FONT_PATH, 300) SMALL_FONT = ImageFont.truetype(FONT_PATH, 180) +IMAGE_SIZE_X = 2334 +IMAGE_SIZE_Y = 1650 +LINE_COLOUR = "#000000" +LINE_WIDTH = 1 NUMBER_BITS_VALUES = { "4": _("Four (1 to 8)"), + "5": _("Five (1 to 16)"), + "6": _("Six (1 to 32)"), "8": _("Eight (1 to 128)"), } @@ -55,126 +61,219 @@ def data(self): A dictionary or list of dictionaries for each resource page. """ # Retrieve parameters - number_of_bits = self.options["number_bits"].value + number_of_bits = int(self.options["number_bits"].value) value_type = self.options["value_type"].value - dot_counts = self.options["dot_counts"].value + show_bits_value = self.options["dot_counts"].value + + # Define variables + column_width = IMAGE_SIZE_X / number_of_bits - pages = [] - page_sets = [("binary-windows-1-to-8.png", 8)] - if number_of_bits == "8": - page_sets.append(("binary-windows-16-to-128.png", 128)) - - for (filename, dot_count_start) in page_sets: - image = Image.open(os.path.join(BASE_IMAGE_PATH, filename)) - image = self.add_digit_values(image, value_type, True, 660, 724, 1700, FONT) - if dot_counts: - image = self.add_dot_counts(image, dot_count_start, SMALL_FONT) - image = image.rotate(90, expand=True) - pages.append({"type": "image", "data": image}) - pages.append(self.back_page(value_type)) - pages[0]["thumbnail"] = True + # Get page outline + page_outline = self.page_outline(number_of_bits, column_width) + front_page = self.front_page( + value_type, + column_width, + show_bits_value, + page_outline.copy() + ) + back_page = self.back_page( + value_type, + column_width, + page_outline.copy() + ) + pages = [front_page, back_page] return pages - def back_page(self, value_type): + def page_outline(self, number_of_bits, column_width): + page_outline = Image.new("RGB", (IMAGE_SIZE_X, IMAGE_SIZE_Y), "#fff") + draw = ImageDraw.Draw(page_outline) + image_midpoint_y = int(IMAGE_SIZE_Y / 2) + + # Draw outline + draw.rectangle( + [(0, 0), (IMAGE_SIZE_X - LINE_WIDTH, IMAGE_SIZE_Y - LINE_WIDTH)], + outline=LINE_COLOUR, + fill="#ffffff", + width=LINE_WIDTH, + ) + + # Draw internal separator lines + for line_number in range(1, number_of_bits): + x_coord = line_number * column_width + draw.line( + [(x_coord, 0), (x_coord, image_midpoint_y)], + fill=LINE_COLOUR, + width=LINE_WIDTH, + ) + + # Draw dashed line + dash_size = 10 + for x_coord in range(0, IMAGE_SIZE_X, dash_size * 3): + draw.line( + [(x_coord, image_midpoint_y), (x_coord + dash_size, image_midpoint_y)], + fill="#666666", + width=LINE_WIDTH, + ) + + return page_outline + + def front_page(self, value_type, column_width, show_bits_value, page_outline): + """Return a Pillow object of front page of Binary Windows. + + Args: + value_type (str): Type of value representation used. + column_width (float): Width of a bit column. + show_bits_value (bool): True if bit value labels should be shown. + page_outline (Pillow Draw): Outline of page to draw on. + + Returns: + A dictionary for the back page. + """ + image = self.add_dots(page_outline, column_width, show_bits_value) + image = self.add_digit_values(page_outline, column_width, value_type, True) + image = image.rotate(90, expand=True) + return {"type": "image", "data": image} + + def back_page(self, value_type, column_width, page_outline): """Return a Pillow object of back page of Binary Windows. Args: - value_type: Type of value representation used (str). + value_type (str): Type of value representation used. + column_width (float): Width of a bit column. + page_outline (Pillow Draw): Outline of page to draw on. Returns: A dictionary for the back page. """ - image = Image.open(os.path.join(BASE_IMAGE_PATH, "binary-windows-blank.png")) - image = self.add_digit_values(image, value_type, False, 660, 724, 650, FONT) + image = self.add_digit_values(page_outline, column_width, value_type, False) image = image.rotate(90, expand=True) return {"type": "image", "data": image} - def add_dot_counts(self, image, starting_value, font): - """Add dot count text onto image. + def add_dots(self, image, column_width, show_bits_value): + """Add binary values onto image. + + Note: This method adds dots from right to left on the page. Args: - image: The image to add text to (Pillow Image). - starting_value: Number on left window (int). - font: Font used for adding text (Pillow Font). + image (Pillow Image): The image to add binary values to. + column_width (float): Width of a bit column. + show_bits_value (bool): True if bit value labels should be shown. Returns: - Pillow Image with text added (Pillow Image). + Pillow Image with dots (Pillow Image). """ - value = starting_value draw = ImageDraw.Draw(image) - coord_x = 660 - coord_x_increment = 724 - coord_y = 1000 - for i in range(4): - text = str(value) - text_width, text_height = draw.textsize(text, font=font) - text_coord_x = coord_x - (text_width / 2) - text_coord_y = coord_y - (text_height / 2) - draw.text( - (text_coord_x, text_coord_y), - text, - font=font, - fill="#000" + coord_x_start = IMAGE_SIZE_X - (column_width / 2) + coord_x_increment = column_width + coord_x = coord_x_start + base_image_coord_y = IMAGE_SIZE_Y * 0.2 + base_text_coord_y = IMAGE_SIZE_Y * 0.4 + dots_value = 1 + + while coord_x > 0: + # Select dots image + image_file = f"dots-{dots_value}.png" + dots_image = Image.open(os.path.join(BASE_IMAGE_PATH, image_file)) + + # Scale image to fit dots to 80% of column width + (dots_width, dots_height) = dots_image.size + x_scale_factor = (column_width / dots_width) * 0.9 + y_scale_factor = (IMAGE_SIZE_Y * 0.3) / dots_height + scale_factor = min(x_scale_factor, y_scale_factor) + dots_image = dots_image.resize(( + int(dots_width * scale_factor), + int(dots_height * scale_factor), + )) + + # Paste into image + (dots_width, dots_height) = dots_image.size + coords = ( + int(coord_x - (dots_width / 2)), + int(base_image_coord_y - (dots_height / 2)), ) - coord_x += coord_x_increment - value = int(value / 2) + image.paste(dots_image, box=coords, mask=dots_image) + + if show_bits_value: + text = str(dots_value) + text_width, text_height = draw.textsize(text, font=SMALL_FONT) + text_coord_x = coord_x - (text_width / 2) + text_coord_y = base_text_coord_y - (text_height / 2) + draw.text( + (text_coord_x, text_coord_y), + text, + font=SMALL_FONT, + fill="#000" + ) + + # Update variables + coord_x -= coord_x_increment + dots_value *= 2 return image - def add_digit_values(self, image, value_type, on, x_coord_start, x_coord_increment, base_y_coord, font): + def add_digit_values(self, image, column_width, value_type, on): """Add binary values onto image. Args: - image: The image to add binary values to (Pillow Image). - value_type: Either "binary" for 0's and 1's, or "lightbulb" for - lit and unlit lightbulbs (str). - on: True if binary value is on/lit, otherwise False (bool). - x_coord_start: X co-ordinate starting value (int). - x_coord_increment: X co-ordinate increment value (int). - base_y_coord: Y co-ordinate value (int). - font: Font used for adding text (Pillow Font). + image (Pillow Image): The image to add binary values to. + column_width (float): Width of a bit column. + value_type (str): Either "binary" for 0's and 1's, or "lightbulb" for + lit and unlit lightbulbs. + on (bool): True if binary value is on/lit, otherwise False. Returns: Pillow Image with binary values (Pillow Image). """ - text_coord_x = x_coord_start + coord_x_start = column_width / 2 + coord_x_increment = column_width if value_type == "binary": if on: text = "1" else: text = "0" - else: # lightbulb + else: # Lightbulb if on: - image_file = "col_binary_lightbulb.png" + image_file = "lightbulb-on.png" else: - image_file = "col_binary_lightbulb_off.png" - lightbulb = Image.open(os.path.join("static/img/topics/", image_file)) - (width, height) = lightbulb.size - scale_factor = 0.6 - lightbulb = lightbulb.resize((int(width * scale_factor), int(height * scale_factor))) - (width, height) = lightbulb.size - lightbulb_width = int(width / 2) - lightbulb_height = int(height / 2) + image_file = "lightbulb-off.png" + lightbulb = Image.open(os.path.join(BASE_IMAGE_PATH, image_file)) + (lightbulb_width, lightbulb_height) = lightbulb.size + # Scale image to fit lightbulb to 80% of column width + scale_factor = (column_width / lightbulb_width) * 0.8 + lightbulb = lightbulb.resize(( + int(lightbulb_width * scale_factor), + int(lightbulb_height * scale_factor), + )) + (lightbulb_width, lightbulb_height) = lightbulb.size if not on: lightbulb = lightbulb.rotate(180) - for i in range(4): - draw = ImageDraw.Draw(image) - if value_type == "binary": + draw = ImageDraw.Draw(image) + coord_x = coord_x_start - text_width, text_height = draw.textsize(text, font=font) - coord_x = text_coord_x - (text_width / 2) - coord_y = base_y_coord - (text_height / 2) + if on: + base_coord_y = IMAGE_SIZE_Y * 0.75 + else: + base_coord_y = IMAGE_SIZE_Y * 0.25 + + while coord_x < IMAGE_SIZE_X: + if value_type == "binary": + text_width, text_height = draw.textsize(text, font=FONT) + text_coord_x = coord_x - (text_width / 2) + text_coord_y = base_coord_y - (text_height * .7) draw.text( - (coord_x, coord_y), + (text_coord_x, text_coord_y), text, - font=font, + font=FONT, fill="#000" ) else: # lightbulb - coords = (text_coord_x - lightbulb_width, base_y_coord - lightbulb_height + 75) + coords = ( + int(coord_x - (lightbulb_width / 2)), + int(base_coord_y - (lightbulb_height / 2)), + ) image.paste(lightbulb, box=coords, mask=lightbulb) - text_coord_x += x_coord_increment + coord_x += coord_x_increment return image @property diff --git a/csunplugged/static/img/resources/binary-windows/dots-1.png b/csunplugged/static/img/resources/binary-windows/dots-1.png new file mode 100755 index 0000000000000000000000000000000000000000..0c32356e308ff7f71581fd6a559fb6ff325dd838 GIT binary patch literal 9176 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 literal 0 HcmV?d00001 diff --git a/csunplugged/static/img/resources/binary-windows/dots-128.png b/csunplugged/static/img/resources/binary-windows/dots-128.png new file mode 100755 index 0000000000000000000000000000000000000000..b858bdff37b5df94231fdfa38a731a80bd8d3ea9 GIT binary patch literal 56499 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 literal 0 HcmV?d00001 diff --git a/csunplugged/static/img/resources/binary-windows/dots-2.png b/csunplugged/static/img/resources/binary-windows/dots-2.png new file mode 100755 index 0000000000000000000000000000000000000000..36444bc0a5f10815c8f0feccb7bba954daf04e0e GIT binary patch literal 11377 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 KNzr5TH~$H=HDHeb literal 0 HcmV?d00001 diff --git a/csunplugged/static/img/resources/binary-windows/dots-4.png b/csunplugged/static/img/resources/binary-windows/dots-4.png new file mode 100755 index 0000000000000000000000000000000000000000..f9b33a35a89eccf7343572923c2afd8c5933538e GIT binary patch literal 15086 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 Date: Mon, 4 Apr 2022 02:07:27 +0000 Subject: [PATCH 004/195] Bump tqdm from 4.62.3 to 4.64.0 Bumps [tqdm](https://github.com/tqdm/tqdm) from 4.62.3 to 4.64.0. - [Release notes](https://github.com/tqdm/tqdm/releases) - [Commits](https://github.com/tqdm/tqdm/compare/v4.62.3...v4.64.0) --- updated-dependencies: - dependency-name: tqdm dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/base.txt b/requirements/base.txt index d9e53ac06..4a92d4425 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -29,7 +29,7 @@ django-widget-tweaks==1.4.12 PyYAML==6.0 # System tools -tqdm==4.62.3 +tqdm==4.64.0 # XML Parsing lxml==4.7.1 From 4e68164f96b6af3e11c97142a06d9c881e7163b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Apr 2022 02:08:35 +0000 Subject: [PATCH 005/195] Bump actions/download-artifact from 2 to 3 Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 2 to 3. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/test-and-deploy.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-and-deploy.yaml b/.github/workflows/test-and-deploy.yaml index 4aac92b0f..7207dbaca 100644 --- a/.github/workflows/test-and-deploy.yaml +++ b/.github/workflows/test-and-deploy.yaml @@ -266,7 +266,7 @@ jobs: uses: actions/checkout@v2 - name: Download all workflow run artifacts - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: path: artifacts/ From ae408163f683385f4a243cf693338310560011a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Apr 2022 21:56:13 +0000 Subject: [PATCH 006/195] Bump pypdf2 from 1.26.0 to 1.27.5 in /requirements Bumps [pypdf2](https://github.com/py-pdf/PyPDF2) from 1.26.0 to 1.27.5. - [Release notes](https://github.com/py-pdf/PyPDF2/releases) - [Changelog](https://github.com/py-pdf/PyPDF2/blob/main/CHANGELOG) - [Commits](https://github.com/py-pdf/PyPDF2/compare/1.26.0...1.27.5) --- updated-dependencies: - dependency-name: pypdf2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements/test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/test.txt b/requirements/test.txt index 146a76991..84c2025a5 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -11,4 +11,4 @@ coverage==6.2 django-test-without-migrations==0.6 # PDF file checking -PyPDF2==1.26.0 +PyPDF2==1.27.5 From f72ff75804631ca046c80c229943ec1fe45f8053 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 May 2022 02:07:44 +0000 Subject: [PATCH 007/195] Bump docker/metadata-action from 3 to 4 Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 3 to 4. - [Release notes](https://github.com/docker/metadata-action/releases) - [Upgrade guide](https://github.com/docker/metadata-action/blob/master/UPGRADE.md) - [Commits](https://github.com/docker/metadata-action/compare/v3...v4) --- updated-dependencies: - dependency-name: docker/metadata-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/test-and-deploy.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-and-deploy.yaml b/.github/workflows/test-and-deploy.yaml index 4aac92b0f..29236ca9a 100644 --- a/.github/workflows/test-and-deploy.yaml +++ b/.github/workflows/test-and-deploy.yaml @@ -291,7 +291,7 @@ jobs: - name: Setup Docker metadata id: meta - uses: docker/metadata-action@v3 + uses: docker/metadata-action@v4 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | From 86b69e53aeec00893f1de22a693e13c19cbb8864 Mon Sep 17 00:00:00 2001 From: JackMorganNZ Date: Mon, 16 May 2022 14:10:50 +1200 Subject: [PATCH 008/195] Fix date typo --- docs/changelog.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 895663db7..f5b4fbac8 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -26,7 +26,7 @@ All notable changes to this project will be documented in this file. 6.5.0 ============================================================================== -**Release date:** 19th December 2022 +**Release date:** 19th December 2021 **Changelog:** From 92ac166d4835e423b85333d709369413efe0261c Mon Sep 17 00:00:00 2001 From: JackMorganNZ Date: Mon, 16 May 2022 14:20:51 +1200 Subject: [PATCH 009/195] Delete unused assets --- .../binary-windows/binary-windows-1-to-8.png | Bin 54653 -> 0 bytes .../binary-windows/binary-windows-16-to-128.png | Bin 78502 -> 0 bytes .../binary-windows/binary-windows-blank.png | Bin 39159 -> 0 bytes 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 csunplugged/static/img/resources/binary-windows/binary-windows-1-to-8.png delete mode 100644 csunplugged/static/img/resources/binary-windows/binary-windows-16-to-128.png delete mode 100644 csunplugged/static/img/resources/binary-windows/binary-windows-blank.png diff --git a/csunplugged/static/img/resources/binary-windows/binary-windows-1-to-8.png b/csunplugged/static/img/resources/binary-windows/binary-windows-1-to-8.png deleted file mode 100644 index 96738e67794021067dc4dbd6a1745dab2ae449b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54653 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 E1DBvsw*UYD diff --git a/csunplugged/static/img/resources/binary-windows/binary-windows-16-to-128.png b/csunplugged/static/img/resources/binary-windows/binary-windows-16-to-128.png deleted file mode 100644 index 935fe9b551b5bd96225392dd32fec1dd25a8467c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78502 zcmeFYXH-*77e9Is6;Y9<6lo$&g(yXOvr?p~^xkXeNDTp0q)1c1&_PA%5LyCARp|jj z4;`d;q$G5>C-}VY_5FXj>wdT&?pn{R<-$yI_RQHcv-fZR_MXtEs`3=)ubu}0fI?B> z(R1)mDFBcco;wTn>^xQe4gMi_R?u|=fZH6ze0VmZbJ8m3W^D! z=UTQU<=my+7nk@II%k7#`pt*_grbN8|J(l6z`q*!R|EfQ;9m{=tAT$t@c*p_oa1B- zPMO^Q$@SMT<-^Y80e$C6NqBwS$^YtKVc&R~G;ToPH_tKONUk5B<;Q5Gote zzdNoy_(<{h=YVtn4+4PlJe;S@Pp(ryfO=!--cMSkK83zLor-s0;{#*Rk^td|(W${c)u*RJ*7 z89zEa7(M+$YbnafDa~+bYt&fO|M=T41MiC6-P}Cme}n*q`TygTZ$&O0?=!C)QYk(^ zHc8U*2j;;&LUniY(Qm^rv@sdqkbEx3G=!FKc!TkHbA=Ebh|nCRn#c z6g`y<_wWxuJ<-=n5lYj=Xi?6-BmxA%WD1fK37!-H{~Hyh6VXYC-p=8wYt83By%SiN z^Y_rnd|vn4BX5P_E_2LW{?0hfC8jCy77? z569N8?tIZ8N1uC|PunfdDkU0u9sZ1~?%NMmT_@C7JozGYVi7vzl}X3E+Ov0I;^qJG z)&&`5Zo%jFgH|NQ5-^phg&PCfhmR_?9Mok8c_ha~1)bX zQM%P@Tp9R)brhjd-JcZDaqCdFp|7(A&%3Mqdmg>KF%q=*2u@*exNBFQ{C>!*|Bk}I zIz9I(+^tc(CM;4Kqg0 z2HeIkQe^2M^U$i=q0yfsq#49D_QgWJVT9{1n=dyh_^_ZgmxIK$?$MnA)K9js8+i%oaSIdqd0H|ZOPJKuMh<(rC(so{pi{|Zk z-L(k+wpBf zqSg^eoY@lY#$D~@!%sCq(zD+=7OB6Z-M5RE-TRh=+#CvIvaMM6f-Y?Mo&)uq?0x$T zFmXBwp@GwHAJ;Kj!Sosxs+81H$%?R8=Z?zD<$8L3(c6LE4VD|gC9GeNj2t$+WJb{9 z84%Q~zK1C=&uu;M@<{UegkS0s-h7rP{jnwpi$jOPUhUWUZ95*Kt<&7&;DheZ>f(4^ zL{6Wav@v0z?y?9Z+p#}RpSS%@7r~d~;pa51-3Q0i@L1O1>OLuhXDbe8tNSDkiZ+w1 zO&G!q%8iUn;YY#MlJ^{$wCT>gO=zvTh-~X@RY3B|9^w34q#{)mIYS(i)f>Kfa?^(1 zBfSO`H)w5emRiE5G{}e0dY_M6toS1B%$0r�JigY(hg^B64%2M|>YWA9h#_73je> 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 From 752dc77da1a9b425e9df28e0a6d8ced51bd47f7d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 May 2022 02:10:48 +0000 Subject: [PATCH 010/195] Bump pillow from 9.0.0 to 9.1.1 Bumps [pillow](https://github.com/python-pillow/Pillow) from 9.0.0 to 9.1.1. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/9.0.0...9.1.1) --- updated-dependencies: - dependency-name: pillow dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/base.txt b/requirements/base.txt index d9e53ac06..94eb88cf5 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -12,7 +12,7 @@ psycopg2==2.9.3 # Resources WeasyPrint==52.4 -Pillow==9.0.0 +Pillow==9.1.1 yattag==1.14.0 tinycss==0.4 From 2a70a8f78ac975092892f86be183227cbbcd3c28 Mon Sep 17 00:00:00 2001 From: JackMorganNZ Date: Thu, 26 May 2022 14:46:21 +1200 Subject: [PATCH 011/195] Rewrite search application This rewrite of the search application removes the requirement of elasticsearch and the django-haystack dependency. The following features are yet to be readded: - Curriculum area filter - Pagination The system could also benefit from a generic search index, so only one table needs to be queried, instead of every type of model. --- .../migrations/0013_auto_20220520_0506.py | 24 +++ csunplugged/at_home/models.py | 25 ++- .../migrations/0004_auto_20220520_0454.py | 24 +++ csunplugged/classic/models.py | 22 +++ csunplugged/classic/search_indexes.py | 31 --- csunplugged/config/settings/base.py | 17 +- .../general/management/commands/updatedata.py | 2 +- .../migrations/0003_auto_20220520_0501.py | 24 +++ csunplugged/general/models.py | 24 +++ csunplugged/general/search_indexes.py | 56 ------ .../BinaryWindowsResourceGenerator.py | 9 + .../migrations/0021_auto_20220520_0454.py | 24 +++ csunplugged/resources/models.py | 21 +- csunplugged/resources/search_indexes.py | 18 -- csunplugged/search/forms.py | 65 ------ .../management/commands/rebuild_index.py | 38 ---- .../commands/rebuild_search_indexes.py | 19 ++ csunplugged/search/settings.py | 126 ++++++++++++ csunplugged/search/templatetags/__init__.py | 1 + .../search/templatetags/search_result.py | 20 ++ csunplugged/search/urls.py | 2 +- csunplugged/search/utils.py | 138 +++++++++++++ csunplugged/search/views.py | 187 ++++++++++-------- csunplugged/static/js/website-search.js | 116 +++++------ csunplugged/static/scss/search.scss | 7 +- .../search/curriculum-area-option.html | 3 + csunplugged/templates/search/index.html | 150 ++++++++++++++ .../search/result/at_home.activity.html | 5 + .../search/result/classic.classicpage.html | 5 + .../templates/search/result/classicpage.html | 5 - .../search/result/general.generalpage.html | 5 + .../templates/search/result/generalpage.html | 5 - .../search/result/programmingchallenge.html | 20 -- .../templates/search/result/resource.html | 5 - .../search/result/resources.resource.html | 5 + .../templates/search/result/topic.html | 5 - ...html => topics.curriculumintegration.html} | 10 +- .../{lesson.html => topics.lesson.html} | 16 +- .../result/topics.programmingchallenge.html | 20 ++ .../templates/search/result/topics.topic.html | 5 + .../search/result/topics.unitplan.html | 15 ++ .../templates/search/result/unitplan.html | 15 -- csunplugged/templates/search/search.html | 176 ----------------- .../migrations/0102_auto_20220516_0335.py | 24 +++ .../migrations/0103_auto_20220519_2311.py | 24 +++ .../migrations/0104_auto_20220520_0454.py | 42 ++++ csunplugged/topics/models.py | 122 ++++++++++++ csunplugged/topics/search_indexes.py | 183 ----------------- dev | 6 +- docker-compose.local.yml | 10 +- docker-compose.prod.yml | 18 +- docs/getting_started/helper_commands.rst | 9 - requirements/base.txt | 7 +- 53 files changed, 1116 insertions(+), 839 deletions(-) create mode 100644 csunplugged/at_home/migrations/0013_auto_20220520_0506.py create mode 100644 csunplugged/classic/migrations/0004_auto_20220520_0454.py delete mode 100644 csunplugged/classic/search_indexes.py create mode 100644 csunplugged/general/migrations/0003_auto_20220520_0501.py delete mode 100644 csunplugged/general/search_indexes.py create mode 100644 csunplugged/resources/migrations/0021_auto_20220520_0454.py delete mode 100644 csunplugged/resources/search_indexes.py delete mode 100644 csunplugged/search/forms.py delete mode 100644 csunplugged/search/management/commands/rebuild_index.py create mode 100644 csunplugged/search/management/commands/rebuild_search_indexes.py create mode 100644 csunplugged/search/settings.py create mode 100644 csunplugged/search/templatetags/__init__.py create mode 100644 csunplugged/search/templatetags/search_result.py create mode 100644 csunplugged/search/utils.py create mode 100644 csunplugged/templates/search/curriculum-area-option.html create mode 100644 csunplugged/templates/search/index.html create mode 100644 csunplugged/templates/search/result/at_home.activity.html create mode 100644 csunplugged/templates/search/result/classic.classicpage.html delete mode 100644 csunplugged/templates/search/result/classicpage.html create mode 100644 csunplugged/templates/search/result/general.generalpage.html delete mode 100644 csunplugged/templates/search/result/generalpage.html delete mode 100644 csunplugged/templates/search/result/programmingchallenge.html delete mode 100644 csunplugged/templates/search/result/resource.html create mode 100644 csunplugged/templates/search/result/resources.resource.html delete mode 100644 csunplugged/templates/search/result/topic.html rename csunplugged/templates/search/result/{curriculumintegration.html => topics.curriculumintegration.html} (54%) rename csunplugged/templates/search/result/{lesson.html => topics.lesson.html} (63%) create mode 100644 csunplugged/templates/search/result/topics.programmingchallenge.html create mode 100644 csunplugged/templates/search/result/topics.topic.html create mode 100644 csunplugged/templates/search/result/topics.unitplan.html delete mode 100644 csunplugged/templates/search/result/unitplan.html delete mode 100644 csunplugged/templates/search/search.html create mode 100644 csunplugged/topics/migrations/0102_auto_20220516_0335.py create mode 100644 csunplugged/topics/migrations/0103_auto_20220519_2311.py create mode 100644 csunplugged/topics/migrations/0104_auto_20220520_0454.py delete mode 100644 csunplugged/topics/search_indexes.py diff --git a/csunplugged/at_home/migrations/0013_auto_20220520_0506.py b/csunplugged/at_home/migrations/0013_auto_20220520_0506.py new file mode 100644 index 000000000..527022ff8 --- /dev/null +++ b/csunplugged/at_home/migrations/0013_auto_20220520_0506.py @@ -0,0 +1,24 @@ +# Generated by Django 3.2.11 on 2022-05-20 05:06 + +import django.contrib.postgres.indexes +import django.contrib.postgres.search +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('at_home', '0012_auto_20210929_2238'), + ] + + operations = [ + migrations.AddField( + model_name='activity', + name='search_vector', + field=django.contrib.postgres.search.SearchVectorField(null=True), + ), + migrations.AddIndex( + model_name='activity', + index=django.contrib.postgres.indexes.GinIndex(fields=['search_vector'], name='at_home_act_search__0470ab_gin'), + ), + ] diff --git a/csunplugged/at_home/models.py b/csunplugged/at_home/models.py index b4411353b..7bd5b11d8 100644 --- a/csunplugged/at_home/models.py +++ b/csunplugged/at_home/models.py @@ -4,17 +4,20 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ from utils.TranslatableModel import TranslatableModel +from django.contrib.postgres.search import SearchVectorField +from django.contrib.postgres.indexes import GinIndex class Activity(TranslatableModel): """Model for an activity in database.""" - MODEL_NAME = _("Activity") + MODEL_NAME = _("At Home Activity") slug = models.SlugField(max_length=100) name = models.CharField(max_length=150, default="") icon = models.CharField(max_length=150, null=True) order_number = models.PositiveSmallIntegerField(unique=True) + search_vector = SearchVectorField(null=True) # The following are stored as HTML from Markdown files introduction = models.TextField(default="") inside_the_computer = models.TextField(default="") @@ -40,10 +43,30 @@ def __str__(self): """ return self.name + def index_contents(self): + """Return dictionary for search indexing. + + Returns: + Dictionary of content for search indexing. The dictionary keys + are the weightings of content, and the dictionary values + are strings of content to index. + """ + text = ( + self.introduction + self.inside_the_computer + + self.project + self.more_information + ) + return { + 'A': self.name, + 'B': text, + } + class Meta: """Set consistent ordering of activities.""" ordering = ["order_number", ] + indexes = [ + GinIndex(fields=['search_vector']) + ] class Challenge(TranslatableModel): diff --git a/csunplugged/classic/migrations/0004_auto_20220520_0454.py b/csunplugged/classic/migrations/0004_auto_20220520_0454.py new file mode 100644 index 000000000..c3994c71f --- /dev/null +++ b/csunplugged/classic/migrations/0004_auto_20220520_0454.py @@ -0,0 +1,24 @@ +# Generated by Django 3.2.11 on 2022-05-20 04:54 + +import django.contrib.postgres.indexes +import django.contrib.postgres.search +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('classic', '0003_alter_classicpage_id'), + ] + + operations = [ + migrations.AddField( + model_name='classicpage', + name='search_vector', + field=django.contrib.postgres.search.SearchVectorField(null=True), + ), + migrations.AddIndex( + model_name='classicpage', + index=django.contrib.postgres.indexes.GinIndex(fields=['search_vector'], name='classic_cla_search__3a2336_gin'), + ), + ] diff --git a/csunplugged/classic/models.py b/csunplugged/classic/models.py index a27eaf391..43cbe3097 100644 --- a/csunplugged/classic/models.py +++ b/csunplugged/classic/models.py @@ -2,6 +2,8 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ +from django.contrib.postgres.search import SearchVectorField +from django.contrib.postgres.indexes import GinIndex class ClassicPage(models.Model): @@ -13,6 +15,7 @@ class ClassicPage(models.Model): slug = models.SlugField(unique=True) name = models.CharField(max_length=200) redirect = models.URLField() + search_vector = SearchVectorField(null=True) def get_absolute_url(self): """Return the canonical URL for a ClassicPage. @@ -29,3 +32,22 @@ def __str__(self): Name of page (str). """ return self.name + + def index_contents(self): + """Return dictionary for search indexing. + + Returns: + Dictionary of content for search indexing. The dictionary keys + are the weightings of content, and the dictionary values + are strings of content to index. + """ + return { + 'A': self.name, + } + + class Meta: + """Meta options for model.""" + + indexes = [ + GinIndex(fields=['search_vector']) + ] diff --git a/csunplugged/classic/search_indexes.py b/csunplugged/classic/search_indexes.py deleted file mode 100644 index cb5a71531..000000000 --- a/csunplugged/classic/search_indexes.py +++ /dev/null @@ -1,31 +0,0 @@ -"""Search index for ClassicPage model.""" - -from haystack import indexes -from classic.models import ClassicPage - - -class ClassicPageIndex(indexes.SearchIndex, indexes.Indexable): - """Search index for ClassicPage model.""" - - text = indexes.CharField(document=True, use_template=True) - - def prepare(self, obj): - """Set boost of ClassicPage model for index. - - Args: - obj (ClassicPage): ClassicPage object. - - Returns: - Dictionary of data. - """ - data = super(ClassicPageIndex, self).prepare(obj) - data["_boost"] = 0.6 - return data - - def get_model(self): - """Return the Resource model. - - Returns: - Resource object. - """ - return ClassicPage diff --git a/csunplugged/config/settings/base.py b/csunplugged/config/settings/base.py index c5e69ba0b..b0de5e22d 100644 --- a/csunplugged/config/settings/base.py +++ b/csunplugged/config/settings/base.py @@ -33,11 +33,10 @@ "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", + # Full text search "django.contrib.postgres", - # Useful template tags "django.contrib.humanize", - # Admin "django.contrib.admin", ] @@ -45,8 +44,6 @@ THIRD_PARTY_APPS = [ "corsheaders", "django_bootstrap_breadcrumbs", - "haystack", - "widget_tweaks", "modeltranslation", "bidiutils", ] @@ -336,18 +333,6 @@ }, ] -# SEARCH CONFIGURATION -# ------------------------------------------------------------------------------ -# See: http://django-haystack.readthedocs.io/en/v2.6.0/settings.html -HAYSTACK_CONNECTIONS = { - 'default': { - 'ENGINE': 'haystack.backends.elasticsearch5_backend.Elasticsearch5SearchEngine', - 'URL': 'elasticsearch:9200', - 'INDEX_NAME': 'haystack', - }, -} -HAYSTACK_SEARCH_RESULTS_PER_PAGE = 10 - # OTHER SETTINGS # ------------------------------------------------------------------------------ DEPLOYED = env.bool("DEPLOYED") diff --git a/csunplugged/general/management/commands/updatedata.py b/csunplugged/general/management/commands/updatedata.py index 91fcffa4c..13a127d62 100644 --- a/csunplugged/general/management/commands/updatedata.py +++ b/csunplugged/general/management/commands/updatedata.py @@ -26,4 +26,4 @@ def handle(self, *args, **options): management.call_command("loadgeneralpages", lite_load=lite_load) management.call_command("loadclassicpages", lite_load=lite_load) management.call_command("loadactivities", lite_load=lite_load) - management.call_command("rebuild_index", "--noinput") + management.call_command("rebuild_search_indexes") diff --git a/csunplugged/general/migrations/0003_auto_20220520_0501.py b/csunplugged/general/migrations/0003_auto_20220520_0501.py new file mode 100644 index 000000000..ce455555c --- /dev/null +++ b/csunplugged/general/migrations/0003_auto_20220520_0501.py @@ -0,0 +1,24 @@ +# Generated by Django 3.2.11 on 2022-05-20 05:01 + +import django.contrib.postgres.indexes +import django.contrib.postgres.search +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('general', '0002_alter_generalpage_id'), + ] + + operations = [ + migrations.AddField( + model_name='generalpage', + name='search_vector', + field=django.contrib.postgres.search.SearchVectorField(null=True), + ), + migrations.AddIndex( + model_name='generalpage', + index=django.contrib.postgres.indexes.GinIndex(fields=['search_vector'], name='general_gen_search__2e3762_gin'), + ), + ] diff --git a/csunplugged/general/models.py b/csunplugged/general/models.py index 132fa7122..d0f09e835 100644 --- a/csunplugged/general/models.py +++ b/csunplugged/general/models.py @@ -3,6 +3,9 @@ from django.db import models from django.urls import reverse from django.utils.translation import ugettext_lazy as _ +from django.contrib.postgres.search import SearchVectorField +from django.contrib.postgres.indexes import GinIndex +from search.utils import get_template_text class GeneralPage(models.Model): @@ -15,6 +18,7 @@ class GeneralPage(models.Model): name = models.CharField(max_length=100) template = models.CharField(max_length=100) url_name = models.CharField(max_length=100) + search_vector = SearchVectorField(null=True) def get_absolute_url(self): """Return the canonical URL for a GeneralPage. @@ -31,3 +35,23 @@ def __str__(self): Name of page (str). """ return self.name + + def index_contents(self): + """Return dictionary for search indexing. + + Returns: + Dictionary of content for search indexing. The dictionary keys + are the weightings of content, and the dictionary values + are strings of content to index. + """ + return { + 'A': self.name, + 'B': get_template_text(self.template), + } + + class Meta: + """Meta options for model.""" + + indexes = [ + GinIndex(fields=['search_vector']) + ] diff --git a/csunplugged/general/search_indexes.py b/csunplugged/general/search_indexes.py deleted file mode 100644 index 976d43048..000000000 --- a/csunplugged/general/search_indexes.py +++ /dev/null @@ -1,56 +0,0 @@ -"""Search index for GeneralPage model.""" - -from haystack import indexes -from lxml.html import fromstring -from lxml.cssselect import CSSSelector -from django.template.loader import render_to_string -from django.template.exceptions import TemplateSyntaxError -from general.models import GeneralPage - -CONTENT_NOT_FOUND_ERROR_MESSAGE = ("General page requires content wrapped in " - "an element with ID 'general-page-content'") - - -class GeneralPageIndex(indexes.SearchIndex, indexes.Indexable): - """Search index for GeneralPage model.""" - - text = indexes.CharField(document=True) - - def prepare(self, obj): - """Set boost of GeneralPage model for index. - - Args: - obj (GeneralPage): GeneralPage object. - - Returns: - Dictionary of data. - """ - data = super(GeneralPageIndex, self).prepare(obj) - data["_boost"] = 0.8 - return data - - def prepare_text(self, obj): - """Return text for indexing. - - Args: - obj (GeneralPage): Object for indexing. - - Returns: - String for indexing. - """ - rendered = render_to_string(obj.template, {"LANGUAGE_CODE": "en"}) - html = fromstring(rendered) - selector = CSSSelector("#general-page-content") - try: - contents = selector(html)[0].text_content() - except IndexError: - raise TemplateSyntaxError(CONTENT_NOT_FOUND_ERROR_MESSAGE) - return contents - - def get_model(self): - """Return the GeneralPage model. - - Returns: - GeneralPage object. - """ - return GeneralPage diff --git a/csunplugged/resources/generators/BinaryWindowsResourceGenerator.py b/csunplugged/resources/generators/BinaryWindowsResourceGenerator.py index 4197624d0..ead268b5c 100644 --- a/csunplugged/resources/generators/BinaryWindowsResourceGenerator.py +++ b/csunplugged/resources/generators/BinaryWindowsResourceGenerator.py @@ -85,6 +85,15 @@ def data(self): return pages def page_outline(self, number_of_bits, column_width): + """Create outline (lines without content) for page. + + Args: + number_of_bits (int): Number of bits on page. + column_width (int): Width of each bit on page. + + Return: + Page outline as type Image. + """ page_outline = Image.new("RGB", (IMAGE_SIZE_X, IMAGE_SIZE_Y), "#fff") draw = ImageDraw.Draw(page_outline) image_midpoint_y = int(IMAGE_SIZE_Y / 2) diff --git a/csunplugged/resources/migrations/0021_auto_20220520_0454.py b/csunplugged/resources/migrations/0021_auto_20220520_0454.py new file mode 100644 index 000000000..4891abe4a --- /dev/null +++ b/csunplugged/resources/migrations/0021_auto_20220520_0454.py @@ -0,0 +1,24 @@ +# Generated by Django 3.2.11 on 2022-05-20 04:54 + +import django.contrib.postgres.indexes +import django.contrib.postgres.search +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('resources', '0020_alter_resource_id'), + ] + + operations = [ + migrations.AddField( + model_name='resource', + name='search_vector', + field=django.contrib.postgres.search.SearchVectorField(null=True), + ), + migrations.AddIndex( + model_name='resource', + index=django.contrib.postgres.indexes.GinIndex(fields=['search_vector'], name='resources_r_search__82e125_gin'), + ), + ] diff --git a/csunplugged/resources/models.py b/csunplugged/resources/models.py index 609baaf1e..271789ac1 100644 --- a/csunplugged/resources/models.py +++ b/csunplugged/resources/models.py @@ -4,6 +4,8 @@ from django.utils.translation import ugettext_lazy as _ from django.urls import reverse from utils.TranslatableModel import TranslatableModel +from django.contrib.postgres.search import SearchVectorField +from django.contrib.postgres.indexes import GinIndex class Resource(TranslatableModel): @@ -17,6 +19,7 @@ class Resource(TranslatableModel): generator_module = models.CharField(max_length=200) copies = models.BooleanField() content = models.TextField(default="") + search_vector = SearchVectorField(null=True) def get_absolute_url(self): """Return the canonical URL for a resource. @@ -37,7 +40,23 @@ def __str__(self): """ return self.name + def index_contents(self): + """Return dictionary for search indexing. + + Returns: + Dictionary of content for search indexing. The dictionary keys + are the weightings of content, and the dictionary values + are strings of content to index. + """ + return { + 'A': self.name, + 'B': self.content, + } + class Meta: - """Meta class settings.""" + """Meta options for model.""" ordering = ["name"] + indexes = [ + GinIndex(fields=['search_vector']) + ] diff --git a/csunplugged/resources/search_indexes.py b/csunplugged/resources/search_indexes.py deleted file mode 100644 index 7a7f985b0..000000000 --- a/csunplugged/resources/search_indexes.py +++ /dev/null @@ -1,18 +0,0 @@ -"""Search index for resources model.""" - -from haystack import indexes -from resources.models import Resource - - -class ResourceIndex(indexes.SearchIndex, indexes.Indexable): - """Search index for Resource model.""" - - text = indexes.CharField(document=True, use_template=True) - - def get_model(self): - """Return the Resource model. - - Returns: - Resource object. - """ - return Resource diff --git a/csunplugged/search/forms.py b/csunplugged/search/forms.py deleted file mode 100644 index 8b0e82b91..000000000 --- a/csunplugged/search/forms.py +++ /dev/null @@ -1,65 +0,0 @@ -"""Module for custom search form.""" -from django import forms -from haystack.forms import ModelSearchForm -from topics.models import ( - Lesson, - CurriculumIntegration, - CurriculumArea, -) - - -class CustomSearchForm(ModelSearchForm): - """Class for custom search form.""" - - curriculum_areas = forms.ModelMultipleChoiceField( - queryset=CurriculumArea.objects.all(), - required=False, - widget=None, - ) - - def search(self): - """Search index based off query. - - This method overrides the default ModelSearchForm search method to - modify the default result if a blank query string is given. The form - returns all items instead of zero items if a blank string is given. - - The original search method checks if the form is valid, however - with all fields being optional with no validation, the form is always - valid. Therefore logic for an invalid form is removed. - - Returns: - SearchQuerySet of search results. - """ - if not self.cleaned_data.get('q'): - search_query_set = all_items(self.searchqueryset.all()) - else: - search_query_set = self.searchqueryset.auto_query(self.cleaned_data['q']) - search_query_set = search_query_set.models(*self.get_models()) - - # Filter items by curriculum areas if given in query. - if self.cleaned_data["curriculum_areas"]: - # Currently the given filter is provided as a QuerySet, but the search - # index saves the curriculum areas for objects as a list of primary - # keys, stored as strings. Because of this, the logic below must - # covert the QuerySet of the filter into a list of primary key strings. - query_ids = list(map(str, self.cleaned_data["curriculum_areas"].values_list("pk", flat=True))) - # Only query models with curriculum_areas attribute. - models = set(self.get_models()).intersection([Lesson, CurriculumIntegration]) - search_query_set = search_query_set.models(*models).filter( - curriculum_areas__in=query_ids - ) - - return search_query_set - - -def all_items(searchqueryset): - """Return all items of SearchQuerySet. - - Args: - searchqueryset (SearchQuerySet): QuerySet of search items. - - Returns: - All items in index. - """ - return searchqueryset.all() diff --git a/csunplugged/search/management/commands/rebuild_index.py b/csunplugged/search/management/commands/rebuild_index.py deleted file mode 100644 index 84421fb70..000000000 --- a/csunplugged/search/management/commands/rebuild_index.py +++ /dev/null @@ -1,38 +0,0 @@ -"""Module for the overriden Django Haystack rebuild_index command.""" - -from haystack.management.commands import rebuild_index -from haystack.query import SearchQuerySet -from search.forms import all_items -from resources.models import Resource -from general.models import GeneralPage -from classic.models import ClassicPage -from topics.models import ( - Topic, - UnitPlan, - Lesson, - ProgrammingChallenge, - CurriculumIntegration, -) - - -class Command(rebuild_index.Command): - """Command class for the custom Django rebuild_index command.""" - - help = "Rebuild search index and check empty query returns all items." - - def handle(self, *args, **options): - """Automatically called when the rebuild_index command is given.""" - total_objects = Resource.objects.count() - total_objects += Topic.objects.count() - total_objects += UnitPlan.objects.count() - total_objects += Lesson.objects.count() - total_objects += ProgrammingChallenge.objects.count() - total_objects += CurriculumIntegration.objects.count() - total_objects += GeneralPage.objects.count() - total_objects += ClassicPage.objects.count() - super(Command, self).handle(*args, **options) - total_results = len(all_items(SearchQuerySet())) - if total_objects == total_results: - print("Search index loaded with {} items.".format(total_results)) - else: # pragma: no cover - raise Exception("Search all_items() method does not return all items.") diff --git a/csunplugged/search/management/commands/rebuild_search_indexes.py b/csunplugged/search/management/commands/rebuild_search_indexes.py new file mode 100644 index 000000000..e02c5067d --- /dev/null +++ b/csunplugged/search/management/commands/rebuild_search_indexes.py @@ -0,0 +1,19 @@ +"""Module for the custom Django rebuild_search_indexes command.""" + +from django.core import management +from django.db import transaction +from search.utils import get_search_index_updater +from search.settings import SEARCH_CLASSES_AND_BOOSTS + + +class Command(management.base.BaseCommand): + """Required command class for the custom Django rebuild_search_indexes command.""" + + help = "Rebuild search indexes in database." + + def handle(self, *args, **options): + """Automatically called when the command is given.""" + for model_data in SEARCH_CLASSES_AND_BOOSTS: + model = model_data['class'] + for instance in model.objects.all(): + transaction.on_commit(get_search_index_updater(instance)) diff --git a/csunplugged/search/settings.py b/csunplugged/search/settings.py new file mode 100644 index 000000000..9cbb17728 --- /dev/null +++ b/csunplugged/search/settings.py @@ -0,0 +1,126 @@ +"""Settings for the search application.""" + +from topics.models import ( + Topic, + UnitPlan, + Lesson, + ProgrammingChallenge, + CurriculumIntegration, + LessonNumber, + CurriculumArea, +) +from classic.models import ClassicPage +from resources.models import Resource +from general.models import GeneralPage +from at_home.models import Activity +from search.utils import ( + get_search_model_types, + get_model_filter_options, +) + +SEARCH_PAGINATION = 25 +SEARCH_RESULT_TEMPLATE_DIRECTORY = 'search/result/' + + +def lesson_render_function(lesson): + """Provide additional context for rendering lesson results. + + Args: + lesson (Lesson): Instance of search result. + + Returns: + Dictionary of additional items to add to the render context. + """ + lesson_ages = [] + lesson_numbers = LessonNumber.objects.filter(lesson=lesson).select_related('age_group') + for lesson_number in lesson_numbers: + lesson_ages.append( + { + "lower": lesson_number.age_group.ages.lower, + "upper": lesson_number.age_group.ages.upper, + "number": lesson_number.number, + } + ) + curriculum_areas = CurriculumArea.objects.filter( + learning_outcomes__in=lesson.learning_outcomes.all() + ).select_related('parent').distinct() + + additional_context = { + 'lesson_ages': lesson_ages, + 'curriculum_areas': curriculum_areas, + } + return additional_context + + +# List of dicts of class, boost value, required prefetches. +SEARCH_CLASSES_AND_BOOSTS = [ + { + 'class': Topic, + 'boost': 2, + 'curriculum_area_filtered': False, + 'select_related': [], + 'prefetch_related': [], + }, + { + 'class': UnitPlan, + 'boost': 1.5, + 'curriculum_area_filtered': False, + 'select_related': ['topic'], + 'prefetch_related': [], + }, + { + 'class': Lesson, + 'boost': 1.2, + 'curriculum_area_filtered': True, + 'select_related': ['topic', 'unit_plan', 'unit_plan__topic'], + 'prefetch_related': ['learning_outcomes'], + 'render_function': lesson_render_function, + }, + { + 'class': Resource, + 'boost': 1, + 'curriculum_area_filtered': False, + 'select_related': [], + 'prefetch_related': [], + }, + { + 'class': GeneralPage, + 'boost': 0.9, + 'curriculum_area_filtered': False, + 'select_related': [], + 'prefetch_related': [], + }, + { + 'class': Activity, + 'boost': 0.8, + 'curriculum_area_filtered': False, + 'select_related': [], + 'prefetch_related': [], + }, + { + 'class': CurriculumIntegration, + 'boost': 0.7, + 'curriculum_area_filtered': True, + 'select_related': ['topic'], + 'prefetch_related': ['curriculum_areas', 'curriculum_areas__parent'], + }, + { + 'class': ClassicPage, + 'boost': 0.6, + 'curriculum_area_filtered': False, + 'select_related': [], + 'prefetch_related': [], + }, + { + 'class': ProgrammingChallenge, + 'boost': 0.4, + 'curriculum_area_filtered': False, + 'select_related': ['topic'], + 'prefetch_related': ['difficulty'], + }, +] + + +# Settings calculated from SEARCH_MODEL_TYPES +SEARCH_MODEL_TYPES = get_search_model_types(SEARCH_CLASSES_AND_BOOSTS) +SEARCH_MODEL_FILTER_VALUES = get_model_filter_options(SEARCH_MODEL_TYPES) diff --git a/csunplugged/search/templatetags/__init__.py b/csunplugged/search/templatetags/__init__.py new file mode 100644 index 000000000..23ff4ca91 --- /dev/null +++ b/csunplugged/search/templatetags/__init__.py @@ -0,0 +1 @@ +"""Module for the templatetags for the search application.""" diff --git a/csunplugged/search/templatetags/search_result.py b/csunplugged/search/templatetags/search_result.py new file mode 100644 index 000000000..7eff6e3e7 --- /dev/null +++ b/csunplugged/search/templatetags/search_result.py @@ -0,0 +1,20 @@ +"""Module for the search result template tag.""" + +from os.path import join +from django.template.defaulttags import register +from django.template.loader import render_to_string +from search.utils import get_search_model_id +from search.settings import SEARCH_RESULT_TEMPLATE_DIRECTORY, SEARCH_MODEL_TYPES + + +@register.simple_tag +def search_result_template(result): + """Return the value in a dictionary given a key.""" + class_id = get_search_model_id(type(result)) + context = {'result': result} + + render_func = SEARCH_MODEL_TYPES[class_id].get('render_function', None) + if render_func: + context.update(render_func(result)) + template = join(SEARCH_RESULT_TEMPLATE_DIRECTORY, class_id + '.html') + return render_to_string(template, context) diff --git a/csunplugged/search/urls.py b/csunplugged/search/urls.py index cb409670b..18211dc43 100644 --- a/csunplugged/search/urls.py +++ b/csunplugged/search/urls.py @@ -9,7 +9,7 @@ # eg: /search/ path( '', - views.CustomSearchView.as_view(), + views.SearchView.as_view(), name="index" ), ] diff --git a/csunplugged/search/utils.py b/csunplugged/search/utils.py new file mode 100644 index 000000000..d99ff9c2c --- /dev/null +++ b/csunplugged/search/utils.py @@ -0,0 +1,138 @@ +"""Search utility functions.""" + +import copy +from django.db.models import Value +from django.contrib.postgres.search import SearchVector +from lxml.html import fromstring +from lxml.cssselect import CSSSelector +from django.template.loader import render_to_string +from django.template.exceptions import TemplateSyntaxError + +CONTENT_NOT_FOUND_ERROR_MESSAGE = ("General page requires content wrapped in " + "an element with ID 'general-page-content'") + + +def concat_field_values(*args): + """Return string of field values for search indexing. + + Args: + Any number of QuerySet objects, the result of value_list calls. + + Returns: + String for search indexing. + """ + field_names = [] + for queryset in args: + for instance in queryset: + for field in instance: + field_names.append(str(field)) + return ' '.join(field_names) + + +def get_search_index_updater(instance): + """Return function for updating search index of instance.""" + components = instance.index_contents() + pk = instance.pk + + def on_commit(): + search_vector_list = [] + for weight, text in components.items(): + search_vector_list.append( + SearchVector(Value(text), weight=weight) + ) + search_vectors = search_vector_list[0] + for search_vector in search_vector_list[1:]: + search_vectors += search_vector + + instance.__class__.objects.filter(pk=pk).update( + search_vector=search_vectors + ) + print(f'Rebuilt index for {instance} ({instance.__class__})') + return on_commit + + +def get_template_text(template): + """Return text for indexing. + + Args: + template (string): Path to template to get text from. + + Returns: + String for indexing. + """ + rendered = render_to_string(template, {"LANGUAGE_CODE": "en"}) + html = fromstring(rendered) + selector = CSSSelector("#general-page-content") + try: + contents = selector(html)[0].text_content() + except IndexError: + raise TemplateSyntaxError(CONTENT_NOT_FOUND_ERROR_MESSAGE) + return contents + + +def get_search_model_types(search_model_types_list): + """Return dictionary of search model types. + + Args: + search_model_types: List of dicts of search base data to + to be fleshed out into full dictionary. + + Return: + Dictionary of search model types, keyed by search model ID. + """ + model_types = dict() + for model_data in search_model_types_list: + model_types[get_search_model_id(model_data['class'])] = model_data + return model_types + + +def get_search_model_id(model): + """Return search ID for model. + + Args: + model: Class to get search ID for. + + Returns: + String identifying class. + """ + module_name = model._meta.app_label.lower() + class_name = model._meta.object_name.lower() + return f'{module_name}.{class_name}' + + +def get_model_filter_options(search_model_types): + """Return of model options for search type filter. + + Args: + search_model_types (dict): Dictionary of search model type data. + + Return: + List of dictionaries of model options. + """ + options = [] + for (model_id, model_data) in search_model_types.items(): + options.append( + { + 'name': model_data['class'].MODEL_NAME, + 'value': model_id, + 'selected': False, + } + ) + return options + + +def updated_model_filter_options(model_options, selected_options): + """Update a set of model filters with selected options. + + Args: + model_options (list): List of dictionaries of model options. + selected_options (list): List of selected values. + + Returns: + Updated list of dictionaries of model options. + """ + model_options = copy.deepcopy(model_options) + for model_option in model_options: + if model_option['value'] in selected_options: + model_option['selected'] = True + return model_options diff --git a/csunplugged/search/views.py b/csunplugged/search/views.py index 780b45016..f90050de8 100644 --- a/csunplugged/search/views.py +++ b/csunplugged/search/views.py @@ -1,91 +1,122 @@ """Module for custom search view.""" -from haystack.generic_views import SearchView -from haystack.query import EmptySearchQuerySet -from django.db.models.functions import Concat -from search.forms import CustomSearchForm -from topics.models import ( - CurriculumArea, - LessonNumber, -) - -class CustomSearchView(SearchView): - """View for custom search.""" +from itertools import chain +from django.views import generic +from django.db.models import ( + F, + # Value, + # BooleanField, + # Case, + # When, +) +from django.contrib.postgres.search import ( + SearchQuery, + SearchRank, +) +# from topics.models import CurriculumArea +from search.settings import ( + SEARCH_MODEL_TYPES, + SEARCH_MODEL_FILTER_VALUES, +) +from search.utils import updated_model_filter_options - form_class = CustomSearchForm - def get_queryset(self): - """Return the list of items for this view. +class SearchView(generic.TemplateView): + """View for search.""" - This method overrides the default method, as all items were being - returned when no query parameters was given (not a blank query). - - Returns: - QuerySet for view. - """ - if self.request.GET: - return super(CustomSearchView, self).get_queryset() - else: - return EmptySearchQuerySet() + template_name = 'search/index.html' def get_context_data(self, *args, **kwargs): - """Return context dictionary for custom search view. + """Return context dictionary for search view. Returns: Dictionary of context values. """ - context = super(CustomSearchView, self).get_context_data(*args, **kwargs) - context["search"] = bool(self.request.GET) - - # Model filter - selected_models = self.request.GET.getlist("models") - models_tuples = context["form"].fields["models"].choices - models = [] - for (model_value, model_name) in models_tuples: - model_data = { - "value": model_value, - "name": model_name, - } - if model_value in selected_models: - model_data["selected"] = "true" - if model_value == "classic.classicpage": - model_data["name"] = "Classic CS Unplugged pages" - models.append(model_data) - context["models"] = models - - # Curriculum area filter - selected_curriculum_areas = self.request.GET.getlist("curriculum_areas") - curriculum_areas = list(CurriculumArea.objects.annotate( - display_name=Concat("parent__name", "name") - ).order_by("display_name").values("pk", "colour", "name", "parent__name", "parent__pk")) - grouped_curriculum_areas = [] - for curriculum_area in curriculum_areas: - if selected_curriculum_areas: - if str(curriculum_area["pk"]) in selected_curriculum_areas: - curriculum_area["selected"] = "true" - parent_pk = curriculum_area["parent__pk"] - if parent_pk: - grouped_curriculum_areas[-1]["children"].append(curriculum_area) - else: - curriculum_area["children"] = [] - grouped_curriculum_areas.append(curriculum_area) - context["curriculum_areas"] = grouped_curriculum_areas - - # Update result objects - for result in context["object_list"]: - if result.model_name == "lesson": - lesson_ages = [] - for age_group in result.object.age_group.order_by("ages"): - number = LessonNumber.objects.get(lesson=result.object, age_group=age_group).number - lesson_ages.append( - { - "lower": age_group.ages.lower, - "upper": age_group.ages.upper, - "number": number, - } + context = super().get_context_data(*args, **kwargs) + + # Get request query parmaters + query_text = self.request.GET.get('q') + selected_models = self.request.GET.getlist('models') + # selected_curriculum_areas = self.request.GET.getlist('curriculum_areas') + get_request = bool(self.request.GET) + + if get_request: + context['search'] = get_request + + search_request_data = SEARCH_MODEL_TYPES.copy() + models_to_ignore = [] + + for (model_id, model_data) in search_request_data.items(): + if not selected_models or model_id in selected_models: + model_data['results'] = model_data['class'].objects.all() + else: + models_to_ignore.append(model_id) + + # Delete unused models after iterating + for model_id in models_to_ignore: + del search_request_data[model_id] + + # Search by text query if provided + if query_text: + query = SearchQuery(query_text, search_type="websearch") + for (model_id, model_data) in search_request_data.items(): + model_data['results'] = model_data['results'].filter( + search_vector=query + ).annotate( + rank=SearchRank( + F('search_vector'), query + ) + model_data['boost'] + ).filter( + rank__gt=0 + ).order_by( + '-rank' + ) + + # Concatenate all results + results = [] + for model_data in search_request_data.values(): + results.append( + model_data['results'].select_related( + *model_data['select_related'] + ).prefetch_related( + *model_data['prefetch_related'] ) - result.lesson_ages = lesson_ages - result.curriculum_areas = CurriculumArea.objects.filter( - learning_outcomes__in=result.object.learning_outcomes.all() - ).distinct() + ) + results = chain(*results) + + # Order results if query text provided + if query_text: + results = sorted( + results, + key=lambda instance: instance.rank, + reverse=True, + ) + else: + results = list(results) + + # Organise curriculum areas + # curriculum_areas = CurriculumArea.objects.order_by( + # 'number', '-parent', 'name' + # ).values( + # 'pk', 'colour', 'name', 'parent__pk' + # ) + # grouped_curriculum_areas = [] + # for curriculum_area in curriculum_areas: + # if selected_curriculum_areas: + # if str(curriculum_area['pk']) in selected_curriculum_areas: + # curriculum_area['selected'] = 'true' + # if curriculum_area['parent__pk']: + # grouped_curriculum_areas[-1]['children'].append(curriculum_area) + # else: + # curriculum_area['children'] = [] + # grouped_curriculum_areas.append(curriculum_area) + + context['query'] = query_text + context['models'] = updated_model_filter_options( + SEARCH_MODEL_FILTER_VALUES, + selected_models, + ) + # context['curriculum_areas'] = grouped_curriculum_areas + context['results'] = results + context['results_count'] = len(results) return context diff --git a/csunplugged/static/js/website-search.js b/csunplugged/static/js/website-search.js index 055be8468..fced507ff 100644 --- a/csunplugged/static/js/website-search.js +++ b/csunplugged/static/js/website-search.js @@ -5,74 +5,76 @@ $(document).ready(function() { placeholder: "Show all types", }); - $('#areas-filter').multipleSelect({ - filter: true, - textTemplate: formatArea, - labelTemplate: formatArea, - selectAll: false, - width: '100%', - onClick: updateSelectedAreas, - onOptgroupClick: updateSelectedAreas, - maxHeight: 500, - }); +// $('#areas-filter').multipleSelect({ +// filter: true, +// textTemplate: formatArea, +// labelTemplate: formatArea, +// selectAll: false, +// width: '100%', +// onClick: updateSelectedAreas, +// onOptgroupClick: updateSelectedAreas, +// maxHeight: 500, +// }); // Render selected areas on initial load. - updateSelectedAreas(); +// updateSelectedAreas(); // Indent all area children. - $('.areas-filter-container .ms-drop li:not(.group)').find(':checkbox').each(function(i, obj) { - if (areaData[$(this).val()]['child']) { - $(this).addClass('area-child'); - } - }); +// $('.areas-filter-container .ms-drop li:not(.group)').find(':checkbox').each(function(i, obj) { +// if (areaData[$(this).val()]['child']) { +// $(this).addClass('area-child'); +// } +// }); // Clear form button. $('#clear-form').click(function(){ $('#id_q').val(''); $('#models-filter').multipleSelect('uncheckAll'); - $('#areas-filter').multipleSelect('uncheckAll'); - updateSelectedAreas(); + // $('#areas-filter').multipleSelect('uncheckAll'); + // updateSelectedAreas(); }); }); -function createAreaBadge(colour, text) { - /** - * Create HTML of curriculum area badge. - * @param {string} colour - Colour of badge. - * @param {string} text - Text of badge. - * @return {string} HTML of curriculum area badge. - */ - return `${text}`; -}; +// function createAreaBadge(id) { +// /** +// * Create HTML of curriculum area badge. +// * @param {int} id - ID for area to create badge for. +// * @return {string} HTML of curriculum area badge. +// */ +// var area_data = areaData[id]; +// var child_class = ''; +// if (area_data.child) { +// child_class = ' area-child'; +// } +// return `${area_data.text}`; +// }; -function updateSelectedAreas(changeData) { - /** - * Update selected field with curriculum area badges. - * @param {object} changeData - Data of the clicked item. - */ - var $selectedSpan = $('.areas-filter-container .ms-choice span'); - $selectedSpan.empty(); - var $selectedValues = $('#areas-filter').multipleSelect('getSelects'); - if ($selectedValues.length == 0) { - $selectedSpan.text("Show all curriculum areas"); - } else { - for (var i = 0; i < $selectedValues.length; i++) { - var data = areaData[$selectedValues[i]]; - $selectedSpan.append(createAreaBadge(data.colour, data.text)); - } - } -}; +// function updateSelectedAreas(changeData) { +// /** +// * Update selected field with curriculum area badges. +// * @param {object} changeData - Data of the clicked item. +// */ +// var $selectedSpan = $('.areas-filter-container .ms-choice span'); +// $selectedSpan.empty(); +// var $selectedValues = $('#areas-filter').multipleSelect('getSelects'); +// if ($selectedValues.length == 0) { +// $selectedSpan.text("Show all curriculum areas"); +// } else { +// for (var i = 0; i < $selectedValues.length; i++) { +// $selectedSpan.append(createAreaBadge($selectedValues[i])); +// } +// } +// }; -function formatArea(element) { - /** - * Render curriculum area option in multiple select widget. - * @param {Node} element - Element to render text. - * @return {string} HTML of curriculum area badge. - */ - var element_value = element[0].value; - if (!element_value) { - element_value = areaGroupMapping[element[0].label]; - } - var data = areaData[element_value]; - return createAreaBadge(data.colour, data.text, data.child); -}; +// function formatArea(element) { +// /** +// * Render curriculum area option in multiple select widget. +// * @param {Node} element - Element to render text. +// * @return {string} HTML of curriculum area badge. +// */ +// var element_value = element[0].value; +// if (!element_value) { +// element_value = element[0].dataset.value; +// } +// return createAreaBadge(element_value); +// }; diff --git a/csunplugged/static/scss/search.scss b/csunplugged/static/scss/search.scss index 6a83f11f1..2b37b282b 100644 --- a/csunplugged/static/scss/search.scss +++ b/csunplugged/static/scss/search.scss @@ -19,13 +19,10 @@ ul { margin-bottom: 0 !important; } - .area-badge { - margin-left: 1px; + .area-child { + margin-left: 1rem; } } -.area-child { - margin-left: 1.5em; -} #results { .row { padding: 0.4em 0; diff --git a/csunplugged/templates/search/curriculum-area-option.html b/csunplugged/templates/search/curriculum-area-option.html new file mode 100644 index 000000000..3f6495c9f --- /dev/null +++ b/csunplugged/templates/search/curriculum-area-option.html @@ -0,0 +1,3 @@ + diff --git a/csunplugged/templates/search/index.html b/csunplugged/templates/search/index.html new file mode 100644 index 000000000..7b2a33059 --- /dev/null +++ b/csunplugged/templates/search/index.html @@ -0,0 +1,150 @@ +{% extends "base-educators.html" %} + +{% load static query_replace %} + +{% block title %} + Search +{% endblock title %} + +{% block body_container %} + +{% endblock body_container %} + +{% block scripts %} + + +{% endblock scripts %} + +{% block css %} + +{% endblock css %} diff --git a/csunplugged/templates/search/result/at_home.activity.html b/csunplugged/templates/search/result/at_home.activity.html new file mode 100644 index 000000000..bbf82608d --- /dev/null +++ b/csunplugged/templates/search/result/at_home.activity.html @@ -0,0 +1,5 @@ +

+ + {{ result.name }} + +

diff --git a/csunplugged/templates/search/result/classic.classicpage.html b/csunplugged/templates/search/result/classic.classicpage.html new file mode 100644 index 000000000..bbf82608d --- /dev/null +++ b/csunplugged/templates/search/result/classic.classicpage.html @@ -0,0 +1,5 @@ +

+ + {{ result.name }} + +

diff --git a/csunplugged/templates/search/result/classicpage.html b/csunplugged/templates/search/result/classicpage.html deleted file mode 100644 index 1bc00cc96..000000000 --- a/csunplugged/templates/search/result/classicpage.html +++ /dev/null @@ -1,5 +0,0 @@ -

- - {{ object.name }} - -

diff --git a/csunplugged/templates/search/result/general.generalpage.html b/csunplugged/templates/search/result/general.generalpage.html new file mode 100644 index 000000000..bbf82608d --- /dev/null +++ b/csunplugged/templates/search/result/general.generalpage.html @@ -0,0 +1,5 @@ +

+ + {{ result.name }} + +

diff --git a/csunplugged/templates/search/result/generalpage.html b/csunplugged/templates/search/result/generalpage.html deleted file mode 100644 index 1bc00cc96..000000000 --- a/csunplugged/templates/search/result/generalpage.html +++ /dev/null @@ -1,5 +0,0 @@ -

- - {{ object.name }} - -

diff --git a/csunplugged/templates/search/result/programmingchallenge.html b/csunplugged/templates/search/result/programmingchallenge.html deleted file mode 100644 index 78e3ff128..000000000 --- a/csunplugged/templates/search/result/programmingchallenge.html +++ /dev/null @@ -1,20 +0,0 @@ -{% load i18n %} - -

- - {{ object.name }} - -

-

- - {% trans "Challenge Level:" %} {{ object.difficulty.name }} - -

-

- - {% trans "Within topic" %} - - {{ object.topic.name }} - - -

diff --git a/csunplugged/templates/search/result/resource.html b/csunplugged/templates/search/result/resource.html deleted file mode 100644 index 1bc00cc96..000000000 --- a/csunplugged/templates/search/result/resource.html +++ /dev/null @@ -1,5 +0,0 @@ -

- - {{ object.name }} - -

diff --git a/csunplugged/templates/search/result/resources.resource.html b/csunplugged/templates/search/result/resources.resource.html new file mode 100644 index 000000000..bbf82608d --- /dev/null +++ b/csunplugged/templates/search/result/resources.resource.html @@ -0,0 +1,5 @@ +

+ + {{ result.name }} + +

diff --git a/csunplugged/templates/search/result/topic.html b/csunplugged/templates/search/result/topic.html deleted file mode 100644 index 1bc00cc96..000000000 --- a/csunplugged/templates/search/result/topic.html +++ /dev/null @@ -1,5 +0,0 @@ -

- - {{ object.name }} - -

diff --git a/csunplugged/templates/search/result/curriculumintegration.html b/csunplugged/templates/search/result/topics.curriculumintegration.html similarity index 54% rename from csunplugged/templates/search/result/curriculumintegration.html rename to csunplugged/templates/search/result/topics.curriculumintegration.html index 4d1942a32..3b32edf5d 100644 --- a/csunplugged/templates/search/result/curriculumintegration.html +++ b/csunplugged/templates/search/result/topics.curriculumintegration.html @@ -1,20 +1,20 @@ {% load i18n %}

- - {{ object.name }} + + {{ result.name }}

- {% for area in object.curriculum_areas.all %} + {% for area in result.curriculum_areas.all %} {% include "topics/curriculum-area-badge.html" %} {% endfor %}

{% trans "Within topic" %} - - {{ object.topic.name }} + + {{ result.topic.name }}

diff --git a/csunplugged/templates/search/result/lesson.html b/csunplugged/templates/search/result/topics.lesson.html similarity index 63% rename from csunplugged/templates/search/result/lesson.html rename to csunplugged/templates/search/result/topics.lesson.html index 43644a0e9..9edb0d58d 100644 --- a/csunplugged/templates/search/result/lesson.html +++ b/csunplugged/templates/search/result/topics.lesson.html @@ -1,11 +1,11 @@ {% load i18n %}

- - {{ object.name }} + + {{ result.name }}

-{% for lesson_age in result.lesson_ages %} +{% for lesson_age in lesson_ages %}

{% blocktrans with lower=lesson_age.lower upper=lesson_age.upper number=lesson_age.number trimmed %} @@ -17,17 +17,17 @@

{% trans "Within topic" %} - - {{ object.topic.name }} + + {{ result.topic.name }} {% trans "within unit plan" %} - - {{ object.unit_plan.name }} + + {{ result.unit_plan.name }}

- {% for area in result.curriculum_areas %} + {% for area in curriculum_areas %} {% include "topics/curriculum-area-badge.html" %} {% endfor %}

diff --git a/csunplugged/templates/search/result/topics.programmingchallenge.html b/csunplugged/templates/search/result/topics.programmingchallenge.html new file mode 100644 index 000000000..de159c74f --- /dev/null +++ b/csunplugged/templates/search/result/topics.programmingchallenge.html @@ -0,0 +1,20 @@ +{% load i18n %} + +

+ + {{ result.name }} + +

+

+ + {% trans "Challenge Level:" %} {{ result.difficulty.name }} + +

+

+ + {% trans "Within topic" %} + + {{ result.topic.name }} + + +

diff --git a/csunplugged/templates/search/result/topics.topic.html b/csunplugged/templates/search/result/topics.topic.html new file mode 100644 index 000000000..bbf82608d --- /dev/null +++ b/csunplugged/templates/search/result/topics.topic.html @@ -0,0 +1,5 @@ +

+ + {{ result.name }} + +

diff --git a/csunplugged/templates/search/result/topics.unitplan.html b/csunplugged/templates/search/result/topics.unitplan.html new file mode 100644 index 000000000..35508e26a --- /dev/null +++ b/csunplugged/templates/search/result/topics.unitplan.html @@ -0,0 +1,15 @@ +{% load i18n %} + +

+ + {{ result.name }} + +

+

+ + {% trans "Within topic" %} + + {{ result.topic.name }} + + +

diff --git a/csunplugged/templates/search/result/unitplan.html b/csunplugged/templates/search/result/unitplan.html deleted file mode 100644 index 19f540b41..000000000 --- a/csunplugged/templates/search/result/unitplan.html +++ /dev/null @@ -1,15 +0,0 @@ -{% load i18n %} - -

- - {{ object.name }} - -

-

- - {% trans "Within topic" %} - - {{ object.topic.name }} - - -

diff --git a/csunplugged/templates/search/search.html b/csunplugged/templates/search/search.html deleted file mode 100644 index 21f6c7aa8..000000000 --- a/csunplugged/templates/search/search.html +++ /dev/null @@ -1,176 +0,0 @@ -{% extends "base-educators.html" %} - -{% load static %} -{% load django_bootstrap_breadcrumbs %} -{% load widget_tweaks %} -{% load query_replace %} - -{% block title %} - Search -{% endblock title %} - -{% block body_container %} -
-
-
-
- {% if form.non_field_errors %} - - {% endif %} - -
- -
- {% if form.is_bound and form.q.errors %} - {% render_field form.q class="form-control form-control-lg is-invalid" aria-describedby="form-query-text-help" placeholder="What are you searching for?" %} - {% for error in field.errors %} -
- {{ error }} -
- {% endfor %} - {% else %} - {% render_field form.q class="form-control form-control-lg" aria-describedby="form-query-text-help" placeholder="What are you searching for?" %} - {% endif %} - - Leave blank to search all items. - -
-
- -
- -
- -
-
- -
- -
- -
-
- - - -
- - {% if search %} -

Results

- - {% if object_list %} -

Showing {% if is_paginated %}results {{ page_obj.start_index }} to {{ page_obj.end_index }} of {% endif %}{{ paginator.count }} results

- -
- {% for result in page_obj.object_list %} -
- {% with object=result.object %} -
- {{ object.MODEL_NAME }} -
-
- {% with template="search/result/"|add:result.model_name|add:".html" %} - {% include template %} - {% endwith %} - {% if not DEPLOYED %} -

- - Search score: {{ result.score|floatformat:3 }} - -

- {% endif %} -
- {% endwith %} -
- {% endfor %} -
- - {% if paginator.num_pages > 1 %} -
- {% if page_obj.has_previous %} - « Previous page - {% endif %} - {% if page_obj.has_next %} - Next page » - {% endif %} -
- - {% endif %} - {% else %} -

No results found.

- {% endif %} - {% else %} -

- - Try searching for curriculum integrations with reading and writing - -

- {% endif %} -
-
-
-{% endblock body_container %} - -{% block scripts %} - - -{% endblock scripts %} - -{% block css %} - -{% endblock css %} diff --git a/csunplugged/topics/migrations/0102_auto_20220516_0335.py b/csunplugged/topics/migrations/0102_auto_20220516_0335.py new file mode 100644 index 000000000..458bc2991 --- /dev/null +++ b/csunplugged/topics/migrations/0102_auto_20220516_0335.py @@ -0,0 +1,24 @@ +# Generated by Django 3.2.11 on 2022-05-16 03:35 + +import django.contrib.postgres.indexes +import django.contrib.postgres.search +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('topics', '0101_auto_20210929_2238'), + ] + + operations = [ + migrations.AddField( + model_name='topic', + name='search_vector', + field=django.contrib.postgres.search.SearchVectorField(null=True), + ), + migrations.AddIndex( + model_name='topic', + index=django.contrib.postgres.indexes.GinIndex(fields=['search_vector'], name='topics_topi_search__d723a2_gin'), + ), + ] diff --git a/csunplugged/topics/migrations/0103_auto_20220519_2311.py b/csunplugged/topics/migrations/0103_auto_20220519_2311.py new file mode 100644 index 000000000..edb1e07e7 --- /dev/null +++ b/csunplugged/topics/migrations/0103_auto_20220519_2311.py @@ -0,0 +1,24 @@ +# Generated by Django 3.2.11 on 2022-05-19 23:11 + +import django.contrib.postgres.indexes +import django.contrib.postgres.search +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('topics', '0102_auto_20220516_0335'), + ] + + operations = [ + migrations.AddField( + model_name='unitplan', + name='search_vector', + field=django.contrib.postgres.search.SearchVectorField(null=True), + ), + migrations.AddIndex( + model_name='unitplan', + index=django.contrib.postgres.indexes.GinIndex(fields=['search_vector'], name='topics_unit_search__1551c1_gin'), + ), + ] diff --git a/csunplugged/topics/migrations/0104_auto_20220520_0454.py b/csunplugged/topics/migrations/0104_auto_20220520_0454.py new file mode 100644 index 000000000..4d2edee3f --- /dev/null +++ b/csunplugged/topics/migrations/0104_auto_20220520_0454.py @@ -0,0 +1,42 @@ +# Generated by Django 3.2.11 on 2022-05-20 04:54 + +import django.contrib.postgres.indexes +import django.contrib.postgres.search +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('topics', '0103_auto_20220519_2311'), + ] + + operations = [ + migrations.AddField( + model_name='curriculumintegration', + name='search_vector', + field=django.contrib.postgres.search.SearchVectorField(null=True), + ), + migrations.AddField( + model_name='lesson', + name='search_vector', + field=django.contrib.postgres.search.SearchVectorField(null=True), + ), + migrations.AddField( + model_name='programmingchallenge', + name='search_vector', + field=django.contrib.postgres.search.SearchVectorField(null=True), + ), + migrations.AddIndex( + model_name='curriculumintegration', + index=django.contrib.postgres.indexes.GinIndex(fields=['search_vector'], name='topics_curr_search__ba0181_gin'), + ), + migrations.AddIndex( + model_name='lesson', + index=django.contrib.postgres.indexes.GinIndex(fields=['search_vector'], name='topics_less_search__3c7d6a_gin'), + ), + migrations.AddIndex( + model_name='programmingchallenge', + index=django.contrib.postgres.indexes.GinIndex(fields=['search_vector'], name='topics_prog_search__168ecd_gin'), + ), + ] diff --git a/csunplugged/topics/models.py b/csunplugged/topics/models.py index 8b11f4eeb..f4c3a1a81 100644 --- a/csunplugged/topics/models.py +++ b/csunplugged/topics/models.py @@ -6,6 +6,9 @@ from django.contrib.postgres.fields import IntegerRangeField from resources.models import Resource from utils.TranslatableModel import TranslatableModel +from django.contrib.postgres.search import SearchVectorField +from django.contrib.postgres.indexes import GinIndex +from search.utils import concat_field_values class GlossaryTerm(TranslatableModel): @@ -114,6 +117,7 @@ class Topic(TranslatableModel): content = models.TextField(default="") other_resources = models.TextField(default="") icon = models.CharField(max_length=100, null=True) + search_vector = SearchVectorField(null=True) def get_absolute_url(self): """Return the canonical URL for a topic. @@ -134,6 +138,30 @@ def __str__(self): """ return self.name + def index_contents(self): + """Return dictionary for search indexing. + + Returns: + Dictionary of content for search indexing. The dictionary keys + are the weightings of content, and the dictionary values + are strings of content to index. + """ + return { + 'A': self.name, + 'B': self.content, + 'C': concat_field_values( + self.unit_plans.values_list('name'), + ), + 'D': self.other_resources, + } + + class Meta: + """Meta options for model.""" + + indexes = [ + GinIndex(fields=['search_vector']) + ] + class UnitPlan(TranslatableModel): """Model for unit plan in database.""" @@ -152,6 +180,7 @@ class UnitPlan(TranslatableModel): content = models.TextField(default="") computational_thinking_links = models.TextField(default="") heading_tree = models.JSONField(default=dict) + search_vector = SearchVectorField(null=True) def get_absolute_url(self): """Return the canonical URL for a unit plan. @@ -173,6 +202,29 @@ def __str__(self): """ return self.name + def index_contents(self): + """Return dictionary for search indexing. + + Returns: + Dictionary of content for search indexing. The dictionary keys + are the weightings of content, and the dictionary values + are strings of content to index. + """ + return { + 'A': self.name, + 'B': self.content + self.computational_thinking_links, + 'C': concat_field_values( + self.lessons.values_list('name'), + ), + } + + class Meta: + """Meta options for model.""" + + indexes = [ + GinIndex(fields=['search_vector']) + ] + class ProgrammingChallengeDifficulty(TranslatableModel): """Model for programming challenge difficulty in database.""" @@ -218,6 +270,7 @@ class ProgrammingChallenge(TranslatableModel): on_delete=models.CASCADE, related_name="programming_challenges" ) + search_vector = SearchVectorField(null=True) def get_absolute_url(self): """Return the canonical URL for a programming challenge. @@ -263,6 +316,27 @@ def __str__(self): """ return self.name + def index_contents(self): + """Return dictionary for search indexing. + + Returns: + Dictionary of content for search indexing. The dictionary keys + are the weightings of content, and the dictionary values + are strings of content to index. + """ + return { + 'A': self.name, + 'B': self.content, + 'D': self.topic.name, + } + + class Meta: + """Meta options for model.""" + + indexes = [ + GinIndex(fields=['search_vector']) + ] + class ProgrammingChallengeLanguage(TranslatableModel): """Model for programming language in database.""" @@ -390,6 +464,7 @@ class Lesson(TranslatableModel): classroom_resources = models.ManyToManyField( ClassroomResource, ) + search_vector = SearchVectorField(null=True) def has_programming_challenges(self): """Return boolean of lesson having any programming challenges. @@ -457,6 +532,28 @@ def __str__(self): """ return self.name + def index_contents(self): + """Return dictionary for search indexing. + + Returns: + Dictionary of content for search indexing. The dictionary keys + are the weightings of content, and the dictionary values + are strings of content to index. + """ + return { + 'A': self.name, + 'B': self.content, + 'C': self.topic.name, + 'D': self.computational_thinking_links, + } + + class Meta: + """Meta options for model.""" + + indexes = [ + GinIndex(fields=['search_vector']) + ] + class LessonNumber(models.Model): """Model for relationship between age group and lesson in database.""" @@ -506,6 +603,7 @@ class CurriculumIntegration(TranslatableModel): Lesson, related_name="curriculum_integrations" ) + search_vector = SearchVectorField(null=True) def has_prerequisite_lessons(self): """Return boolean of integration having any prerequisite lessons. @@ -536,6 +634,30 @@ def __str__(self): """ return self.name + def index_contents(self): + """Return dictionary for search indexing. + + Returns: + Dictionary of content for search indexing. The dictionary keys + are the weightings of content, and the dictionary values + are strings of content to index. + """ + return { + 'A': self.name, + 'B': self.content, + 'C': concat_field_values( + self.curriculum_areas.values_list('name'), + ), + 'D': self.topic.name, + } + + class Meta: + """Meta options for model.""" + + indexes = [ + GinIndex(fields=['search_vector']) + ] + class ResourceDescription(TranslatableModel): """Model for relationship between resource and lesson in database.""" diff --git a/csunplugged/topics/search_indexes.py b/csunplugged/topics/search_indexes.py deleted file mode 100644 index 1c2acae8b..000000000 --- a/csunplugged/topics/search_indexes.py +++ /dev/null @@ -1,183 +0,0 @@ -"""Search index for topics models. - -Note: Document boosting for Whoosh backend is with keyword '_boost' instead - of 'boost'. -""" - -from haystack import indexes -from topics.models import ( - Topic, - UnitPlan, - Lesson, - ProgrammingChallenge, - CurriculumIntegration, - CurriculumArea, -) - - -class TopicIndex(indexes.SearchIndex, indexes.Indexable): - """Search index for Topic model.""" - - text = indexes.CharField(document=True, use_template=True) - - def prepare(self, obj): - """Set boost of Topic model for index. - - Args: - obj (Topic): Topic object. - - Returns: - Dictionary of data. - """ - data = super(TopicIndex, self).prepare(obj) - data["_boost"] = 2 - return data - - def get_model(self): - """Return the Topic model. - - Returns: - Topic object. - """ - return Topic - - -class UnitPlanIndex(indexes.SearchIndex, indexes.Indexable): - """Search index for UnitPlan model.""" - - text = indexes.CharField(document=True, use_template=True) - topic = indexes.CharField(model_attr="topic") - - def prepare(self, obj): - """Set boost of UnitPlan model for index. - - Args: - obj (UnitPlan): UnitPlan object. - - Returns: - Dictionary of data. - """ - data = super(UnitPlanIndex, self).prepare(obj) - data["_boost"] = 1.5 - return data - - def get_model(self): - """Return the UnitPlan model. - - Returns: - UnitPlan object. - """ - return UnitPlan - - -class LessonIndex(indexes.SearchIndex, indexes.Indexable): - """Search index for Lesson model.""" - - text = indexes.CharField(document=True, use_template=True) - topic = indexes.CharField(model_attr="topic") - unit_plan = indexes.CharField(model_attr="unit_plan") - curriculum_areas = indexes.MultiValueField() - - def prepare(self, obj): - """Set boost of Lesson model for index. - - Args: - obj (Lesson): Lesson object. - - Returns: - Dictionary of data. - """ - data = super(LessonIndex, self).prepare(obj) - data["_boost"] = 1.2 - return data - - def prepare_curriculum_areas(self, obj): - """Create data for curriculum_areas index value. - - Args: - obj (Lesson): Lesson object. - - Returns: - List of curriculum area primary keys as strings. - """ - curriculum_areas = list(CurriculumArea.objects.filter( - learning_outcomes__in=obj.learning_outcomes.all() - ).distinct().values_list("pk", flat=True)) - return curriculum_areas - - def get_model(self): - """Return the Lesson model. - - Returns: - Lesson object. - """ - return Lesson - - -class CurriculumIntegrationIndex(indexes.SearchIndex, indexes.Indexable): - """Search index for CurriculumIntegration model.""" - - text = indexes.CharField(document=True, use_template=True) - topic = indexes.CharField(model_attr="topic") - curriculum_areas = indexes.MultiValueField() - - def prepare(self, obj): - """Set boost of CurriculumIntegration model for index. - - Args: - obj (CurriculumIntegration): CurriculumIntegration object. - - Returns: - Dictionary of data. - """ - data = super(CurriculumIntegrationIndex, self).prepare(obj) - data["_boost"] = 0.7 - return data - - def prepare_curriculum_areas(self, obj): - """Create data for curriculum_areas index value. - - Args: - obj (CurriculumIntegration): CurriculumIntegration object. - - Returns: - List of curriculum area primary keys as strings. - """ - curriculum_areas = list(obj.curriculum_areas.all().values_list("pk", flat=True)) - return curriculum_areas - - def get_model(self): - """Return the CurriculumIntegration model. - - Returns: - CurriculumIntegration object. - """ - return CurriculumIntegration - - -class ProgrammingChallengeIndex(indexes.SearchIndex, indexes.Indexable): - """Search index for ProgrammingChallenge model.""" - - text = indexes.CharField(document=True, use_template=True) - topic = indexes.CharField(model_attr="topic") - - def prepare(self, obj): - """Set boost of ProgrammingChallenge model for index. - - Args: - obj (ProgrammingChallenge): ProgrammingChallenge object. - - Returns: - Dictionary of data. - """ - data = super(ProgrammingChallengeIndex, self).prepare(obj) - data["_boost"] = 0.4 - return data - - def get_model(self): - """Return the ProgrammingChallenge model. - - Returns: - ProgrammingChallenge object. - """ - return ProgrammingChallenge diff --git a/dev b/dev index 33fff1f0f..72e38ae01 100755 --- a/dev +++ b/dev @@ -140,11 +140,11 @@ cmd_update_static() { defhelp update_static 'Update static files.' # Run Django command rebuild_index -cmd_rebuild_index() { +cmd_rebuild_search_indexes() { echo "Rebuilding search index..." - docker-compose -f docker-compose.local.yml run --rm --label traefik.enable=false django python ./manage.py rebuild_index --noinput + docker-compose -f docker-compose.local.yml run --rm --label traefik.enable=false django python ./manage.py rebuild_search_indexes } -defhelp rebuild_index "Run Django rebuild_index command." +defhelp rebuild_index "Run Django rebuild_search_indexes command." # Run Django makeresourcethumbnails command cmd_make_resource_thumbnails() { diff --git a/docker-compose.local.yml b/docker-compose.local.yml index a2e2d4027..3c74f391a 100644 --- a/docker-compose.local.yml +++ b/docker-compose.local.yml @@ -41,7 +41,7 @@ services: command: npm run dev postgres: - image: postgres:13.3 + image: postgres:13.6 healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] start_period: 10s @@ -56,14 +56,6 @@ services: - local-postgres-data:/var/lib/postgresql/data:Z - local-postgres-data-backups:/backups:z - - elasticsearch: - image: elasticsearch:5 - networks: - - backend - volumes: - - local-search-index:/usr/share/elasticsearch/data:Z - jobe: image: trampgeek/jobeinabox:latest networks: diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 5559e12f2..712b8053b 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -78,7 +78,7 @@ services: postgres: <<: *default-opts - image: postgres:13.3 + image: postgres:13.6 # TODO: Write test script that reads secret files # to get correct username # healthcheck: @@ -109,22 +109,6 @@ services: - postgres-data:/var/lib/postgresql/data:Z - postgres-data-backups:/backups:z - elasticsearch: - <<: *default-opts - image: elasticsearch:5 - deploy: - replicas: 1 - placement: - constraints: - - node.role==worker - - node.labels.role==data - restart_policy: - condition: on-failure - networks: - - backend - volumes: - - search-index:/usr/share/elasticsearch/data:Z - jobe: <<: *default-opts image: trampgeek/jobeinabox:latest diff --git a/docs/getting_started/helper_commands.rst b/docs/getting_started/helper_commands.rst index 0174f8ea6..1d77522a3 100644 --- a/docs/getting_started/helper_commands.rst +++ b/docs/getting_started/helper_commands.rst @@ -201,15 +201,6 @@ Running ``./csu reboot_django`` will rebuild the Django Docker container. ----------------------------------------------------------------------------- -.. _rebuild_index: - -``rebuild_index`` -============================================================================== - -Running ``./csu rebuild_index`` runs the Haystack ``rebuild_index`` Django command. - ------------------------------------------------------------------------------ - .. _restart: ``restart`` diff --git a/requirements/base.txt b/requirements/base.txt index d9e53ac06..e8f05caf4 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -20,11 +20,6 @@ tinycss==0.4 verto==1.0.1 python-markdown-math==0.6 -# Search -django-haystack[elasticsearch]==3.1.1 -elasticsearch==5.5.3 -django-widget-tweaks==1.4.12 - # YAML Loading PyYAML==6.0 @@ -45,4 +40,4 @@ django-bidi-utils==1.0 requests==2.27.1 # CORS -django-cors-headers==3.11.0 \ No newline at end of file +django-cors-headers==3.11.0 From 3126d876571572cdea463b423c282f859afd4b50 Mon Sep 17 00:00:00 2001 From: JackMorganNZ Date: Thu, 26 May 2022 16:37:46 +1200 Subject: [PATCH 012/195] Update tests --- csunplugged/classic/models.py | 2 +- csunplugged/general/models.py | 2 +- csunplugged/search/views.py | 1 + csunplugged/templates/search/index.html | 2 +- ...=> test_rebuild_search_indexes_command.py} | 47 +- .../tests/search/views/test_index_view.py | 825 +++++++++--------- 6 files changed, 450 insertions(+), 429 deletions(-) rename csunplugged/tests/search/management/{test_rebuild_index_command.py => test_rebuild_search_indexes_command.py} (68%) diff --git a/csunplugged/classic/models.py b/csunplugged/classic/models.py index 43cbe3097..3ae393dc1 100644 --- a/csunplugged/classic/models.py +++ b/csunplugged/classic/models.py @@ -9,7 +9,7 @@ class ClassicPage(models.Model): """Model for Classic CS Unplugged page in database.""" - MODEL_NAME = _("Classic CS Unplugged page") + MODEL_NAME = _("Classic CS Unplugged Page") # Auto-incrementing 'id' field is automatically set by Django slug = models.SlugField(unique=True) diff --git a/csunplugged/general/models.py b/csunplugged/general/models.py index d0f09e835..946244070 100644 --- a/csunplugged/general/models.py +++ b/csunplugged/general/models.py @@ -11,7 +11,7 @@ class GeneralPage(models.Model): """Model for general page in database.""" - MODEL_NAME = _("General page") + MODEL_NAME = _("General Page") # Auto-incrementing 'id' field is automatically set by Django slug = models.SlugField(unique=True) diff --git a/csunplugged/search/views.py b/csunplugged/search/views.py index f90050de8..a7a80b55a 100644 --- a/csunplugged/search/views.py +++ b/csunplugged/search/views.py @@ -33,6 +33,7 @@ def get_context_data(self, *args, **kwargs): Dictionary of context values. """ context = super().get_context_data(*args, **kwargs) + context['models'] = SEARCH_MODEL_FILTER_VALUES # Get request query parmaters query_text = self.request.GET.get('q') diff --git a/csunplugged/templates/search/index.html b/csunplugged/templates/search/index.html index 7b2a33059..a9bad9148 100644 --- a/csunplugged/templates/search/index.html +++ b/csunplugged/templates/search/index.html @@ -62,7 +62,7 @@
{% if search %} -

Results

+

Result{{ results_count|pluralize }}

diff --git a/csunplugged/tests/search/management/test_rebuild_index_command.py b/csunplugged/tests/search/management/test_rebuild_search_indexes_command.py similarity index 68% rename from csunplugged/tests/search/management/test_rebuild_index_command.py rename to csunplugged/tests/search/management/test_rebuild_search_indexes_command.py index b8653b80a..68d93bd33 100644 --- a/csunplugged/tests/search/management/test_rebuild_index_command.py +++ b/csunplugged/tests/search/management/test_rebuild_search_indexes_command.py @@ -1,4 +1,4 @@ -"""Module for the testing custom Django rebuild_index command.""" +"""Module for the testing custom Django rebuild_search_indexes command.""" from os.path import join, dirname from django.conf import settings @@ -27,19 +27,19 @@ def __init__(self, *args, **kwargs): self.language = "en" self.test_data = TopicsTestDataGenerator() - def test_rebuild_index_command_no_items(self): - management.call_command("rebuild_index", "--noinput") + def test_rebuild_search_indexes_command_no_items(self): + management.call_command("rebuild_search_indexes") - def test_rebuild_index_command_topic_model(self): + def test_rebuild_search_indexes_command_topic_model(self): self.test_data.create_topic(1) - management.call_command("rebuild_index", "--noinput") + management.call_command("rebuild_search_indexes") - def test_rebuild_index_command_unit_plan_model(self): + def test_rebuild_search_indexes_command_unit_plan_model(self): topic = self.test_data.create_topic(1) self.test_data.create_unit_plan(topic, 1) - management.call_command("rebuild_index", "--noinput") + management.call_command("rebuild_search_indexes") - def test_rebuild_index_command_lesson_model(self): + def test_rebuild_search_indexes_command_lesson_model(self): topic = self.test_data.create_topic(1) unit_plan = self.test_data.create_unit_plan(topic, 1) age_group_1 = self.test_data.create_age_group(5, 7) @@ -49,14 +49,14 @@ def test_rebuild_index_command_lesson_model(self): 1, age_group_1 ) - management.call_command("rebuild_index", "--noinput") + management.call_command("rebuild_search_indexes") - def test_rebuild_index_command_curriculum_integration_model(self): + def test_rebuild_search_indexes_command_curriculum_integration_model(self): topic = self.test_data.create_topic(1) self.test_data.create_integration(topic, 1) - management.call_command("rebuild_index", "--noinput") + management.call_command("rebuild_search_indexes") - def test_rebuild_index_command_programming_challenge_model(self): + def test_rebuild_search_indexes_command_programming_challenge_model(self): topic = self.test_data.create_topic(1) difficulty = self.test_data.create_difficulty_level(1) language = self.test_data.create_programming_language(1) @@ -66,9 +66,9 @@ def test_rebuild_index_command_programming_challenge_model(self): language, challenge, ) - management.call_command("rebuild_index", "--noinput") + management.call_command("rebuild_search_indexes") - def test_rebuild_index_command_resource_model(self): + def test_rebuild_search_indexes_command_resource_model(self): resources_test_data = ResourcesTestDataGenerator() resources_test_data.create_resource( "grid", @@ -76,19 +76,19 @@ def test_rebuild_index_command_resource_model(self): "resources/grid.html", "GridResourceGenerator", ) - management.call_command("rebuild_index", "--noinput") + management.call_command("rebuild_search_indexes") - def test_rebuild_index_command_classic_page_model(self): + def test_rebuild_search_indexes_command_classic_page_model(self): page = ClassicPage( slug="page", name="Page", redirect="http://www.example.com", ) page.save() - management.call_command("rebuild_index", "--noinput") + management.call_command("rebuild_search_indexes") @override_settings(TEMPLATES=test_template_settings) - def test_rebuild_index_command_general_page_model(self): + def test_rebuild_search_indexes_command_general_page_model(self): page = GeneralPage( slug="page", name="Page", @@ -96,10 +96,10 @@ def test_rebuild_index_command_general_page_model(self): url_name="url", ) page.save() - management.call_command("rebuild_index", "--noinput") + management.call_command("rebuild_search_indexes") @override_settings(TEMPLATES=test_template_settings) - def test_rebuild_index_command_general_page_with_invalid_template(self): + def test_rebuild_search_indexes_command_general_page_with_invalid_template(self): page = GeneralPage( slug="page", name="Page", @@ -110,11 +110,10 @@ def test_rebuild_index_command_general_page_with_invalid_template(self): self.assertRaises( TemplateSyntaxError, management.call_command, - "rebuild_index", - "--noinput" + "rebuild_search_indexes", ) - def test_rebuild_index_command_multiple_models(self): + def test_rebuild_search_indexes_command_multiple_models(self): topic = self.test_data.create_topic(1) unit_plan = self.test_data.create_unit_plan(topic, 1) age_group_1 = self.test_data.create_age_group(5, 7) @@ -124,4 +123,4 @@ def test_rebuild_index_command_multiple_models(self): 1, age_group_1 ) - management.call_command("rebuild_index", "--noinput") + management.call_command("rebuild_search_indexes") diff --git a/csunplugged/tests/search/views/test_index_view.py b/csunplugged/tests/search/views/test_index_view.py index 1dd8660f2..25206b583 100644 --- a/csunplugged/tests/search/views/test_index_view.py +++ b/csunplugged/tests/search/views/test_index_view.py @@ -4,6 +4,7 @@ from tests.BaseTestWithDB import BaseTestWithDB from tests.topics.TopicsTestDataGenerator import TopicsTestDataGenerator from tests.create_query_string import query_string +from topics.models import Topic, UnitPlan, Lesson class IndexViewTest(BaseTestWithDB): @@ -19,66 +20,79 @@ def test_search_view_with_no_query_with_index(self): self.test_data.create_topic(1) self.test_data.create_topic(2) self.test_data.create_topic(3) - management.call_command("rebuild_index", "--noinput") + management.call_command("rebuild_search_indexes") url = reverse("search:index") response = self.client.get(url) self.assertEqual(HTTPStatus.OK, response.status_code) - self.assertFalse(response.context["object_list"]) - self.assertEqual(response.context.get("query"), "") + self.assertNotIn("results", response.context) + self.assertNotIn("query", response.context) def test_search_view_with_no_query_with_no_index(self): url = reverse("search:index") response = self.client.get(url) self.assertEqual(HTTPStatus.OK, response.status_code) - self.assertFalse(response.context["object_list"]) - self.assertEqual(response.context.get("query"), "") + self.assertNotIn("results", response.context) + self.assertNotIn("query", response.context) # Context def test_search_view_context_model_data(self): - management.call_command("rebuild_index", "--noinput") + management.call_command("rebuild_search_indexes") url = reverse("search:index") response = self.client.get(url) self.assertEqual( response.context["models"], [ { - "value": "classic.classicpage", - "name": "Classic CS Unplugged pages" + "value": "topics.topic", + "name": "Topic", + "selected": False, }, { - "value": "topics.curriculumintegration", - "name": "Curriculum integrations" + "value": "topics.unitplan", + "name": "Unit Plan", + "selected": False, }, { - "value": "general.generalpage", - "name": "General pages" + "value": "topics.lesson", + "name": "Lesson", + "selected": False, }, { - "value": "topics.lesson", - "name": "Lessons" + "value": "resources.resource", + "name": "Printable", + "selected": False, }, { - "value": "topics.programmingchallenge", - "name": "Programming challenges" + "value": "general.generalpage", + "name": "General Page", + "selected": False, }, { - "value": "resources.resource", - "name": "Resources" + "value": "at_home.activity", + "name": "At Home Activity", + "selected": False, }, { - "value": "topics.topic", - "name": "Topics" + "value": "topics.curriculumintegration", + "name": "Curriculum Integration", + "selected": False, }, { - "value": "topics.unitplan", - "name": "Unit plans" - } + "value": "classic.classicpage", + "name": "Classic CS Unplugged Page", + "selected": False, + }, + { + "value": "topics.programmingchallenge", + "name": "Programming Challenge", + "selected": False, + }, ] ) def test_search_view_context_model_data_with_selected(self): - management.call_command("rebuild_index", "--noinput") + management.call_command("rebuild_search_indexes") url = reverse("search:index") get_parameters = [ ("models", "topics.topic"), @@ -90,285 +104,360 @@ def test_search_view_context_model_data_with_selected(self): response.context["models"], [ { - "value": "classic.classicpage", - "name": "Classic CS Unplugged pages" - }, - { - "value": "topics.curriculumintegration", - "name": "Curriculum integrations" + "value": "topics.topic", + "name": "Topic", + "selected": True, }, { - "value": "general.generalpage", - "name": "General pages" + "value": "topics.unitplan", + "name": "Unit Plan", + "selected": True, }, { "value": "topics.lesson", - "name": "Lessons" - }, - { - "value": "topics.programmingchallenge", - "name": "Programming challenges" + "name": "Lesson", + "selected": False, }, { "value": "resources.resource", - "name": "Resources" + "name": "Printable", + "selected": False, }, { - "value": "topics.topic", - "name": "Topics", - "selected": "true", - }, - { - "value": "topics.unitplan", - "name": "Unit plans", - "selected": "true", - } - ] - ) - - def test_search_view_context_curriculum_areas_data(self): - area_1 = self.test_data.create_curriculum_area(1) - area_2 = self.test_data.create_curriculum_area(2) - management.call_command("rebuild_index", "--noinput") - url = reverse("search:index") - response = self.client.get(url) - self.assertEqual( - response.context["curriculum_areas"], - [ - { - "pk": area_1.pk, - "name": "Area 1", - "colour": "colour-1", - "parent__pk": None, - "parent__name": None, - "children": [] + "value": "general.generalpage", + "name": "General Page", + "selected": False, }, { - "pk": area_2.pk, - "name": "Area 2", - "colour": "colour-2", - "parent__pk": None, - "parent__name": None, - "children": [] + "value": "at_home.activity", + "name": "At Home Activity", + "selected": False, }, - ] - ) - - def test_search_view_context_curriculum_areas_data_with_selected(self): - area_1 = self.test_data.create_curriculum_area(1) - area_2 = self.test_data.create_curriculum_area(2) - area_3 = self.test_data.create_curriculum_area(3) - management.call_command("rebuild_index", "--noinput") - url = reverse("search:index") - get_parameters = [ - ("curriculum_areas", area_1.pk), - ("curriculum_areas", area_3.pk), - ] - url += query_string(get_parameters) - response = self.client.get(url) - self.assertEqual( - response.context["curriculum_areas"], - [ { - "pk": area_1.pk, - "name": "Area 1", - "colour": "colour-1", - "parent__pk": None, - "parent__name": None, - "children": [], - "selected": "true", + "value": "topics.curriculumintegration", + "name": "Curriculum Integration", + "selected": False, }, { - "pk": area_2.pk, - "name": "Area 2", - "colour": "colour-2", - "parent__pk": None, - "parent__name": None, - "children": [], + "value": "classic.classicpage", + "name": "Classic CS Unplugged Page", + "selected": False, }, { - "pk": area_3.pk, - "name": "Area 3", - "colour": "colour-3", - "parent__pk": None, - "parent__name": None, - "children": [], - "selected": "true", + "value": "topics.programmingchallenge", + "name": "Programming Challenge", + "selected": False, }, ] ) - def test_search_view_context_curriculum_areas_data_with_children(self): - area_1 = self.test_data.create_curriculum_area(1) - area_2 = self.test_data.create_curriculum_area(2) - area_3 = self.test_data.create_curriculum_area(3, parent=area_2) - area_4 = self.test_data.create_curriculum_area(4, parent=area_2) - area_5 = self.test_data.create_curriculum_area(5, parent=area_2) - management.call_command("rebuild_index", "--noinput") + # def test_search_view_context_curriculum_areas_data(self): + # area_1 = self.test_data.create_curriculum_area(1) + # area_2 = self.test_data.create_curriculum_area(2) + # management.call_command("rebuild_search_indexes") + # url = reverse("search:index") + # response = self.client.get(url) + # self.assertEqual( + # response.context["curriculum_areas"], + # [ + # { + # "pk": area_1.pk, + # "name": "Area 1", + # "colour": "colour-1", + # "parent__pk": None, + # "parent__name": None, + # "children": [] + # }, + # { + # "pk": area_2.pk, + # "name": "Area 2", + # "colour": "colour-2", + # "parent__pk": None, + # "parent__name": None, + # "children": [] + # }, + # ] + # ) + + # def test_search_view_context_curriculum_areas_data_with_selected(self): + # area_1 = self.test_data.create_curriculum_area(1) + # area_2 = self.test_data.create_curriculum_area(2) + # area_3 = self.test_data.create_curriculum_area(3) + # management.call_command("rebuild_search_indexes") + # url = reverse("search:index") + # get_parameters = [ + # ("curriculum_areas", area_1.pk), + # ("curriculum_areas", area_3.pk), + # ] + # url += query_string(get_parameters) + # response = self.client.get(url) + # self.assertEqual( + # response.context["curriculum_areas"], + # [ + # { + # "pk": area_1.pk, + # "name": "Area 1", + # "colour": "colour-1", + # "parent__pk": None, + # "parent__name": None, + # "children": [], + # "selected": "true", + # }, + # { + # "pk": area_2.pk, + # "name": "Area 2", + # "colour": "colour-2", + # "parent__pk": None, + # "parent__name": None, + # "children": [], + # }, + # { + # "pk": area_3.pk, + # "name": "Area 3", + # "colour": "colour-3", + # "parent__pk": None, + # "parent__name": None, + # "children": [], + # "selected": "true", + # }, + # ] + # ) + + # def test_search_view_context_curriculum_areas_data_with_children(self): + # area_1 = self.test_data.create_curriculum_area(1) + # area_2 = self.test_data.create_curriculum_area(2) + # area_3 = self.test_data.create_curriculum_area(3, parent=area_2) + # area_4 = self.test_data.create_curriculum_area(4, parent=area_2) + # area_5 = self.test_data.create_curriculum_area(5, parent=area_2) + # management.call_command("rebuild_search_indexes") + # url = reverse("search:index") + # response = self.client.get(url) + # self.assertEqual( + # response.context["curriculum_areas"], + # [ + # { + # "pk": area_1.pk, + # "name": "Area 1", + # "colour": "colour-1", + # "parent__pk": None, + # "parent__name": None, + # "children": [] + # }, + # { + # "pk": area_2.pk, + # "name": "Area 2", + # "colour": "colour-2", + # "parent__pk": None, + # "parent__name": None, + # "children": [ + # { + # "pk": area_3.pk, + # "name": "Area 3", + # "colour": "colour-3", + # "parent__pk": area_2.pk, + # "parent__name": "Area 2", + # }, + # { + # "pk": area_4.pk, + # "name": "Area 4", + # "colour": "colour-4", + # "parent__pk": area_2.pk, + # "parent__name": "Area 2", + # }, + # { + # "pk": area_5.pk, + # "name": "Area 5", + # "colour": "colour-5", + # "parent__pk": area_2.pk, + # "parent__name": "Area 2", + # }, + # ] + # }, + # ] + # ) + + # def test_search_view_context_curriculum_areas_data_with_children_with_selected(self): + # area_1 = self.test_data.create_curriculum_area(1) + # area_2 = self.test_data.create_curriculum_area(2) + # area_3 = self.test_data.create_curriculum_area(3, parent=area_2) + # area_4 = self.test_data.create_curriculum_area(4, parent=area_2) + # area_5 = self.test_data.create_curriculum_area(5, parent=area_2) + # management.call_command("rebuild_search_indexes") + # url = reverse("search:index") + # get_parameters = [ + # ("curriculum_areas", area_1.pk), + # ("curriculum_areas", area_2.pk), + # ("curriculum_areas", area_3.pk), + # ("curriculum_areas", area_5.pk), + # ] + # url += query_string(get_parameters) + # response = self.client.get(url) + # self.assertEqual( + # response.context["curriculum_areas"], + # [ + # { + # "pk": area_1.pk, + # "name": "Area 1", + # "colour": "colour-1", + # "parent__pk": None, + # "parent__name": None, + # "children": [], + # "selected": "true", + # }, + # { + # "pk": area_2.pk, + # "name": "Area 2", + # "colour": "colour-2", + # "parent__pk": None, + # "parent__name": None, + # "selected": "true", + # "children": [ + # { + # "pk": area_3.pk, + # "name": "Area 3", + # "colour": "colour-3", + # "parent__pk": area_2.pk, + # "parent__name": "Area 2", + # "selected": "true", + # }, + # { + # "pk": area_4.pk, + # "name": "Area 4", + # "colour": "colour-4", + # "parent__pk": area_2.pk, + # "parent__name": "Area 2", + # }, + # { + # "pk": area_5.pk, + # "name": "Area 5", + # "colour": "colour-5", + # "parent__pk": area_2.pk, + # "parent__name": "Area 2", + # "selected": "true", + # }, + # ] + # }, + # ] + # ) + + # TODO: Test is broken as query text provides zero matches + # def test_search_view_context_lesson_data(self): + # topic = self.test_data.create_topic(1) + # unit_plan = self.test_data.create_unit_plan(topic, 1) + # age_group = self.test_data.create_age_group(5, 7) + # lesson = self.test_data.create_lesson( + # topic, + # unit_plan, + # 1, + # age_group + # ) + # learning_outcome1 = self.test_data.create_learning_outcome(1) + # area_1 = self.test_data.create_curriculum_area(1) + # learning_outcome1.curriculum_areas.add(area_1) + # lesson.learning_outcomes.add(learning_outcome1) + # learning_outcome2 = self.test_data.create_learning_outcome(2) + # area_2 = self.test_data.create_curriculum_area(2) + # learning_outcome2.curriculum_areas.add(area_2) + # area_3 = self.test_data.create_curriculum_area(3) + # learning_outcome2.curriculum_areas.add(area_3) + # lesson.learning_outcomes.add(learning_outcome2) + # self.test_data.create_curriculum_area(4) + # management.call_command("rebuild_search_indexes") + # url = reverse("search:index") + # get_parameters = [("q", lesson.name)] + # url += query_string(get_parameters) + # response = self.client.get(url) + # result_lesson = response.context["results"][0] + # self.assertEqual( + # result_lesson.lesson_ages, + # [ + # { + # "lower": 5, + # "upper": 7, + # "number": 1, + # }, + # ] + # ) + # self.assertQuerysetEqual( + # result_lesson.curriculum_areas, + # [ + # "", + # "", + # "", + # ] + # ) + + # With query + + def test_search_view_all_items(self): + topic = self.test_data.create_topic(1) + self.test_data.create_topic(2) + self.test_data.create_topic(3) + unit_plan = self.test_data.create_unit_plan(topic, 1) + unit_plan = self.test_data.create_unit_plan(topic, 2) + age_group = self.test_data.create_age_group(5, 7) + self.test_data.create_lesson( + topic, + unit_plan, + 1, + age_group + ) + management.call_command("rebuild_search_indexes") url = reverse("search:index") + get_parameters = [("q", "")] + url += query_string(get_parameters) response = self.client.get(url) - self.assertEqual( - response.context["curriculum_areas"], - [ - { - "pk": area_1.pk, - "name": "Area 1", - "colour": "colour-1", - "parent__pk": None, - "parent__name": None, - "children": [] - }, - { - "pk": area_2.pk, - "name": "Area 2", - "colour": "colour-2", - "parent__pk": None, - "parent__name": None, - "children": [ - { - "pk": area_3.pk, - "name": "Area 3", - "colour": "colour-3", - "parent__pk": area_2.pk, - "parent__name": "Area 2", - }, - { - "pk": area_4.pk, - "name": "Area 4", - "colour": "colour-4", - "parent__pk": area_2.pk, - "parent__name": "Area 2", - }, - { - "pk": area_5.pk, - "name": "Area 5", - "colour": "colour-5", - "parent__pk": area_2.pk, - "parent__name": "Area 2", - }, - ] - }, - ] - ) + self.assertEqual(len(response.context["results"]), 6) - def test_search_view_context_curriculum_areas_data_with_children_with_selected(self): - area_1 = self.test_data.create_curriculum_area(1) - area_2 = self.test_data.create_curriculum_area(2) - area_3 = self.test_data.create_curriculum_area(3, parent=area_2) - area_4 = self.test_data.create_curriculum_area(4, parent=area_2) - area_5 = self.test_data.create_curriculum_area(5, parent=area_2) - management.call_command("rebuild_index", "--noinput") + def test_search_view_assert_order(self): + topic = self.test_data.create_topic(1) + self.test_data.create_topic(2) + unit_plan = self.test_data.create_unit_plan(topic, 1) + age_group = self.test_data.create_age_group(5, 7) + self.test_data.create_lesson( + topic, + unit_plan, + 1, + age_group + ) + management.call_command("rebuild_search_indexes") url = reverse("search:index") - get_parameters = [ - ("curriculum_areas", area_1.pk), - ("curriculum_areas", area_2.pk), - ("curriculum_areas", area_3.pk), - ("curriculum_areas", area_5.pk), - ] + get_parameters = [("q", "")] url += query_string(get_parameters) response = self.client.get(url) - self.assertEqual( - response.context["curriculum_areas"], - [ - { - "pk": area_1.pk, - "name": "Area 1", - "colour": "colour-1", - "parent__pk": None, - "parent__name": None, - "children": [], - "selected": "true", - }, - { - "pk": area_2.pk, - "name": "Area 2", - "colour": "colour-2", - "parent__pk": None, - "parent__name": None, - "selected": "true", - "children": [ - { - "pk": area_3.pk, - "name": "Area 3", - "colour": "colour-3", - "parent__pk": area_2.pk, - "parent__name": "Area 2", - "selected": "true", - }, - { - "pk": area_4.pk, - "name": "Area 4", - "colour": "colour-4", - "parent__pk": area_2.pk, - "parent__name": "Area 2", - }, - { - "pk": area_5.pk, - "name": "Area 5", - "colour": "colour-5", - "parent__pk": area_2.pk, - "parent__name": "Area 2", - "selected": "true", - }, - ] - }, - ] - ) + result_objects = response.context["results"] + self.assertIsInstance(result_objects[0], Topic) + self.assertIsInstance(result_objects[1], Topic) + self.assertIsInstance(result_objects[2], UnitPlan) + self.assertIsInstance(result_objects[3], Lesson) - def test_search_view_context_lesson_data(self): + def test_search_view_model_filter(self): topic = self.test_data.create_topic(1) + self.test_data.create_topic(2) unit_plan = self.test_data.create_unit_plan(topic, 1) age_group = self.test_data.create_age_group(5, 7) - lesson = self.test_data.create_lesson( + self.test_data.create_lesson( topic, unit_plan, 1, age_group ) - learning_outcome1 = self.test_data.create_learning_outcome(1) - area_1 = self.test_data.create_curriculum_area(1) - learning_outcome1.curriculum_areas.add(area_1) - lesson.learning_outcomes.add(learning_outcome1) - learning_outcome2 = self.test_data.create_learning_outcome(2) - area_2 = self.test_data.create_curriculum_area(2) - learning_outcome2.curriculum_areas.add(area_2) - area_3 = self.test_data.create_curriculum_area(3) - learning_outcome2.curriculum_areas.add(area_3) - lesson.learning_outcomes.add(learning_outcome2) - self.test_data.create_curriculum_area(4) - management.call_command("rebuild_index", "--noinput") + management.call_command("rebuild_search_indexes") url = reverse("search:index") - get_parameters = [("q", lesson.name)] + get_parameters = [ + ("models", "topics.topic"), + ] url += query_string(get_parameters) response = self.client.get(url) - result_lesson = response.context["object_list"][0] - self.assertEqual( - result_lesson.lesson_ages, - [ - { - "lower": 5, - "upper": 7, - "number": 1, - }, - ] - ) - self.assertQuerysetEqual( - result_lesson.curriculum_areas, - [ - "", - "", - "", - ] - ) - - # With query + result_objects = response.context["results"] + self.assertEqual(len(result_objects), 2) + self.assertIsInstance(result_objects[0], Topic) + self.assertIsInstance(result_objects[1], Topic) - def test_search_view_all_items(self): + def test_search_view_model_filter_multiple(self): topic = self.test_data.create_topic(1) self.test_data.create_topic(2) - self.test_data.create_topic(3) unit_plan = self.test_data.create_unit_plan(topic, 1) - unit_plan = self.test_data.create_unit_plan(topic, 2) age_group = self.test_data.create_age_group(5, 7) self.test_data.create_lesson( topic, @@ -376,15 +465,22 @@ def test_search_view_all_items(self): 1, age_group ) - management.call_command("rebuild_index", "--noinput") + management.call_command("rebuild_search_indexes") url = reverse("search:index") - get_parameters = [("q", "")] + get_parameters = [ + ("models", "topics.topic"), + ("models", "topics.unitplan"), + ] url += query_string(get_parameters) response = self.client.get(url) - self.assertEqual(len(response.context["object_list"]), 6) + result_objects = response.context["results"] + self.assertEqual(len(result_objects), 3) + self.assertIsInstance(result_objects[0], Topic) + self.assertIsInstance(result_objects[1], Topic) + self.assertIsInstance(result_objects[2], UnitPlan) - # TODO: Test is currently broken, however test is skipped as not required for server migration. - # def test_search_view_assert_order(self): + # TODO: Test is broken as query text provides zero matches + # def test_search_view_model_filter_multiple_with_query(self): # topic = self.test_data.create_topic(1) # self.test_data.create_topic(2) # unit_plan = self.test_data.create_unit_plan(topic, 1) @@ -395,162 +491,87 @@ def test_search_view_all_items(self): # 1, # age_group # ) - # management.call_command("rebuild_index", "--noinput") + # management.call_command("rebuild_search_indexes") # url = reverse("search:index") - # get_parameters = [("q", "")] + # get_parameters = [ + # ("q", "Unit Plan 1"), + # ("models", "topics.topic"), + # ("models", "topics.unitplan"), + # ] # url += query_string(get_parameters) # response = self.client.get(url) - # result_objects = response.context["object_list"] - # self.assertEqual(result_objects[0].model_name, "topic") - # self.assertEqual(result_objects[1].model_name, "topic") - # self.assertEqual(result_objects[2].model_name, "unitplan") - # self.assertEqual(result_objects[3].model_name, "lesson") + # result_objects = response.context["results"] + # self.assertIsInstance(result_objects[0], UnitPlan) - # TODO: Test is currently broken (all models are returned), - # however test is skipped as not required for server migration. - # def test_search_view_model_filter(self): + # def test_search_view_curriculum_areas_filter_1(self): # topic = self.test_data.create_topic(1) - # self.test_data.create_topic(2) - # unit_plan = self.test_data.create_unit_plan(topic, 1) - # age_group = self.test_data.create_age_group(5, 7) - # self.test_data.create_lesson( - # topic, - # unit_plan, - # 1, - # age_group - # ) - # management.call_command("rebuild_index", "--noinput") + # area_1 = self.test_data.create_curriculum_area(1) + # self.test_data.create_integration(topic, 1, curriculum_areas=[area_1]) + # area_2 = self.test_data.create_curriculum_area(2) + # self.test_data.create_integration(topic, 2, curriculum_areas=[area_1, area_2]) + # self.test_data.create_integration(topic, 3) + # self.test_data.create_integration(topic, 4) + # management.call_command("rebuild_search_indexes") # url = reverse("search:index") # get_parameters = [ - # ("models", "topics.topic"), + # ("curriculum_areas", area_1.pk), # ] # url += query_string(get_parameters) # response = self.client.get(url) - # result_objects = response.context["object_list"] + # result_objects = response.context["results"] # self.assertEqual(len(result_objects), 2) - # self.assertEqual(result_objects[0].model_name, "topic") - # self.assertEqual(result_objects[1].model_name, "topic") - # TODO: Test is currently broken (all models are returned), - # however test is skipped as not required for server migration. - # def test_search_view_model_filter_multiple(self): + # def test_search_view_curriculum_areas_filter_2(self): # topic = self.test_data.create_topic(1) - # self.test_data.create_topic(2) - # unit_plan = self.test_data.create_unit_plan(topic, 1) - # age_group = self.test_data.create_age_group(5, 7) - # self.test_data.create_lesson( - # topic, - # unit_plan, - # 1, - # age_group - # ) - # management.call_command("rebuild_index", "--noinput") + # area_1 = self.test_data.create_curriculum_area(1) + # self.test_data.create_integration(topic, 1, curriculum_areas=[area_1]) + # area_2 = self.test_data.create_curriculum_area(2) + # self.test_data.create_integration(topic, 2, curriculum_areas=[area_1, area_2]) + # self.test_data.create_integration(topic, 3) + # self.test_data.create_integration(topic, 4) + # management.call_command("rebuild_search_indexes") # url = reverse("search:index") # get_parameters = [ - # ("models", "topics.topic"), - # ("models", "topics.unitplan"), + # ("curriculum_areas", area_2.pk), # ] # url += query_string(get_parameters) # response = self.client.get(url) - # result_objects = response.context["object_list"] - # self.assertEqual(len(result_objects), 3) - # self.assertEqual(result_objects[0].model_name, "topic") - # self.assertEqual(result_objects[1].model_name, "topic") - # self.assertEqual(result_objects[2].model_name, "unitplan") + # result_objects = response.context["results"] + # self.assertEqual(len(result_objects), 1) - def test_search_view_model_filter_multiple_with_query(self): - topic = self.test_data.create_topic(1) - self.test_data.create_topic(2) - unit_plan = self.test_data.create_unit_plan(topic, 1) - age_group = self.test_data.create_age_group(5, 7) - self.test_data.create_lesson( - topic, - unit_plan, - 1, - age_group - ) - management.call_command("rebuild_index", "--noinput") - url = reverse("search:index") - get_parameters = [ - ("q", "Unit Plan 1"), - ("models", "topics.topic"), - ("models", "topics.unitplan"), - ] - url += query_string(get_parameters) - response = self.client.get(url) - result_objects = response.context["object_list"] - self.assertEqual(len(result_objects), 1) - self.assertEqual(result_objects[0].model_name, "unitplan") - - def test_search_view_curriculum_areas_filter_1(self): - topic = self.test_data.create_topic(1) - area_1 = self.test_data.create_curriculum_area(1) - self.test_data.create_integration(topic, 1, curriculum_areas=[area_1]) - area_2 = self.test_data.create_curriculum_area(2) - self.test_data.create_integration(topic, 2, curriculum_areas=[area_1, area_2]) - self.test_data.create_integration(topic, 3) - self.test_data.create_integration(topic, 4) - management.call_command("rebuild_index", "--noinput") - url = reverse("search:index") - get_parameters = [ - ("curriculum_areas", area_1.pk), - ] - url += query_string(get_parameters) - response = self.client.get(url) - result_objects = response.context["object_list"] - self.assertEqual(len(result_objects), 2) - - def test_search_view_curriculum_areas_filter_2(self): - topic = self.test_data.create_topic(1) - area_1 = self.test_data.create_curriculum_area(1) - self.test_data.create_integration(topic, 1, curriculum_areas=[area_1]) - area_2 = self.test_data.create_curriculum_area(2) - self.test_data.create_integration(topic, 2, curriculum_areas=[area_1, area_2]) - self.test_data.create_integration(topic, 3) - self.test_data.create_integration(topic, 4) - management.call_command("rebuild_index", "--noinput") - url = reverse("search:index") - get_parameters = [ - ("curriculum_areas", area_2.pk), - ] - url += query_string(get_parameters) - response = self.client.get(url) - result_objects = response.context["object_list"] - self.assertEqual(len(result_objects), 1) - - def test_search_view_curriculum_areas_filter_parent_no_results(self): - # This search is not accessible to user, but - # checks indexes are created without including parent. - topic = self.test_data.create_topic(1) - area_1 = self.test_data.create_curriculum_area(1) - area_2 = self.test_data.create_curriculum_area(2, parent=area_1) - self.test_data.create_integration(topic, 1, curriculum_areas=[area_2]) + # def test_search_view_curriculum_areas_filter_parent_no_results(self): + # # This search is not accessible to user, but + # # checks indexes are created without including parent. + # topic = self.test_data.create_topic(1) + # area_1 = self.test_data.create_curriculum_area(1) + # area_2 = self.test_data.create_curriculum_area(2, parent=area_1) + # self.test_data.create_integration(topic, 1, curriculum_areas=[area_2]) - management.call_command("rebuild_index", "--noinput") - url = reverse("search:index") - get_parameters = [ - ("curriculum_areas", area_1.pk), - ] - url += query_string(get_parameters) - response = self.client.get(url) - self.assertFalse(response.context["object_list"]) + # management.call_command("rebuild_search_indexes") + # url = reverse("search:index") + # get_parameters = [ + # ("curriculum_areas", area_1.pk), + # ] + # url += query_string(get_parameters) + # response = self.client.get(url) + # self.assertFalse(response.context["results"]) - def test_search_view_curriculum_areas_filter_with_query(self): - topic = self.test_data.create_topic(1) - area_1 = self.test_data.create_curriculum_area(1) - self.test_data.create_integration(topic, 1, curriculum_areas=[area_1]) - area_2 = self.test_data.create_curriculum_area(2) - self.test_data.create_integration(topic, 2, curriculum_areas=[area_1, area_2]) - self.test_data.create_integration(topic, 3) - self.test_data.create_integration(topic, 4) - management.call_command("rebuild_index", "--noinput") - url = reverse("search:index") - get_parameters = [ - ("q", "Integration"), - ("curriculum_areas", area_2.pk), - ] - url += query_string(get_parameters) - response = self.client.get(url) - result_objects = response.context["object_list"] - self.assertEqual(len(result_objects), 1) - self.assertEqual(result_objects[0].object.name, "Integration 2") + # def test_search_view_curriculum_areas_filter_with_query(self): + # topic = self.test_data.create_topic(1) + # area_1 = self.test_data.create_curriculum_area(1) + # self.test_data.create_integration(topic, 1, curriculum_areas=[area_1]) + # area_2 = self.test_data.create_curriculum_area(2) + # self.test_data.create_integration(topic, 2, curriculum_areas=[area_1, area_2]) + # self.test_data.create_integration(topic, 3) + # self.test_data.create_integration(topic, 4) + # management.call_command("rebuild_search_indexes") + # url = reverse("search:index") + # get_parameters = [ + # ("q", "Integration"), + # ("curriculum_areas", area_2.pk), + # ] + # url += query_string(get_parameters) + # response = self.client.get(url) + # result_objects = response.context["results"] + # self.assertEqual(len(result_objects), 1) + # self.assertEqual(result_objects[0].object.name, "Integration 2") From 300d58121bfc4e5b88c118da7c1e601ba5ca0abd Mon Sep 17 00:00:00 2001 From: JackMorganNZ Date: Thu, 26 May 2022 21:14:56 +1200 Subject: [PATCH 013/195] Set thumbnail page for BinaryWindows resource --- .../resources/generators/BinaryWindowsResourceGenerator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csunplugged/resources/generators/BinaryWindowsResourceGenerator.py b/csunplugged/resources/generators/BinaryWindowsResourceGenerator.py index ead268b5c..94f5bacae 100644 --- a/csunplugged/resources/generators/BinaryWindowsResourceGenerator.py +++ b/csunplugged/resources/generators/BinaryWindowsResourceGenerator.py @@ -141,7 +141,7 @@ def front_page(self, value_type, column_width, show_bits_value, page_outline): image = self.add_dots(page_outline, column_width, show_bits_value) image = self.add_digit_values(page_outline, column_width, value_type, True) image = image.rotate(90, expand=True) - return {"type": "image", "data": image} + return {"type": "image", "data": image, "thumbnail": True} def back_page(self, value_type, column_width, page_outline): """Return a Pillow object of back page of Binary Windows. From cdfbdd519610501c32acab82740de0f8cd83b157 Mon Sep 17 00:00:00 2001 From: JackMorganNZ Date: Thu, 26 May 2022 21:52:05 +1200 Subject: [PATCH 014/195] Fix tests --- csunplugged/tests/classic/models/test_classic_page.py | 2 +- csunplugged/tests/general/models/test_general_page.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/csunplugged/tests/classic/models/test_classic_page.py b/csunplugged/tests/classic/models/test_classic_page.py index 3e73bff21..425c676c2 100644 --- a/csunplugged/tests/classic/models/test_classic_page.py +++ b/csunplugged/tests/classic/models/test_classic_page.py @@ -21,7 +21,7 @@ def test_classic_page_model_name(self): name="Page", redirect="http://www.example.com", ) - self.assertEqual(page.MODEL_NAME, "Classic CS Unplugged page") + self.assertEqual(page.MODEL_NAME, "Classic CS Unplugged Page") def test_classic_page_model_get_absolute_url(self): page = ClassicPage( diff --git a/csunplugged/tests/general/models/test_general_page.py b/csunplugged/tests/general/models/test_general_page.py index 49213bdd5..d1492708e 100644 --- a/csunplugged/tests/general/models/test_general_page.py +++ b/csunplugged/tests/general/models/test_general_page.py @@ -24,7 +24,7 @@ def test_general_page_model_name(self): template="template.html", url_name="url", ) - self.assertEqual(page.MODEL_NAME, "General page") + self.assertEqual(page.MODEL_NAME, "General Page") @override_settings(ROOT_URLCONF="tests.general.models.assets.urls") def test_general_page_model_get_absolute_url(self): From cddf057569616605ce9c73e09557b047d3350035 Mon Sep 17 00:00:00 2001 From: JackMorganNZ Date: Thu, 26 May 2022 21:56:14 +1200 Subject: [PATCH 015/195] Documentation updates --- docs/author/topics.rst | 8 +-- docs/developer/test_suite.rst | 2 +- docs/getting_started/helper_commands.rst | 89 +++++++++++++----------- docs/getting_started/installation.rst | 8 +-- docs/troubleshooting.rst | 24 +++---- 5 files changed, 70 insertions(+), 61 deletions(-) diff --git a/docs/author/topics.rst b/docs/author/topics.rst index d335b9dee..bd96aae58 100644 --- a/docs/author/topics.rst +++ b/docs/author/topics.rst @@ -44,7 +44,7 @@ This is a broad overview of the topics application, and the following sections p Viewing All Topics Content ------------------------------------------------------------------------------ -When developing locally, once you have run ``./csu start`` and ``./csu update`` (see +When developing locally, once you have run ``./dev start`` and ``./dev update`` (see :doc:`../getting_started/helper_commands`) you can go to the url below to see your local version of the website: @@ -130,12 +130,12 @@ To set up a new topic, which you can then add content to, you will first need to - Create a set of required directories and config files within the ``topics/structure/`` directory. - Add the minimum required configuration settings to these files. -Before you can run ``./csu update`` and view the topic on your local machine, these Markdown +Before you can run ``./dev update`` and view the topic on your local machine, these Markdown and YAML files must contain some required headings and content. We recommend adding some placeholder content to these files and checking that you can view them locally, before moving on to adding content. -After these steps have been completed you can run ``./csu update``, and view +After these steps have been completed you can run ``./dev update``, and view the topic at: .. code-block:: none @@ -178,7 +178,7 @@ Add the required fields, and their keys, to these YAML files: - The **lesson** config file. The required fields are listed in the section :ref:`lesson-file` section. -Now you can run the ./csu update command. +Now you can run the ``./dev update`` command. Once this has finished you will be able to view the topic at ``cs-unplugged.localhost/en/topics/`` The description of the topic is written in the **topic** Markdown file. diff --git a/docs/developer/test_suite.rst b/docs/developer/test_suite.rst index 0f64aa253..8989d22fe 100644 --- a/docs/developer/test_suite.rst +++ b/docs/developer/test_suite.rst @@ -8,7 +8,7 @@ Test Suite Running the Test Suite ============================================================================== -``./csu test_suite`` will run the entire test suite. For running a specific tests, viewing code coverage, and more testing commands, see :doc:`../getting_started/helper_commands`. +``./dev test_suite`` will run the entire test suite. For running a specific tests, viewing code coverage, and more testing commands, see :doc:`../getting_started/helper_commands`. Structure diff --git a/docs/getting_started/helper_commands.rst b/docs/getting_started/helper_commands.rst index 1d77522a3..dac8f9ae1 100644 --- a/docs/getting_started/helper_commands.rst +++ b/docs/getting_started/helper_commands.rst @@ -7,12 +7,12 @@ Helper Commands for Developing The CS Unplugged project uses many systems (Django, Docker, Gulp, etc) to run, so we have written a script for running groups of commands for running the system while developing. -The script is called ``csu`` and can be found in the ``cs-unplugged`` folder of the repository. +The script is called ``dev`` and can be found in the ``cs-unplugged`` folder of the repository. To run this script, open a terminal window in the directory and enter the following command (you don't need to enter the ``$`` character, this shows the start of your terminal prompt): .. code-block:: bash - $ ./csu [COMMAND] + $ ./dev [COMMAND] Where ``[COMMAND]`` is a word from the list below: @@ -62,7 +62,7 @@ All users of the project (content and technical developers) should become famili ``build`` ============================================================================== -Running ``./csu build`` will build or rebuild the Docker images that are required for the CS Unplugged system. +Running ``./dev build`` will build or rebuild the Docker images that are required for the CS Unplugged system. ----------------------------------------------------------------------------- @@ -71,7 +71,7 @@ Running ``./csu build`` will build or rebuild the Docker images that are require ``clean`` ============================================================================== -Running ``./csu clean`` deletes 'dangling' Docker images left over from builds, which will free up hard drive space. +Running ``./dev clean`` deletes 'dangling' Docker images left over from builds, which will free up hard drive space. ----------------------------------------------------------------------------- @@ -80,7 +80,7 @@ Running ``./csu clean`` deletes 'dangling' Docker images left over from builds, ``collect_static`` ============================================================================== -Running ``./csu collect_static`` runs the Django ``collectstatic`` command to collect static files. +Running ``./dev collect_static`` runs the Django ``collectstatic`` command to collect static files. It will copy files under the ``static/`` folder into the ``staticfiles/`` folder. ----------------------------------------------------------------------------- @@ -90,7 +90,7 @@ It will copy files under the ``static/`` folder into the ``staticfiles/`` folder ``compilemessages`` ============================================================================== -Running ``./csu compilemessages`` runs the Django ``compilemessages`` command. +Running ``./dev compilemessages`` runs the Django ``compilemessages`` command. This runs over ``.po`` files and creates ``.mo`` files which are optimised for use by ``gettext``. You will need to run this command after each time you create your message file or each time you make changes to it. @@ -101,7 +101,7 @@ You will need to run this command after each time you create your message file o ``docs`` ============================================================================== -Running ``./csu docs`` will remove any existing documentation and build a fresh copy of the documentation for CS Unplugged. +Running ``./dev docs`` will remove any existing documentation and build a fresh copy of the documentation for CS Unplugged. ----------------------------------------------------------------------------- @@ -110,7 +110,7 @@ Running ``./csu docs`` will remove any existing documentation and build a fresh ``end`` ============================================================================== -Running ``./csu end`` will stop any containers which are currently running, this usually takes 10 to 20 seconds. +Running ``./dev end`` will stop any containers which are currently running, this usually takes 10 to 20 seconds. ----------------------------------------------------------------------------- @@ -119,7 +119,7 @@ Running ``./csu end`` will stop any containers which are currently running, this ``flush`` ============================================================================== -Running ``./csu flush`` runs the Django ``flush`` command to flush the database. +Running ``./dev flush`` runs the Django ``flush`` command to flush the database. ----------------------------------------------------------------------------- @@ -128,7 +128,7 @@ Running ``./csu flush`` runs the Django ``flush`` command to flush the database. ``help`` ============================================================================== -Running ``./csu help`` displays brief help text for the script. +Running ``./dev help`` displays brief help text for the script. More details for each command can be found on this page. ----------------------------------------------------------------------------- @@ -138,7 +138,7 @@ More details for each command can be found on this page. ``logs`` ============================================================================== -Running ``./csu logs`` will display the logs for the running systems. +Running ``./dev logs`` will display the logs for the running systems. The output is for all logs until the time the command was run, therefore successive calls may display new logs. To follow logs as they output, enter ``docker-compose logs --follow``. @@ -150,7 +150,7 @@ To follow logs as they output, enter ``docker-compose logs --follow``. ``makemessages`` ============================================================================== -Running ``./csu makemessages`` runs the Djanog ``makemessages`` command. +Running ``./dev makemessages`` runs the Djanog ``makemessages`` command. This will create message files where each message file represents a single language. Message files contain all available translation strings and how they should be represented in the given language. @@ -161,7 +161,7 @@ Message files contain all available translation strings and how they should be r ``makemigrations`` ============================================================================== -Running ``./csu makemigrations`` runs the Django ``makemigrations`` command to create migration files. +Running ``./dev makemigrations`` runs the Django ``makemigrations`` command to create migration files. ----------------------------------------------------------------------------- @@ -170,7 +170,7 @@ Running ``./csu makemigrations`` runs the Django ``makemigrations`` command to c ``makeresources`` ============================================================================== -Running ``./csu makeresources`` runs the custom Django ``makeresources`` command to create static resource PDF files. +Running ``./dev makeresources`` runs the custom Django ``makeresources`` command to create static resource PDF files. ----------------------------------------------------------------------------- @@ -179,7 +179,7 @@ Running ``./csu makeresources`` runs the custom Django ``makeresources`` command ``makeresourcethumbnails`` ============================================================================== -Running ``./csu makeresourcethumbnails`` generates the thumbnails for each resource PDF. +Running ``./dev makeresourcethumbnails`` generates the thumbnails for each resource PDF. ----------------------------------------------------------------------------- @@ -188,7 +188,7 @@ Running ``./csu makeresourcethumbnails`` generates the thumbnails for each resou ``migrate`` ============================================================================== -Running ``./csu migrate`` runs the Django ``migrate`` command to apply migration files. +Running ``./dev migrate`` runs the Django ``migrate`` command to apply migration files. ----------------------------------------------------------------------------- @@ -197,7 +197,16 @@ Running ``./csu migrate`` runs the Django ``migrate`` command to apply migration ``reboot_django`` ============================================================================== -Running ``./csu reboot_django`` will rebuild the Django Docker container. +Running ``./dev reboot_django`` will rebuild the Django Docker container. + +----------------------------------------------------------------------------- + +.. _rebuild_index: + +``rebuild_index`` +============================================================================== + +Running ``./dev rebuild_index`` will rebuild the search indexes. ----------------------------------------------------------------------------- @@ -206,10 +215,10 @@ Running ``./csu reboot_django`` will rebuild the Django Docker container. ``restart`` ============================================================================== -Running ``./csu restart`` is a shortcut for running: +Running ``./dev restart`` is a shortcut for running: -- ``./csu end`` -- ``./csu start`` +- ``./dev end`` +- ``./dev start`` More details for each command can be found on this page. @@ -220,7 +229,7 @@ More details for each command can be found on this page. ``shell`` ============================================================================== -Running ``./csu shell`` opens a bash terminal within the Django container (this requires the CS Unplugged system to be running). +Running ``./dev shell`` opens a bash terminal within the Django container (this requires the CS Unplugged system to be running). This is the equivalent to entering ``docker-compose run django bash``. @@ -231,7 +240,7 @@ This is the equivalent to entering ``docker-compose run django bash``. ``start`` ============================================================================== -Running ``./csu start`` starts the development environment. +Running ``./dev start`` starts the development environment. It performs the following tasks: - Build system Docker images if required (see below) @@ -239,12 +248,12 @@ It performs the following tasks: - Start the Nginx server to display the website and static files - Start the database server -When you run this command for the first time on a computer it will also run ``./csu build`` to build the system Docker images. +When you run this command for the first time on a computer it will also run ``./dev build`` to build the system Docker images. This can take some time, roughly 15 to 30 minutes, depending on your computer and internet speed. -Images are only required to be built once, unless the image specifications change (you can rebuild the images with ``./csu build``). +Images are only required to be built once, unless the image specifications change (you can rebuild the images with ``./dev build``). Once the images are built, the script will run these images in containers. -Once the development environment is operational, run the ``./csu update`` command to load the CS Unplugged content. +Once the development environment is operational, run the ``./dev update`` command to load the CS Unplugged content. ----------------------------------------------------------------------------- @@ -253,7 +262,7 @@ Once the development environment is operational, run the ``./csu update`` comman ``static`` ============================================================================== -Running ``./csu static`` runs the commands for generating the static files for the website. +Running ``./dev static`` runs the commands for generating the static files for the website. If changes are made to the static files (for example, a new image is added) when the system is running, this command needs to be entered to view the new files on the website. @@ -264,7 +273,7 @@ If changes are made to the static files (for example, a new image is added) when ``static_prod`` ============================================================================== -Running ``./csu static_prod`` runs the commands for generating production static files for the website. +Running ``./dev static_prod`` runs the commands for generating production static files for the website. This produces compressed SASS files without sourcemaps. ----------------------------------------------------------------------------- @@ -274,7 +283,7 @@ This produces compressed SASS files without sourcemaps. ``static_scratch`` ============================================================================== -Running ``./csu static_scratch`` runs the commands for generating scratch images for the website. +Running ``./dev static_scratch`` runs the commands for generating scratch images for the website. ----------------------------------------------------------------------------- @@ -283,7 +292,7 @@ Running ``./csu static_scratch`` runs the commands for generating scratch images ``style`` ============================================================================== -Running ``./csu style`` will run the ``flake8`` and ``pydocstyle`` commands to check the style of the project. +Running ``./dev style`` will run the ``flake8`` and ``pydocstyle`` commands to check the style of the project. If the output is ``0`` for a check, then there are zero errors. ----------------------------------------------------------------------------- @@ -293,7 +302,7 @@ If the output is ``0`` for a check, then there are zero errors. ``test_backwards`` ============================================================================== -Running ``./csu test_backwards`` will run the test suite in reverse. +Running ``./dev test_backwards`` will run the test suite in reverse. This is useful to check if any tests are influencing the result of each other. If this command if run on Travis CI, it will only run for a pull request. @@ -304,7 +313,7 @@ If this command if run on Travis CI, it will only run for a pull request. ``test_coverage`` ============================================================================== -Running ``./csu test_coverage`` will display a table detailing test code coverage, from the report generated by ``./csu test``. +Running ``./dev test_coverage`` will display a table detailing test code coverage, from the report generated by ``./dev test``. ----------------------------------------------------------------------------- @@ -313,8 +322,8 @@ Running ``./csu test_coverage`` will display a table detailing test code coverag ``test_specific`` ============================================================================== -Running ``./csu test_specific [MODULE_PATH]`` will run a specific test module. -For example, running ``./csu test_specific tests.resources.views.test_index_view`` will only run the tests for checking the index view of the resources application. +Running ``./dev test_specific [MODULE_PATH]`` will run a specific test module. +For example, running ``./dev test_specific tests.resources.views.test_index_view`` will only run the tests for checking the index view of the resources application. ----------------------------------------------------------------------------- @@ -323,8 +332,8 @@ For example, running ``./csu test_specific tests.resources.views.test_index_view ``test_suite`` ============================================================================== -Running ``./csu test_suite`` will run the test suite, and create a report detailing test code coverage. -The code coverage report can be displayed by running ``./csu test_coverage``. +Running ``./dev test_suite`` will run the test suite, and create a report detailing test code coverage. +The code coverage report can be displayed by running ``./dev test_coverage``. ----------------------------------------------------------------------------- @@ -333,7 +342,7 @@ The code coverage report can be displayed by running ``./csu test_coverage``. ``update`` ============================================================================== -Running ``./csu update`` performs the following tasks: +Running ``./dev update`` performs the following tasks: - Update the database with the required structure (known as the schema) - Load the CS Unplugged content into the database @@ -342,7 +351,7 @@ Running ``./csu update`` performs the following tasks: Once the script has performed all these tasks, the script will let you know the website is ready. Open your preferred web browser to the URL ``cs-unplugged.localhost`` to view the website. -In more detail, ``./csu update`` runs the Django ``makemigratations`` and ``migrate`` commands for updating the database schema, and then runs the custom ``updatedata`` command to load the topics content into the database. +In more detail, ``./dev update`` runs the Django ``makemigratations`` and ``migrate`` commands for updating the database schema, and then runs the custom ``updatedata`` command to load the topics content into the database. It also runs the ``static`` command to generate static files. If changes are made to the topics content when the system is running, this command needs to be run to view the new changes on the website. @@ -354,7 +363,7 @@ If changes are made to the topics content when the system is running, this comma ``updatedata`` ============================================================================== -Running ``./csu updatedata`` runs the custom ``updatedata`` command to load the topics content into the database. +Running ``./dev updatedata`` runs the custom ``updatedata`` command to load the topics content into the database. ----------------------------------------------------------------------------- @@ -363,7 +372,7 @@ Running ``./csu updatedata`` runs the custom ``updatedata`` command to load the ``update_lite`` ============================================================================== -Running ``./csu update_lite`` only loads key content. +Running ``./dev update_lite`` only loads key content. Useful for development. ----------------------------------------------------------------------------- @@ -373,7 +382,7 @@ Useful for development. ``wipe`` ============================================================================== -Running ``./csu wipe`` delete all Docker containers and images on your computer. +Running ``./dev wipe`` delete all Docker containers and images on your computer. Once this command has be run, a full download and rebuild of images is required to run the system (can be triggered by the ``build`` or ``start`` commands). ----------------------------------------------------------------------------- diff --git a/docs/getting_started/installation.rst b/docs/getting_started/installation.rst index ef8b3bc49..a8b30fe95 100644 --- a/docs/getting_started/installation.rst +++ b/docs/getting_started/installation.rst @@ -115,7 +115,7 @@ character, this shows the start of your terminal prompt). Depending on your operating system, if the above commands don't work you may need to set Docker to be able to run without ``sudo``. - You will need to do this in order to use the ``csu`` helper script. + You will need to do this in order to use the ``dev`` helper script. Step 7: Install Text Editor/IDE (optional) ================================================= @@ -222,15 +222,15 @@ Step 9: Check Project Setup Works To check the project works, open a terminal in the project root directory, which is the ``cs-unplugged/`` directory (should contain a file called -``csu``). +``dev``). Type the following commands into the terminal (we will cover these commands in more detail on the next page): .. code-block:: bash - $ ./csu start - $ ./csu update + $ ./dev start + $ ./dev update If this is the first time you're running this script, it will need to build system images. diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst index f541f24cd..246464b3a 100644 --- a/docs/troubleshooting.rst +++ b/docs/troubleshooting.rst @@ -1,27 +1,27 @@ Troubleshooting ############################################################################## -``csu`` helper script +``dev`` helper script ============================================================================== -I get a ``No such file or directory`` error when running the ``csu`` script +I get a ``No such file or directory`` error when running the ``dev`` script ------------------------------------------------------------------------------ Check your terminal working directory is within the ``cs-unplugged`` directory, the root directory of the project. -Running the ``ls`` command in this directory should list the ``csu`` file. +Running the ``ls`` command in this directory should list the ``dev`` file. -I have an error when running ``./csu start`` +I have an error when running ``./dev start`` ------------------------------------------------------------------------------ If you are having issues running the ``start`` command, try rebuilding the -system images with ``./csu build``. +system images with ``./dev build``. Changes may be have been made to the system images since you initally created them. If this still doesn't solve your problem, you could also try deleting any -existing images with ``./csu wipe``, and then build and start the system with -``./csu start``. +existing images with ``./dev wipe``, and then build and start the system with +``./dev start``. If issue still persists, log a bug on our `issue tracker`_. @@ -39,7 +39,7 @@ located within the ``static`` directory. If the image is located within the ``static/`` directory, check the filepath is correct. -When running ``./csu update``, the script will report an error if an image +When running ``./dev update``, the script will report an error if an image cannot be found. **Scratch block images** @@ -50,7 +50,7 @@ find & replace is your friend here). If you can find the file with the same block syntax and there isn't a image in the ``staticfiles/`` directory with the same filename -(``.svg`` instead of ``.txt``), try running ``./csu update``. +(``.svg`` instead of ``.txt``), try running ``./dev update``. If this doesn't fix the problem, the problem is in our scripts so log a bug on our `issue tracker`_. @@ -64,14 +64,14 @@ Changed CSS/SCSS styles are not updated when I view the website Firstly check the compiled CSS is located in the ``staticfiles/`` directory, and that the changes have appeared in the compiled CSS file. -If the CSS file does not include the changes made, run ``./csu static``. -If you are editing SCSS files, check the ``./csu static`` command isn't reporting +If the CSS file does not include the changes made, run ``./dev static``. +If you are editing SCSS files, check the ``./dev static`` command isn't reporting SCSS compilation errors. The website isn't displaying when I open ``cs-unplugged.localhost`` in a browser ---------------------------------------------------------------------------------------------- -Check you have run the ``./csu start`` command, and that it hasn't reported any +Check you have run the ``./dev start`` command, and that it hasn't reported any errors. .. _issue tracker: https://github.com/uccser/cs-unplugged/issues From 5a07936815220611231e76f7ca301cc85baa1fac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jun 2022 02:07:49 +0000 Subject: [PATCH 016/195] Bump whitenoise from 5.3.0 to 6.2.0 Bumps [whitenoise](https://github.com/evansd/whitenoise) from 5.3.0 to 6.2.0. - [Release notes](https://github.com/evansd/whitenoise/releases) - [Changelog](https://github.com/evansd/whitenoise/blob/main/docs/changelog.rst) - [Commits](https://github.com/evansd/whitenoise/compare/v5.3.0...6.2.0) --- updated-dependencies: - dependency-name: whitenoise dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/base.txt b/requirements/base.txt index e8f05caf4..6de9d30c5 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -5,7 +5,7 @@ django-bootstrap-breadcrumbs==0.9.2 # Web serving gunicorn==20.1.0 -whitenoise==5.3.0 +whitenoise==6.2.0 # Database APIs psycopg2==2.9.3 From d62adbc5d553e8ce445e3497fa1ca28fa3d1f5e7 Mon Sep 17 00:00:00 2001 From: JackMorganNZ Date: Tue, 7 Jun 2022 20:51:57 +1200 Subject: [PATCH 017/195] Upload test coverage to codecov --- .github/workflows/test-and-deploy.yaml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.github/workflows/test-and-deploy.yaml b/.github/workflows/test-and-deploy.yaml index 4aac92b0f..10444e8b7 100644 --- a/.github/workflows/test-and-deploy.yaml +++ b/.github/workflows/test-and-deploy.yaml @@ -55,6 +55,13 @@ jobs: uses: actions/checkout@v2 - name: Run general tests run: ./dev ci test_general + - name: Create coverage file + run: docker-compose -f docker-compose.local.yml run --rm --user="root" django coverage xml -i + - name: Upload coverage file + uses: codecov/codecov-action@v3 + with: + files: ./csunplugged/coverage.xml + verbose: true test-resources: name: Tests - Resources @@ -64,6 +71,13 @@ jobs: uses: actions/checkout@v2 - name: Run resource tests run: ./dev ci test_resources + - name: Create coverage file + run: docker-compose -f docker-compose.local.yml run --rm --user="root" django coverage xml -i + - name: Upload coverage file + uses: codecov/codecov-action@v3 + with: + files: ./csunplugged/coverage.xml + verbose: true test-management: name: Tests - Management @@ -73,6 +87,13 @@ jobs: uses: actions/checkout@v2 - name: Run management tests run: ./dev ci test_management + - name: Create coverage file + run: docker-compose -f docker-compose.local.yml run --rm --user="root" django coverage xml -i + - name: Upload coverage file + uses: codecov/codecov-action@v3 + with: + files: ./csunplugged/coverage.xml + verbose: true test-style: name: Tests - Style From f6d792fca9d96dcbdd33db7f01c7a9c01e219aca Mon Sep 17 00:00:00 2001 From: JackMorganNZ Date: Tue, 7 Jun 2022 20:52:27 +1200 Subject: [PATCH 018/195] Remove unused index files --- .../search/indexes/classic/classicpage_text.txt | 1 - .../search/indexes/resources/resource_text.txt | 1 - .../search/indexes/topics/curriculumarea_text.txt | 1 - .../indexes/topics/curriculumintegration_text.txt | 8 -------- .../templates/search/indexes/topics/lesson_text.txt | 11 ----------- .../indexes/topics/programmingchallenge_text.txt | 3 --- .../templates/search/indexes/topics/topic_text.txt | 3 --- .../templates/search/indexes/topics/unitplan_text.txt | 3 --- 8 files changed, 31 deletions(-) delete mode 100644 csunplugged/templates/search/indexes/classic/classicpage_text.txt delete mode 100644 csunplugged/templates/search/indexes/resources/resource_text.txt delete mode 100644 csunplugged/templates/search/indexes/topics/curriculumarea_text.txt delete mode 100644 csunplugged/templates/search/indexes/topics/curriculumintegration_text.txt delete mode 100644 csunplugged/templates/search/indexes/topics/lesson_text.txt delete mode 100644 csunplugged/templates/search/indexes/topics/programmingchallenge_text.txt delete mode 100644 csunplugged/templates/search/indexes/topics/topic_text.txt delete mode 100644 csunplugged/templates/search/indexes/topics/unitplan_text.txt diff --git a/csunplugged/templates/search/indexes/classic/classicpage_text.txt b/csunplugged/templates/search/indexes/classic/classicpage_text.txt deleted file mode 100644 index bd75d3960..000000000 --- a/csunplugged/templates/search/indexes/classic/classicpage_text.txt +++ /dev/null @@ -1 +0,0 @@ -{{ object.name }} diff --git a/csunplugged/templates/search/indexes/resources/resource_text.txt b/csunplugged/templates/search/indexes/resources/resource_text.txt deleted file mode 100644 index bd75d3960..000000000 --- a/csunplugged/templates/search/indexes/resources/resource_text.txt +++ /dev/null @@ -1 +0,0 @@ -{{ object.name }} diff --git a/csunplugged/templates/search/indexes/topics/curriculumarea_text.txt b/csunplugged/templates/search/indexes/topics/curriculumarea_text.txt deleted file mode 100644 index 3cbd38cb7..000000000 --- a/csunplugged/templates/search/indexes/topics/curriculumarea_text.txt +++ /dev/null @@ -1 +0,0 @@ -{{ object }} diff --git a/csunplugged/templates/search/indexes/topics/curriculumintegration_text.txt b/csunplugged/templates/search/indexes/topics/curriculumintegration_text.txt deleted file mode 100644 index 5d2bca909..000000000 --- a/csunplugged/templates/search/indexes/topics/curriculumintegration_text.txt +++ /dev/null @@ -1,8 +0,0 @@ -{{ object.name }} -{{ object.content }} -{% for curriculum_area in object.curriculum_areas.all %} - {{ curriculum_area.name }} - {% if curriculum_area.parent %} - {{ curriculum_area.parent.name }} - {% endif %} -{% endfor %} diff --git a/csunplugged/templates/search/indexes/topics/lesson_text.txt b/csunplugged/templates/search/indexes/topics/lesson_text.txt deleted file mode 100644 index 308665962..000000000 --- a/csunplugged/templates/search/indexes/topics/lesson_text.txt +++ /dev/null @@ -1,11 +0,0 @@ -{{ object.name }} -{{ object.content }} -{{ object.computational_thinking_links }} -{% for learning_outcome in object.learning_outcomes.all %} - {% for curriculum_area in learning_outcome.curriculum_areas.all %} - {{ curriculum_area.name }} - {% if curriculum_area.parent %} - {{ curriculum_area.parent.name }} - {% endif %} - {% endfor %} -{% endfor %} diff --git a/csunplugged/templates/search/indexes/topics/programmingchallenge_text.txt b/csunplugged/templates/search/indexes/topics/programmingchallenge_text.txt deleted file mode 100644 index 20bafd462..000000000 --- a/csunplugged/templates/search/indexes/topics/programmingchallenge_text.txt +++ /dev/null @@ -1,3 +0,0 @@ -{{ object.name }} -{{ object.content }} -{{ object.extra_challenge }} diff --git a/csunplugged/templates/search/indexes/topics/topic_text.txt b/csunplugged/templates/search/indexes/topics/topic_text.txt deleted file mode 100644 index 4db4cc556..000000000 --- a/csunplugged/templates/search/indexes/topics/topic_text.txt +++ /dev/null @@ -1,3 +0,0 @@ -{{ object.name }} -{{ object.content }} -{{ object.other_resources }} diff --git a/csunplugged/templates/search/indexes/topics/unitplan_text.txt b/csunplugged/templates/search/indexes/topics/unitplan_text.txt deleted file mode 100644 index 8bda847b5..000000000 --- a/csunplugged/templates/search/indexes/topics/unitplan_text.txt +++ /dev/null @@ -1,3 +0,0 @@ -{{ object.name }} -{{ object.content }} -{{ object.computational_thinking_links }} From 64fc6469c1486dfc4f0b8fe879aae580c9d4207f Mon Sep 17 00:00:00 2001 From: JackMorganNZ Date: Thu, 9 Jun 2022 11:13:16 +1200 Subject: [PATCH 019/195] Auto-merge minor dependency updates --- .github/dependabot.yml | 8 ++--- .../auto-merge-dependency-updates.yaml | 30 +++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/auto-merge-dependency-updates.yaml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 25fdd00ea..ee44be568 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,19 +9,19 @@ updates: directory: "/" schedule: interval: "daily" - open-pull-requests-limit: 10 + open-pull-requests-limit: 999 - package-ecosystem: "npm" directory: "/csunplugged/" schedule: interval: "daily" - open-pull-requests-limit: 10 + open-pull-requests-limit: 999 - package-ecosystem: "pip" directory: "/" schedule: interval: "daily" - open-pull-requests-limit: 10 + open-pull-requests-limit: 999 - package-ecosystem: "github-actions" directory: "/" schedule: interval: "daily" - open-pull-requests-limit: 10 + open-pull-requests-limit: 999 diff --git a/.github/workflows/auto-merge-dependency-updates.yaml b/.github/workflows/auto-merge-dependency-updates.yaml new file mode 100644 index 000000000..51dd6ae47 --- /dev/null +++ b/.github/workflows/auto-merge-dependency-updates.yaml @@ -0,0 +1,30 @@ +name: Auto-merge minor dependency updates + +on: pull_request + +permissions: + pull-requests: write + contents: write + +jobs: + check-pull-request: + runs-on: ubuntu-latest + if: ${{ github.actor == 'dependabot[bot]' }} + steps: + - name: Dependabot metadata + id: metadata + uses: dependabot/fetch-metadata@v1.3.1 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + - name: Approve + if: ${{steps.metadata.outputs.update-type == 'version-update:semver-minor' || steps.metadata.outputs.update-type == 'version-update:semver-patch'}} + run: gh pr review --body "Automatic approval for minor dependency update." --approve "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + - name: Merge + if: ${{steps.metadata.outputs.update-type == 'version-update:semver-minor' || steps.metadata.outputs.update-type == 'version-update:semver-patch'}} + run: gh pr merge --auto --merge "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} From 832dd654f07a0220cb74ebd6c4ee655cba95a224 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jun 2022 23:13:52 +0000 Subject: [PATCH 020/195] Bump django-cors-headers from 3.11.0 to 3.13.0 Bumps [django-cors-headers](https://github.com/adamchainz/django-cors-headers) from 3.11.0 to 3.13.0. - [Release notes](https://github.com/adamchainz/django-cors-headers/releases) - [Changelog](https://github.com/adamchainz/django-cors-headers/blob/main/HISTORY.rst) - [Commits](https://github.com/adamchainz/django-cors-headers/compare/3.11.0...3.13.0) --- updated-dependencies: - dependency-name: django-cors-headers dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/base.txt b/requirements/base.txt index e8f05caf4..8ec0f28a2 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -40,4 +40,4 @@ django-bidi-utils==1.0 requests==2.27.1 # CORS -django-cors-headers==3.11.0 +django-cors-headers==3.13.0 From 05011a4c4887e2ee024aefd2bdd4d8f5bf8b71e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jun 2022 23:15:00 +0000 Subject: [PATCH 021/195] Bump django from 3.2.11 to 3.2.13 in /requirements Bumps [django](https://github.com/django/django) from 3.2.11 to 3.2.13. - [Release notes](https://github.com/django/django/releases) - [Commits](https://github.com/django/django/compare/3.2.11...3.2.13) --- updated-dependencies: - dependency-name: django dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/base.txt b/requirements/base.txt index 8ec0f28a2..77a192f00 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -1,5 +1,5 @@ # Django -django==3.2.11 +django==3.2.13 django-environ==0.8.1 django-bootstrap-breadcrumbs==0.9.2 From 192c43cc01fd183447988ec4031dfb8b57ae04fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jun 2022 23:16:35 +0000 Subject: [PATCH 022/195] Bump ansi-colors from 4.1.1 to 4.1.3 in /csunplugged Bumps [ansi-colors](https://github.com/doowb/ansi-colors) from 4.1.1 to 4.1.3. - [Release notes](https://github.com/doowb/ansi-colors/releases) - [Commits](https://github.com/doowb/ansi-colors/compare/4.1.1...4.1.3) --- updated-dependencies: - dependency-name: ansi-colors dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- csunplugged/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csunplugged/package.json b/csunplugged/package.json index 317002c7f..4b935dd26 100644 --- a/csunplugged/package.json +++ b/csunplugged/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": {}, "devDependencies": { - "ansi-colors": "4.1.1", + "ansi-colors": "4.1.3", "autoprefixer": "10.4.2", "bootstrap": "4.6.0", "browser-sync": "2.27.7", From 8ed505eb5c7d5b0827bde2b91dd773c9543ee432 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jun 2022 23:16:47 +0000 Subject: [PATCH 023/195] Bump yargs from 17.3.1 to 17.5.1 in /csunplugged Bumps [yargs](https://github.com/yargs/yargs) from 17.3.1 to 17.5.1. - [Release notes](https://github.com/yargs/yargs/releases) - [Changelog](https://github.com/yargs/yargs/blob/main/CHANGELOG.md) - [Commits](https://github.com/yargs/yargs/compare/v17.3.1...v17.5.1) --- updated-dependencies: - dependency-name: yargs dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- csunplugged/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csunplugged/package.json b/csunplugged/package.json index 317002c7f..1d57458c7 100644 --- a/csunplugged/package.json +++ b/csunplugged/package.json @@ -36,7 +36,7 @@ "sass": "1.49.0", "scratchblocks": "uccser/scratchblocks#master", "vinyl-buffer": "1.0.1", - "yargs": "17.3.1" + "yargs": "17.5.1" }, "engines": { "node": ">=8" From f8041f843a57f9fd83750214e0581586082bde10 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jun 2022 23:20:00 +0000 Subject: [PATCH 024/195] Bump browser-sync from 2.27.7 to 2.27.10 in /csunplugged Bumps [browser-sync](https://github.com/BrowserSync/browser-sync) from 2.27.7 to 2.27.10. - [Release notes](https://github.com/BrowserSync/browser-sync/releases) - [Changelog](https://github.com/BrowserSync/browser-sync/blob/master/CHANGELOG.md) - [Commits](https://github.com/BrowserSync/browser-sync/compare/v2.27.7...v2.27.10) --- updated-dependencies: - dependency-name: browser-sync dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- csunplugged/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csunplugged/package.json b/csunplugged/package.json index 4b935dd26..7d4ea175e 100644 --- a/csunplugged/package.json +++ b/csunplugged/package.json @@ -7,7 +7,7 @@ "ansi-colors": "4.1.3", "autoprefixer": "10.4.2", "bootstrap": "4.6.0", - "browser-sync": "2.27.7", + "browser-sync": "2.27.10", "browserify": "17.0.0", "child_process": "1.0.2", "codemirror": "5.65.1", From 75e6f914ab96676096e30a2e05e1a09c18e58b10 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jun 2022 23:20:15 +0000 Subject: [PATCH 025/195] Bump autoprefixer from 10.4.2 to 10.4.7 in /csunplugged Bumps [autoprefixer](https://github.com/postcss/autoprefixer) from 10.4.2 to 10.4.7. - [Release notes](https://github.com/postcss/autoprefixer/releases) - [Changelog](https://github.com/postcss/autoprefixer/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/autoprefixer/compare/10.4.2...10.4.7) --- updated-dependencies: - dependency-name: autoprefixer dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- csunplugged/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csunplugged/package.json b/csunplugged/package.json index 4b935dd26..ee339af92 100644 --- a/csunplugged/package.json +++ b/csunplugged/package.json @@ -5,7 +5,7 @@ "dependencies": {}, "devDependencies": { "ansi-colors": "4.1.3", - "autoprefixer": "10.4.2", + "autoprefixer": "10.4.7", "bootstrap": "4.6.0", "browser-sync": "2.27.7", "browserify": "17.0.0", From f52e9005a2620505b19e717bb81db7e020a602b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jun 2022 23:35:01 +0000 Subject: [PATCH 026/195] Bump sass from 1.49.0 to 1.52.2 in /csunplugged Bumps [sass](https://github.com/sass/dart-sass) from 1.49.0 to 1.52.2. - [Release notes](https://github.com/sass/dart-sass/releases) - [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md) - [Commits](https://github.com/sass/dart-sass/compare/1.49.0...1.52.2) --- updated-dependencies: - dependency-name: sass dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- csunplugged/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csunplugged/package.json b/csunplugged/package.json index b16f5936c..5d3081bff 100644 --- a/csunplugged/package.json +++ b/csunplugged/package.json @@ -33,7 +33,7 @@ "popper.js": "1.16.1", "postcss": "8.4.5", "postcss-flexbugs-fixes": "5.0.2", - "sass": "1.49.0", + "sass": "1.52.2", "scratchblocks": "uccser/scratchblocks#master", "vinyl-buffer": "1.0.1", "yargs": "17.5.1" From 82321cb296ded3ad5c5a84a5e9f6b0b36d951c57 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jun 2022 23:38:32 +0000 Subject: [PATCH 027/195] Bump postcss from 8.4.5 to 8.4.14 in /csunplugged Bumps [postcss](https://github.com/postcss/postcss) from 8.4.5 to 8.4.14. - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss/compare/8.4.5...8.4.14) --- updated-dependencies: - dependency-name: postcss dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- csunplugged/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csunplugged/package.json b/csunplugged/package.json index d190c8358..005eecd31 100644 --- a/csunplugged/package.json +++ b/csunplugged/package.json @@ -31,7 +31,7 @@ "multiple-select": "1.5.2", "pixrem": "5.0.0", "popper.js": "1.16.1", - "postcss": "8.4.5", + "postcss": "8.4.14", "postcss-flexbugs-fixes": "5.0.2", "sass": "1.52.2", "scratchblocks": "uccser/scratchblocks#master", From 8b50d4925c1de92f6594735eeee56677da8e72bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jun 2022 02:08:15 +0000 Subject: [PATCH 028/195] Bump requests from 2.27.1 to 2.28.0 Bumps [requests](https://github.com/psf/requests) from 2.27.1 to 2.28.0. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](https://github.com/psf/requests/compare/v2.27.1...v2.28.0) --- updated-dependencies: - dependency-name: requests dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/base.txt b/requirements/base.txt index 77a192f00..003c540b3 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -37,7 +37,7 @@ python-bidi==0.4.2 django-bidi-utils==1.0 # Plugging it in -requests==2.27.1 +requests==2.28.0 # CORS django-cors-headers==3.13.0 From 0dc583f55641c400b3386709aacb4ecb09d7c865 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jun 2022 02:13:26 +0000 Subject: [PATCH 029/195] Bump sass from 1.52.2 to 1.52.3 in /csunplugged Bumps [sass](https://github.com/sass/dart-sass) from 1.52.2 to 1.52.3. - [Release notes](https://github.com/sass/dart-sass/releases) - [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md) - [Commits](https://github.com/sass/dart-sass/compare/1.52.2...1.52.3) --- updated-dependencies: - dependency-name: sass dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- csunplugged/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csunplugged/package.json b/csunplugged/package.json index 005eecd31..539615437 100644 --- a/csunplugged/package.json +++ b/csunplugged/package.json @@ -33,7 +33,7 @@ "popper.js": "1.16.1", "postcss": "8.4.14", "postcss-flexbugs-fixes": "5.0.2", - "sass": "1.52.2", + "sass": "1.52.3", "scratchblocks": "uccser/scratchblocks#master", "vinyl-buffer": "1.0.1", "yargs": "17.5.1" From cee74ef326ff789087534a3aae953d328dc97f91 Mon Sep 17 00:00:00 2001 From: JackMorganNZ Date: Mon, 13 Jun 2022 09:55:36 +1200 Subject: [PATCH 030/195] Initial removal of unit plan model Todo: - URL redirects - Update tests --- .../management/commands/_ActivityLoader.py | 1 - csunplugged/search/settings.py | 10 +- csunplugged/templates/moocs/index.html | 10 +- .../plugging_it_in/programming-challenge.html | 2 +- csunplugged/templates/resources/resource.html | 2 +- .../search/result/topics.lesson.html | 4 - .../topics/curriculum-integration.html | 4 +- csunplugged/templates/topics/lesson.html | 7 +- .../templates/topics/lessons-table.html | 4 +- .../programming-challenge-lesson-list.html | 2 +- .../topics/programming-challenge.html | 2 +- ...ion.html => topic-whats-it-all-about.html} | 35 +- csunplugged/templates/topics/topic.html | 93 +++-- csunplugged/templates/topics/unit-plan.html | 47 --- .../plugging_it_in/views/test_index_view.py | 10 - .../test_programming_challenge_list_view.py | 12 - .../views/test_programming_challenge_view.py | 3 - .../resources/views/test_resource_view.py | 4 - .../test_rebuild_search_indexes_command.py | 9 - .../tests/search/views/test_index_view.py | 22 +- .../tests/topics/TopicsTestDataGenerator.py | 24 +- .../prerequisite-lessons-blank-lessons.yaml | 6 - .../prerequisite-lessons-invalid-lesson.yaml | 1 - ...rerequisite-lessons-invalid-unit-plan.yaml | 8 - .../prerequisite-lessons-translation.yaml | 1 - .../structure/prerequisite-lessons.yaml | 1 - .../other.md | 0 .../topic-missing-lessons.md} | 0 .../topic-missing-lessons.yaml} | 0 .../test_curriculum_integrations_loader.py | 31 +- .../topics/loaders/test_lessons_loader.py | 104 +----- .../tests/topics/loaders/test_topic_loader.py | 4 +- .../topics/loaders/test_unit_plan_loader.py | 321 ------------------ .../tests/topics/models/test_lesson.py | 12 - .../models/test_resource_description.py | 3 +- .../tests/topics/models/test_unit_plan.py | 27 -- csunplugged/tests/topics/urls/test_lesson.py | 3 +- .../urls/test_programming_challenges_list.py | 3 +- .../tests/topics/urls/test_unit_plan.py | 17 - .../topics/urls/test_unit_plan_description.py | 9 +- .../views/test_curriculum_integration_view.py | 3 - .../tests/topics/views/test_index_view.py | 10 - .../tests/topics/views/test_lesson_view.py | 86 ----- .../views/test_programming_challenge_list.py | 89 ----- .../views/test_programming_challenge_view.py | 3 - .../views/test_unit_plan_description_view.py | 43 +-- .../tests/topics/views/test_unit_plan_view.py | 201 ----------- .../unit-plan-ct-links.md => ct-links.md} | 0 ...rs-using-binary-representation-ct-links.md | 0 ...g-binary-representation-junior-ct-links.md | 0 ...entation-junior-resource-descriptions.yaml | 0 ...ters-using-binary-representation-junior.md | 0 ...-representation-resource-descriptions.yaml | 0 ...for-letters-using-binary-representation.md | 0 .../how-binary-digits-work-ct-links.md | 0 .../how-binary-digits-work-junior-ct-links.md | 0 ...its-work-junior-resource-descriptions.yaml | 0 .../lessons/how-binary-digits-work-junior.md | 0 ...ary-digits-work-resource-descriptions.yaml | 0 .../lessons/how-binary-digits-work.md | 0 ...ncing-in-binary-number-systems-ct-links.md | 0 ...n-binary-number-systems-junior-ct-links.md | 0 ...-systems-junior-resource-descriptions.yaml | 0 ...uencing-in-binary-number-systems-junior.md | 0 ...-number-systems-resource-descriptions.yaml | 0 ...ing-sequencing-in-binary-number-systems.md | 0 .../unit-plan.md => whats-it-all-about.md} | 2 - .../lessons/binary-search-trees-ct-links.md | 2 +- .../unit-plan/lessons/binary-search-trees.md | 2 +- .../unit-plan/unit-plan-ct-links.md | 2 +- .../image-representation.md | 2 +- .../unit-plan/unit-plan.md | 2 +- .../lessons/the-great-number-hunt-unsorted.md | 2 +- .../binary-numbers/binary-numbers.yaml | 24 +- .../curriculum-integrations.yaml | 6 - .../{unit-plan => }/lessons/lessons.yaml | 0 .../binary-numbers/unit-plan/unit-plan.yaml | 18 - .../curriculum-integrations.yaml | 4 - .../curriculum-integrations.yaml | 4 - .../curriculum-integrations.yaml | 3 - .../curriculum-integrations.yaml | 6 +- .../topics/content/structure/structure.yaml | 12 +- .../commands/_CurriculumIntegrationsLoader.py | 33 +- .../management/commands/_LessonsLoader.py | 5 +- .../management/commands/_TopicLoader.py | 139 ++++++-- .../management/commands/_UnitPlanLoader.py | 153 --------- .../migrations/0105_auto_20220609_0411.py | 30 ++ .../migrations/0106_auto_20220609_2330.py | 63 ++++ csunplugged/topics/models.py | 76 +---- csunplugged/topics/translation.py | 13 - csunplugged/topics/urls.py | 46 ++- csunplugged/topics/views.py | 79 +---- csunplugged/utils/LoaderFactory.py | 9 +- docs/author/topics.rst | 6 +- docs/developer/search.rst | 2 +- 95 files changed, 411 insertions(+), 1627 deletions(-) rename csunplugged/templates/topics/{unit-plan-description.html => topic-whats-it-all-about.html} (58%) delete mode 100644 csunplugged/templates/topics/unit-plan.html delete mode 100644 csunplugged/tests/topics/loaders/assets/curriculum_integrations/structure/prerequisite-lessons-blank-lessons.yaml delete mode 100644 csunplugged/tests/topics/loaders/assets/curriculum_integrations/structure/prerequisite-lessons-invalid-unit-plan.yaml rename csunplugged/tests/topics/loaders/assets/topic/en/{topic-missing-unit-plans => topic-missing-lessons}/other.md (100%) rename csunplugged/tests/topics/loaders/assets/topic/en/{topic-missing-unit-plans/topic-missing-unit-plans.md => topic-missing-lessons/topic-missing-lessons.md} (100%) rename csunplugged/tests/topics/loaders/assets/topic/structure/{topic-missing-unit-plans/topic-missing-unit-plans.yaml => topic-missing-lessons/topic-missing-lessons.yaml} (100%) delete mode 100644 csunplugged/tests/topics/loaders/test_unit_plan_loader.py delete mode 100644 csunplugged/tests/topics/models/test_unit_plan.py delete mode 100644 csunplugged/tests/topics/urls/test_unit_plan.py delete mode 100644 csunplugged/tests/topics/views/test_unit_plan_view.py rename csunplugged/topics/content/en/binary-numbers/{unit-plan/unit-plan-ct-links.md => ct-links.md} (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan => }/lessons/codes-for-letters-using-binary-representation-ct-links.md (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan => }/lessons/codes-for-letters-using-binary-representation-junior-ct-links.md (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan => }/lessons/codes-for-letters-using-binary-representation-junior-resource-descriptions.yaml (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan => }/lessons/codes-for-letters-using-binary-representation-junior.md (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan => }/lessons/codes-for-letters-using-binary-representation-resource-descriptions.yaml (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan => }/lessons/codes-for-letters-using-binary-representation.md (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan => }/lessons/how-binary-digits-work-ct-links.md (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan => }/lessons/how-binary-digits-work-junior-ct-links.md (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan => }/lessons/how-binary-digits-work-junior-resource-descriptions.yaml (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan => }/lessons/how-binary-digits-work-junior.md (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan => }/lessons/how-binary-digits-work-resource-descriptions.yaml (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan => }/lessons/how-binary-digits-work.md (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan => }/lessons/reinforcing-sequencing-in-binary-number-systems-ct-links.md (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan => }/lessons/reinforcing-sequencing-in-binary-number-systems-junior-ct-links.md (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan => }/lessons/reinforcing-sequencing-in-binary-number-systems-junior-resource-descriptions.yaml (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan => }/lessons/reinforcing-sequencing-in-binary-number-systems-junior.md (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan => }/lessons/reinforcing-sequencing-in-binary-number-systems-resource-descriptions.yaml (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan => }/lessons/reinforcing-sequencing-in-binary-number-systems.md (100%) rename csunplugged/topics/content/en/binary-numbers/{unit-plan/unit-plan.md => whats-it-all-about.md} (99%) rename csunplugged/topics/content/structure/binary-numbers/{unit-plan => }/lessons/lessons.yaml (100%) delete mode 100644 csunplugged/topics/content/structure/binary-numbers/unit-plan/unit-plan.yaml delete mode 100644 csunplugged/topics/management/commands/_UnitPlanLoader.py create mode 100644 csunplugged/topics/migrations/0105_auto_20220609_0411.py create mode 100644 csunplugged/topics/migrations/0106_auto_20220609_2330.py diff --git a/csunplugged/at_home/management/commands/_ActivityLoader.py b/csunplugged/at_home/management/commands/_ActivityLoader.py index 889c18b3d..c6beb660a 100644 --- a/csunplugged/at_home/management/commands/_ActivityLoader.py +++ b/csunplugged/at_home/management/commands/_ActivityLoader.py @@ -136,7 +136,6 @@ def load(self): else: self.log('Updated Activity: {}'.format(activity.name)) - # structure_filename = os.path.join(unit_plan_file_path) self.factory.create_challenge_loader( activity, base_path=self.base_path, diff --git a/csunplugged/search/settings.py b/csunplugged/search/settings.py index 9cbb17728..b56314980 100644 --- a/csunplugged/search/settings.py +++ b/csunplugged/search/settings.py @@ -2,7 +2,6 @@ from topics.models import ( Topic, - UnitPlan, Lesson, ProgrammingChallenge, CurriculumIntegration, @@ -61,18 +60,11 @@ def lesson_render_function(lesson): 'select_related': [], 'prefetch_related': [], }, - { - 'class': UnitPlan, - 'boost': 1.5, - 'curriculum_area_filtered': False, - 'select_related': ['topic'], - 'prefetch_related': [], - }, { 'class': Lesson, 'boost': 1.2, 'curriculum_area_filtered': True, - 'select_related': ['topic', 'unit_plan', 'unit_plan__topic'], + 'select_related': ['topic'], 'prefetch_related': ['learning_outcomes'], 'render_function': lesson_render_function, }, diff --git a/csunplugged/templates/moocs/index.html b/csunplugged/templates/moocs/index.html index 6cdd3dfc7..bf528865a 100644 --- a/csunplugged/templates/moocs/index.html +++ b/csunplugged/templates/moocs/index.html @@ -56,7 +56,7 @@

Course contents and resources

Introduction @@ -64,7 +64,7 @@

Course contents and resources

Binary basics @@ -85,7 +85,7 @@

Course contents and resources

  • - Image representation unit plan + Image representation topic
  • @@ -98,8 +98,8 @@

    Course contents and resources

  • - - Error detection and correction unit plan + + Error detection and correction topic
  • diff --git a/csunplugged/templates/plugging_it_in/programming-challenge.html b/csunplugged/templates/plugging_it_in/programming-challenge.html index 43cc31c12..9e8002fa0 100644 --- a/csunplugged/templates/plugging_it_in/programming-challenge.html +++ b/csunplugged/templates/plugging_it_in/programming-challenge.html @@ -29,7 +29,7 @@
    {{topic.name}}

    {{lesson.name}}

    - +

    {% trans "Jump to the CS Unplugged lesson" %} diff --git a/csunplugged/templates/resources/resource.html b/csunplugged/templates/resources/resource.html index 379bb10dd..0ed6f8e03 100644 --- a/csunplugged/templates/resources/resource.html +++ b/csunplugged/templates/resources/resource.html @@ -97,7 +97,7 @@

    {% trans "Related Lessons" %}

    {{ lesson.number }} -
    + {{ lesson.name }} {% if not lesson.translation_available %}
    diff --git a/csunplugged/templates/search/result/topics.lesson.html b/csunplugged/templates/search/result/topics.lesson.html index 9edb0d58d..0dc08fa80 100644 --- a/csunplugged/templates/search/result/topics.lesson.html +++ b/csunplugged/templates/search/result/topics.lesson.html @@ -20,10 +20,6 @@
    {{ result.topic.name }} - {% trans "within unit plan" %} - - {{ result.unit_plan.name }} -

    diff --git a/csunplugged/templates/topics/curriculum-integration.html b/csunplugged/templates/topics/curriculum-integration.html index b87f5275c..75e2190a3 100644 --- a/csunplugged/templates/topics/curriculum-integration.html +++ b/csunplugged/templates/topics/curriculum-integration.html @@ -47,8 +47,8 @@

    {{ integration.name }}

      {% for lesson in prerequisite_lessons %}
    • - - {{ lesson.unit_plan.name }}: {{ lesson.name }} + + {{ lesson.topic.name }}: {{ lesson.name }} ({% for age_group in lesson.age_group.all %}{{ age_group.ages.lower }} to {{ age_group.ages.upper }}{% if not forloop.last %} and {% endif %}{% endfor %}) {% if not lesson.translation_available %} diff --git a/csunplugged/templates/topics/lesson.html b/csunplugged/templates/topics/lesson.html index 73570a7c6..6ca9fd3ee 100644 --- a/csunplugged/templates/topics/lesson.html +++ b/csunplugged/templates/topics/lesson.html @@ -12,14 +12,13 @@ {% block breadcrumbs %} {% breadcrumb "Topics" "topics:index" %} {% breadcrumb topic.name "topics:topic" topic.slug %} - {% breadcrumb unit_plan.name "topics:unit_plan" topic.slug unit_plan.slug %} - {% breadcrumb lesson.name "topics:lesson" topic.slug unit_plan.slug lesson.slug %} + {% breadcrumb lesson.name "topics:lesson" topic.slug lesson.slug %} {% endblock breadcrumbs %} {% block page_heading %}

      {{ lesson.name }}

      {% if not lesson.translation_available %} - {% with model=lesson parent=unit_plan %} + {% with model=lesson parent=topic %} {% include "topics/not-available-warning.html" %} {% endwith %} {% else %} @@ -100,7 +99,7 @@

      {% trans "Classroom resources" %}

      {% trans "Programming challenges" %}

      - + {% trans "View related programming challenges" %}

      diff --git a/csunplugged/templates/topics/lessons-table.html b/csunplugged/templates/topics/lessons-table.html index 1da6420b8..f225d1ead 100644 --- a/csunplugged/templates/topics/lessons-table.html +++ b/csunplugged/templates/topics/lessons-table.html @@ -28,7 +28,7 @@ {{ lesson.number }} - + {{ lesson.name }} {% if not lesson.translation_available %}
      @@ -38,7 +38,7 @@ {% if lesson.has_programming_challenges %} -
      + {% trans "Yes" %} {% else %} diff --git a/csunplugged/templates/topics/programming-challenge-lesson-list.html b/csunplugged/templates/topics/programming-challenge-lesson-list.html index 02b21f11f..f86f52393 100644 --- a/csunplugged/templates/topics/programming-challenge-lesson-list.html +++ b/csunplugged/templates/topics/programming-challenge-lesson-list.html @@ -12,7 +12,7 @@ {% block breadcrumbs %} {% breadcrumb "Topics" "topics:index" %} {% breadcrumb topic.name "topics:topic" topic.slug %} - {% breadcrumb "Programming Challenges" "topics:programming_challenges_list" topic.slug unit_plan.slug lesson.slug %} + {% breadcrumb "Programming Challenges" "topics:programming_challenges_list" topic.slug lesson.slug %} {% endblock breadcrumbs %} {% block page_heading %} diff --git a/csunplugged/templates/topics/programming-challenge.html b/csunplugged/templates/topics/programming-challenge.html index 21d82638a..b3f408cb8 100644 --- a/csunplugged/templates/topics/programming-challenge.html +++ b/csunplugged/templates/topics/programming-challenge.html @@ -40,7 +40,7 @@

        {% for lesson in lessons %}
      • - + {% blocktrans with set_num=lesson.challenge_set_number chal_num=lesson.challenge_number name=lesson.name trimmed %} Challenge {{ set_num }}.{{ chal_num }} for {{ name }} {% endblocktrans %} diff --git a/csunplugged/templates/topics/unit-plan-description.html b/csunplugged/templates/topics/topic-whats-it-all-about.html similarity index 58% rename from csunplugged/templates/topics/unit-plan-description.html rename to csunplugged/templates/topics/topic-whats-it-all-about.html index 583f933ba..510761f03 100644 --- a/csunplugged/templates/topics/unit-plan-description.html +++ b/csunplugged/templates/topics/topic-whats-it-all-about.html @@ -5,49 +5,60 @@ {% load django_bootstrap_breadcrumbs %} {% block title %} - {{ unit_plan.name }} - {% trans "Description" %} + {{ topic.name }} - {% trans "What's it all about" %} {% endblock title %} {% block breadcrumbs %} {% breadcrumb "Topics" "topics:index" %} {% breadcrumb topic.name "topics:topic" topic.slug %} - {% breadcrumb unit_plan.name "topics:unit_plan" topic.slug unit_plan.slug %} - {% breadcrumb "Description" "topics:unit_plan_description" topic.slug unit_plan.slug %} + {% breadcrumb "What's it all about" "topics:topic_whats_it_all_about" topic.slug %} {% endblock breadcrumbs %} {% block page_heading %} -

        {% trans "Unit plan:" %} {{ unit_plan.name }}

        +

        + {{ topic.name }} +
        + + {% trans "What's it all about?"%} + +

        {% if not topic.translation_available %} - {% with model=unit_plan parent=topic %} + {% with model=topic %} {% include 'topics/not-available-warning.html' %} {% endwith %} {% endif %} {% endblock page_heading %} {% block left_column_content %} - {% if unit_plan.translation_available %} - {% render_html_field unit_plan.content %} + {% if topic.translation_available %} + {% render_html_field topic.whats_it_all_about %} - {% with computational_thinking_links=unit_plan.computational_thinking_links %} + {% with computational_thinking_links=topic.computational_thinking_links %} {% include "topics/computational-thinking-links.html" %} {% endwith %} {% endif %} + +

        + + {% trans "Go back to the topic homepage" %} + +

        {% endblock left_column_content %} {% block right_column_content %} - {% if unit_plan.translation_available %} + {% if topic.translation_available %} {% endblock navbar %} + +{% block scripts %} + +{% endblock scripts %} diff --git a/csunplugged/templates/at_a_distance/components/reveal-initialize.html b/csunplugged/templates/at_a_distance/components/reveal-initialize.html new file mode 100644 index 000000000..a8792c695 --- /dev/null +++ b/csunplugged/templates/at_a_distance/components/reveal-initialize.html @@ -0,0 +1,26 @@ + diff --git a/csunplugged/templates/at_a_distance/lesson-slides.html b/csunplugged/templates/at_a_distance/lesson-slides.html new file mode 100644 index 000000000..df2282956 --- /dev/null +++ b/csunplugged/templates/at_a_distance/lesson-slides.html @@ -0,0 +1,37 @@ +{% extends "at_a_distance/base.html" %} + +{% load i18n %} +{% load static %} +{% load render_html_field %} +{% load django_bootstrap_breadcrumbs %} + +{% block title %} + {{ lesson.name }} +{% endblock title %} + +{% block breadcrumbs %} + {% breadcrumb lesson.name "at_a_distance:lesson" lesson.slug %} +{% endblock breadcrumbs %} + +{% block extra_body_classes %}no-padding{% endblock extra_body_classes %} + +{% block body %} +
        +
        +
        +
        +

        CS Unplugged - At a Distance

        +

        {{ lesson.name }}

        +
        + + {% include lesson.get_slides_path %} +
        +
        +
        + +{% block scripts %} + {{ block.super }} + {% include "at_a_distance/components/reveal-initialize.html" with embedded="false" speaker_mode=True show_notes="false" %} +{% endblock scripts %} + +{% endblock body %} diff --git a/csunplugged/templates/at_a_distance/lesson-slides/en/stroop-effect.html b/csunplugged/templates/at_a_distance/lesson-slides/en/stroop-effect.html index 42e29faa2..48405b8af 100644 --- a/csunplugged/templates/at_a_distance/lesson-slides/en/stroop-effect.html +++ b/csunplugged/templates/at_a_distance/lesson-slides/en/stroop-effect.html @@ -9,6 +9,22 @@

        Key questions

        Do software designers use psychology concepts when designing their applications?
      + +
      diff --git a/csunplugged/templates/at_a_distance/lesson.html b/csunplugged/templates/at_a_distance/lesson.html index 28d90fe77..7b701a55f 100644 --- a/csunplugged/templates/at_a_distance/lesson.html +++ b/csunplugged/templates/at_a_distance/lesson.html @@ -26,7 +26,13 @@

      {{ lesson.name }}

      {% if lesson.translation_available %} {% render_html_field lesson.introduction %} -

      Slides

      +

      + + Open slides in presentation mode + +

      + +

      Slides with notes

      How to use the slideshow

        @@ -50,7 +56,6 @@

        {{ lesson.name }}

        {% endblock content %} {% block scripts %} - {% if lesson.translation_available %} - - {% endif %} + {{ block.super }} + {% include "at_a_distance/components/reveal-initialize.html" with embedded="true" speaker_mode=False show_notes="true" %} {% endblock scripts %} diff --git a/csunplugged/templates/at_home/index.html b/csunplugged/templates/at_home/index.html index 42383190d..4638620df 100644 --- a/csunplugged/templates/at_home/index.html +++ b/csunplugged/templates/at_home/index.html @@ -8,7 +8,7 @@ {% trans "CS Unplugged at home" %} {% endblock custom_title %} -{% block body_attribute_overrides %} class="homepage"{% endblock body_attribute_overrides %} +{% block extra_body_classes %}no-padding{% endblock extra_body_classes %} {% block navbar_class_overrides %} trans-navbar{% endblock navbar_class_overrides %} {% block body_container %} diff --git a/csunplugged/templates/core.html b/csunplugged/templates/core.html index 2ce007188..36535fd52 100644 --- a/csunplugged/templates/core.html +++ b/csunplugged/templates/core.html @@ -44,7 +44,9 @@ - + + {% block body %} + {% block navbar %} {% endblock navbar %} @@ -271,6 +273,8 @@ {% block scripts %} {% endblock scripts %} + {% endblock body %} + {% if DEPLOYED %} diff --git a/csunplugged/templates/at_a_distance/components/speech-bubble-close.html b/csunplugged/templates/at_a_distance/components/speech-bubble-close.html new file mode 100644 index 000000000..e3cd35bb6 --- /dev/null +++ b/csunplugged/templates/at_a_distance/components/speech-bubble-close.html @@ -0,0 +1,3 @@ + +
        +
      diff --git a/csunplugged/templates/at_a_distance/components/speech-bubble-open.html b/csunplugged/templates/at_a_distance/components/speech-bubble-open.html new file mode 100644 index 000000000..22862c867 --- /dev/null +++ b/csunplugged/templates/at_a_distance/components/speech-bubble-open.html @@ -0,0 +1,2 @@ +
      +
      diff --git a/csunplugged/templates/at_a_distance/lesson-slides/en/stroop-effect.html b/csunplugged/templates/at_a_distance/lesson-slides/en/stroop-effect.html index 48405b8af..80541dbcb 100644 --- a/csunplugged/templates/at_a_distance/lesson-slides/en/stroop-effect.html +++ b/csunplugged/templates/at_a_distance/lesson-slides/en/stroop-effect.html @@ -11,43 +11,290 @@

      Key questions

    -

    RED

    +

    RED

    + +
    -

    GREEN

    +

    GREEN

    -

    BLUE

    +

    BLUE

    -

    BLACK

    +

    BLACK

    -

    RED

    +

    RED

    -

    PURPLE

    +

    PURPLE

    + + +
    + +
    +

    Instructions for timing exercises

    + +
    + +
    +

    Incongruent

    +
    +
    +
    Blue
    +
    Green
    +
    Red
    +
    Purple
    +
    Black
    +
    Yellow
    +
    Purple
    +
    Green
    +
    Blue
    +
    +
    +
    +
    +
    + + +
    + +
    +

    Congruent

    +
    +
    +
    Red
    +
    Purple
    +
    Green
    +
    Red
    +
    Black
    +
    Yellow
    +
    Purple
    +
    Green
    +
    Blue
    +
    +
    +
    +
    +
    + + +
    + +
    +

    Results

    +
    +
    +

    Incongruent

    +
    Blue
    +
    Green
    +
    Red
    +
    Purple
    +
    Black
    +
    Yellow
    +
    Purple
    +
    Green
    +
    Blue
    +
    +
    +

    Congruent

    +
    Red
    +
    Purple
    +
    Green
    +
    Red
    +
    Black
    +
    Yellow
    +
    Purple
    +
    Green
    +
    Blue
    +
    +
    + +
    + + From 508e1286b75b1600927544fe6ecb7bc0e8d3af4d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jun 2022 02:11:06 +0000 Subject: [PATCH 042/195] Bump cssnano from 5.0.15 to 5.1.12 in /csunplugged Bumps [cssnano](https://github.com/cssnano/cssnano) from 5.0.15 to 5.1.12. - [Release notes](https://github.com/cssnano/cssnano/releases) - [Commits](https://github.com/cssnano/cssnano/compare/cssnano@5.0.15...cssnano@5.1.12) --- updated-dependencies: - dependency-name: cssnano dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- csunplugged/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csunplugged/package.json b/csunplugged/package.json index 539615437..8bd890501 100644 --- a/csunplugged/package.json +++ b/csunplugged/package.json @@ -11,7 +11,7 @@ "browserify": "17.0.0", "child_process": "1.0.2", "codemirror": "5.65.1", - "cssnano": "5.0.15", + "cssnano": "5.1.12", "blockly": "7.20211209.2", "details-element-polyfill": "2.4.0", "fancy-log": "2.0.0", From 8a19c3d4e40c39d270caf0cc4915b859d577aaeb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Jun 2022 02:17:19 +0000 Subject: [PATCH 043/195] Bump codemirror from 5.65.1 to 5.65.6 in /csunplugged Bumps [codemirror](https://github.com/codemirror/CodeMirror) from 5.65.1 to 5.65.6. - [Release notes](https://github.com/codemirror/CodeMirror/releases) - [Changelog](https://github.com/codemirror/codemirror5/blob/5.65.6/CHANGELOG.md) - [Commits](https://github.com/codemirror/CodeMirror/compare/5.65.1...5.65.6) --- updated-dependencies: - dependency-name: codemirror dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- csunplugged/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csunplugged/package.json b/csunplugged/package.json index 8bd890501..3e25d814a 100644 --- a/csunplugged/package.json +++ b/csunplugged/package.json @@ -10,7 +10,7 @@ "browser-sync": "2.27.10", "browserify": "17.0.0", "child_process": "1.0.2", - "codemirror": "5.65.1", + "codemirror": "5.65.6", "cssnano": "5.1.12", "blockly": "7.20211209.2", "details-element-polyfill": "2.4.0", From e881f681ca7c55a5efddb8b93c1193c913644609 Mon Sep 17 00:00:00 2001 From: JackMorganNZ Date: Wed, 22 Jun 2022 14:26:16 +1200 Subject: [PATCH 044/195] Add footer and remove repetitive code --- csunplugged/static/scss/_core-variables.scss | 2 +- .../scss/at-a-distance-slide-theme.scss | 10 ++ csunplugged/static/scss/at-a-distance.scss | 4 +- .../components/reveal-initialize.html | 3 + .../components/reveal-slides-structure.html | 19 +++ .../at_a_distance/lesson-slides.html | 21 +-- .../lesson-slides/en/stroop-effect.html | 159 ++++++++++++++++-- .../templates/at_a_distance/lesson.html | 14 +- 8 files changed, 189 insertions(+), 43 deletions(-) create mode 100644 csunplugged/templates/at_a_distance/components/reveal-slides-structure.html diff --git a/csunplugged/static/scss/_core-variables.scss b/csunplugged/static/scss/_core-variables.scss index 420e40c15..69c77d3b0 100644 --- a/csunplugged/static/scss/_core-variables.scss +++ b/csunplugged/static/scss/_core-variables.scss @@ -10,7 +10,7 @@ $ct-pattern: #82358C; $educator-colour: #cc0423; $at-home-colour: #00554E; $plugging-it-in-colour: #3044b3; -$at-a-distance-colour: #45a9f5; +$at-a-distance-colour: $educator-colour; $font-family-sans-serif: "Noto Sans", sans-serif; $headings-font-family: "Sniglet", cursive; diff --git a/csunplugged/static/scss/at-a-distance-slide-theme.scss b/csunplugged/static/scss/at-a-distance-slide-theme.scss index 916919971..7dfac14ce 100644 --- a/csunplugged/static/scss/at-a-distance-slide-theme.scss +++ b/csunplugged/static/scss/at-a-distance-slide-theme.scss @@ -167,4 +167,14 @@ $speech-bubble-background: mix(#fff, $at-a-distance-colour, 95%); } } +// Footer +.reveal > .footer { + position: absolute; + bottom: 0; + padding: 1rem; + font-size: 1.5rem; + color: $at-a-distance-colour; + width: 100%; +} + @import "node_modules/reveal.js/css/theme/template/theme"; diff --git a/csunplugged/static/scss/at-a-distance.scss b/csunplugged/static/scss/at-a-distance.scss index 0f2c9f4ea..747eed398 100644 --- a/csunplugged/static/scss/at-a-distance.scss +++ b/csunplugged/static/scss/at-a-distance.scss @@ -3,11 +3,11 @@ @import "at-a-distance-slide-theme"; #at-a-distance-jumbotron { - background-color: lighten($at-a-distance-colour, 25%); + background-color: rgba($at-a-distance-colour, 15%); } .navbar.navbar-at-a-distance { - background-color: darken($at-a-distance-colour, 25%); + background-color: $at-a-distance-colour; } #slides.embed-responsive { diff --git a/csunplugged/templates/at_a_distance/components/reveal-initialize.html b/csunplugged/templates/at_a_distance/components/reveal-initialize.html index 89a4ee575..090089d55 100644 --- a/csunplugged/templates/at_a_distance/components/reveal-initialize.html +++ b/csunplugged/templates/at_a_distance/components/reveal-initialize.html @@ -3,6 +3,9 @@ embedded: {{ embedded }}, showNotes: {{ show_notes }}, overview: false, + controlsTutorial: false, + disableLayout: false, + center: false, transition: 'slide', plugins: [ diff --git a/csunplugged/templates/at_a_distance/components/reveal-slides-structure.html b/csunplugged/templates/at_a_distance/components/reveal-slides-structure.html new file mode 100644 index 000000000..42c26eefe --- /dev/null +++ b/csunplugged/templates/at_a_distance/components/reveal-slides-structure.html @@ -0,0 +1,19 @@ +{% load static %} + +
    +
    +
    +
    +

    CS Unplugged - At a Distance

    +

    {{ lesson.name }}

    +
    + + {% include lesson.get_slides_path %} +
    + + +
    +
    diff --git a/csunplugged/templates/at_a_distance/lesson-slides.html b/csunplugged/templates/at_a_distance/lesson-slides.html index df2282956..b217661bb 100644 --- a/csunplugged/templates/at_a_distance/lesson-slides.html +++ b/csunplugged/templates/at_a_distance/lesson-slides.html @@ -16,22 +16,11 @@ {% block extra_body_classes %}no-padding{% endblock extra_body_classes %} {% block body %} -
    -
    -
    -
    -

    CS Unplugged - At a Distance

    -

    {{ lesson.name }}

    -
    + {% include "at_a_distance/components/reveal-slides-structure.html" %} - {% include lesson.get_slides_path %} -
    -
    -
    - -{% block scripts %} - {{ block.super }} - {% include "at_a_distance/components/reveal-initialize.html" with embedded="false" speaker_mode=True show_notes="false" %} -{% endblock scripts %} + {% block scripts %} + {{ block.super }} + {% include "at_a_distance/components/reveal-initialize.html" with embedded="false" speaker_mode=True show_notes="false" %} + {% endblock scripts %} {% endblock body %} diff --git a/csunplugged/templates/at_a_distance/lesson-slides/en/stroop-effect.html b/csunplugged/templates/at_a_distance/lesson-slides/en/stroop-effect.html index 80541dbcb..a6fa858fd 100644 --- a/csunplugged/templates/at_a_distance/lesson-slides/en/stroop-effect.html +++ b/csunplugged/templates/at_a_distance/lesson-slides/en/stroop-effect.html @@ -1,6 +1,6 @@
    -

    Key questions

    +

    Key questions

    • Have you ever used an application and had to think carefully about what to click? @@ -33,7 +33,7 @@

      Key questions

    -

    RED

    +

    RED

    -

    GREEN

    +

    GREEN

    -

    BLUE

    +

    BLUE

    -

    BLACK

    +

    BLACK

    -

    RED

    +

    RED

    -

    PURPLE

    +

    PURPLE

    -

    Instructions for timing exercises

    +

    Instructions for timing exercises

    -

    Incongruent

    +

    Incongruent

    Blue
    @@ -152,7 +152,7 @@

    Incongruent

    -

    Congruent

    +

    Congruent

    Red
    @@ -189,8 +189,8 @@

    Congruent

    -
    -

    Results

    +
    +

    Results

    Incongruent

    @@ -242,6 +242,141 @@

    Congruent

    {% include "at_a_distance/components/speech-bubble-close.html" %}
    + +
    +

    HCI in action

    + {% comment %} Image for airline interface {% endcomment %} + + +
    + +
    +

    HCI in action

    + {% comment %} Image for quit prompt {% endcomment %} + + +
    + +
    +

    HCI in action

    + {% comment %} Image of date prompt {% endcomment %} + + +
    + +
    +

    HCI: Answering our key question

    +

    Do software designers use psychology concepts when designing their applications?

    + + +
    + +
    +

    Stroop effect - Supporting resources

    + + + + +
    +
    + + diff --git a/third-party-licences/revealjs.txt b/third-party-licences/revealjs.txt new file mode 100644 index 000000000..f82a0cc76 --- /dev/null +++ b/third-party-licences/revealjs.txt @@ -0,0 +1,19 @@ +Copyright (C) 2011-2022 Hakim El Hattab, http://hakim.se, and reveal.js contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. From 3dcaafcb997d8cbd0f3af3b54e784b6c3f82afcc Mon Sep 17 00:00:00 2001 From: JackMorganNZ Date: Fri, 24 Jun 2022 10:33:34 +1200 Subject: [PATCH 054/195] Update bootstrap --- csunplugged/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csunplugged/package.json b/csunplugged/package.json index 3433e07b6..886dfed5a 100644 --- a/csunplugged/package.json +++ b/csunplugged/package.json @@ -6,7 +6,7 @@ "devDependencies": { "ansi-colors": "4.1.3", "autoprefixer": "10.4.7", - "bootstrap": "4.6.0", + "bootstrap": "4.6.1", "browser-sync": "2.27.10", "browserify": "17.0.0", "child_process": "1.0.2", From ccf1265cfeac966c7d2593773cf760f997cdf63c Mon Sep 17 00:00:00 2001 From: JackMorganNZ Date: Fri, 24 Jun 2022 10:33:54 +1200 Subject: [PATCH 055/195] Show speech bubbles on speaker notes window --- .../reveal-plugin.js | 2 +- .../speaker-notes-window.js | 2 +- csunplugged/static/scss/at-a-distance.scss | 3 +- .../_slide-theme.scss} | 56 ------------------- .../scss/at-a-distance/_speaker-notes.scss | 55 ++++++++++++++++++ .../speaker-notes-window.scss | 3 +- .../speaker-notes-window.html | 2 +- 7 files changed, 62 insertions(+), 61 deletions(-) rename csunplugged/static/scss/{_at-a-distance-slide-theme.scss => at-a-distance/_slide-theme.scss} (71%) create mode 100644 csunplugged/static/scss/at-a-distance/_speaker-notes.scss diff --git a/csunplugged/static/js/reveal-speaker-notes-plugin/reveal-plugin.js b/csunplugged/static/js/reveal-speaker-notes-plugin/reveal-plugin.js index 002f3893c..cd4dc5fff 100644 --- a/csunplugged/static/js/reveal-speaker-notes-plugin/reveal-plugin.js +++ b/csunplugged/static/js/reveal-speaker-notes-plugin/reveal-plugin.js @@ -44,7 +44,7 @@ const Plugin = () => { speakerWindow.focus(); } else { - speakerWindow = window.open('/at-a-distance/speaker-notes/', 'Speaker Notes', 'width=1000,height=1000'); + speakerWindow = window.open('/at-a-distance/speaker-notes/', 'Speaker Notes', 'width=1200,height=800'); if (!speakerWindow) { alert('Speaker view popup failed to open. Please make sure popups are allowed and reopen the speaker view.'); diff --git a/csunplugged/static/js/reveal-speaker-notes-plugin/speaker-notes-window.js b/csunplugged/static/js/reveal-speaker-notes-plugin/speaker-notes-window.js index 1fc00ba0e..51d0555f9 100644 --- a/csunplugged/static/js/reveal-speaker-notes-plugin/speaker-notes-window.js +++ b/csunplugged/static/js/reveal-speaker-notes-plugin/speaker-notes-window.js @@ -32,7 +32,7 @@ // In order to prevent XSS, the speaker view will only run if its // opener has the same origin as itself if (window.location.origin !== openerOrigin) { - connectionStatus.innerHTML = 'Cross origin error.
    The speaker window can only be opened from the same origin.'; + connectionStatus.innerHTML = 'Error: The speaker notes window can only be opened from the same origin and by a slide deck.'; return; } diff --git a/csunplugged/static/scss/at-a-distance.scss b/csunplugged/static/scss/at-a-distance.scss index 747eed398..a7dff8131 100644 --- a/csunplugged/static/scss/at-a-distance.scss +++ b/csunplugged/static/scss/at-a-distance.scss @@ -1,6 +1,7 @@ @import "core-variables"; @import "node_modules/reveal.js/dist/reveal"; -@import "at-a-distance-slide-theme"; +@import "at-a-distance/slide-theme"; +@import "at-a-distance/speaker-notes"; #at-a-distance-jumbotron { background-color: rgba($at-a-distance-colour, 15%); diff --git a/csunplugged/static/scss/_at-a-distance-slide-theme.scss b/csunplugged/static/scss/at-a-distance/_slide-theme.scss similarity index 71% rename from csunplugged/static/scss/_at-a-distance-slide-theme.scss rename to csunplugged/static/scss/at-a-distance/_slide-theme.scss index 1ead9a8b5..3fadfac70 100644 --- a/csunplugged/static/scss/_at-a-distance-slide-theme.scss +++ b/csunplugged/static/scss/at-a-distance/_slide-theme.scss @@ -137,62 +137,6 @@ $footer-height: 3rem; } } -// Speaker notes - -$speech-bubble-background: mix(#fff, $at-a-distance-colour, 95%); - -.reveal .speaker-notes { - - font-family: $font-family-sans-serif; - - p { - line-height: inherit; - } - - .speech-bubble { - background: $speech-bubble-background; - border: 1px solid $at-a-distance-colour; - border-radius: 1rem; - margin: 0 0 1.5em 0; - padding: 0.5em; - position: relative; - - blockquote { - // Overrides for reveal theme defaults - margin: 0; - padding: 0; - box-shadow: none; - background: none; - width: auto; - } - - .speech-bubble-arrow { - border-left: 21px solid transparent; - bottom: -25px; - position: absolute; - right: 15px; - - &::before { - border-left: 23px solid transparent; - border-top: 23px solid $at-a-distance-colour; - bottom: 2px; - content: ""; - position: absolute; - right: 5px; - } - - &::after { - border-left: 21px solid transparent; - border-top: 21px solid $speech-bubble-background; - bottom: 4px; - content: ""; - position: absolute; - right: 6px; - } - } - } -} - // Footer .reveal > .footer { position: absolute; diff --git a/csunplugged/static/scss/at-a-distance/_speaker-notes.scss b/csunplugged/static/scss/at-a-distance/_speaker-notes.scss new file mode 100644 index 000000000..09dae4d91 --- /dev/null +++ b/csunplugged/static/scss/at-a-distance/_speaker-notes.scss @@ -0,0 +1,55 @@ +@import "../core-variables"; + +$speech-bubble-background: mix(#fff, $at-a-distance-colour, 95%); + +.speaker-notes { + + font-family: $font-family-sans-serif; + + p { + line-height: inherit; + } + + .speech-bubble { + background: $speech-bubble-background; + border: 1px solid $at-a-distance-colour; + border-radius: 1rem; + margin: 0 0 1.5em 0; + padding: 0.5em; + position: relative; + + blockquote { + // Overrides for reveal theme defaults + margin: 0; + padding: 0; + box-shadow: none; + background: none; + width: auto; + } + + .speech-bubble-arrow { + border-left: 21px solid transparent; + bottom: -25px; + position: absolute; + right: 15px; + + &::before { + border-left: 23px solid transparent; + border-top: 23px solid $at-a-distance-colour; + bottom: 2px; + content: ""; + position: absolute; + right: 5px; + } + + &::after { + border-left: 21px solid transparent; + border-top: 21px solid $speech-bubble-background; + bottom: 4px; + content: ""; + position: absolute; + right: 6px; + } + } + } +} diff --git a/csunplugged/static/scss/reveal-speaker-notes-plugin/speaker-notes-window.scss b/csunplugged/static/scss/reveal-speaker-notes-plugin/speaker-notes-window.scss index 0811b5e0b..8b04dfa68 100644 --- a/csunplugged/static/scss/reveal-speaker-notes-plugin/speaker-notes-window.scss +++ b/csunplugged/static/scss/reveal-speaker-notes-plugin/speaker-notes-window.scss @@ -1,5 +1,6 @@ +@import "../at-a-distance/speaker-notes"; + body { - font-family: Helvetica; font-size: 18px; } diff --git a/csunplugged/templates/at_a_distance/reveal-speaker-notes-plugin/speaker-notes-window.html b/csunplugged/templates/at_a_distance/reveal-speaker-notes-plugin/speaker-notes-window.html index 36a0ee404..f8860dee5 100644 --- a/csunplugged/templates/at_a_distance/reveal-speaker-notes-plugin/speaker-notes-window.html +++ b/csunplugged/templates/at_a_distance/reveal-speaker-notes-plugin/speaker-notes-window.html @@ -31,7 +31,7 @@