From 5c37aee79c04d9199dc47b9d60f9899a0f6571d9 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Wed, 19 May 2021 09:02:21 +0200 Subject: Dramatically simplify resources. We don't need _category_info, we don't need subcategories, we this will be much simpler now. Also, rglob is nice. --- pydis_site/apps/resources/tests/test_views.py | 13 +++++-------- .../tests/testing_resources/testing/_category_info.yaml | 1 - .../testing_resources/testing/foobar/_category_info.yaml | 1 - 3 files changed, 5 insertions(+), 10 deletions(-) delete mode 100644 pydis_site/apps/resources/tests/testing_resources/testing/_category_info.yaml delete mode 100644 pydis_site/apps/resources/tests/testing_resources/testing/foobar/_category_info.yaml (limited to 'pydis_site/apps/resources/tests') diff --git a/pydis_site/apps/resources/tests/test_views.py b/pydis_site/apps/resources/tests/test_views.py index 53685eef..568f4d13 100644 --- a/pydis_site/apps/resources/tests/test_views.py +++ b/pydis_site/apps/resources/tests/test_views.py @@ -19,16 +19,13 @@ class TestResourcesView(TestCase): class TestResourcesListView(TestCase): - @patch("pydis_site.apps.resources.views.resources_list.RESOURCES_PATH", TESTING_RESOURCES_PATH) def test_valid_resource_list_200(self): """Check does site return code 200 when visiting valid resource list.""" - url = reverse("resources:resources", ("testing",)) + url = reverse("resources:resources") response = self.client.get(url) self.assertEqual(response.status_code, 200) - @patch("pydis_site.apps.resources.views.resources_list.RESOURCES_PATH", TESTING_RESOURCES_PATH) - def test_invalid_resource_list_404(self): - """Check does site return code 404 when trying to visit invalid resource list.""" - url = reverse("resources:resources", ("invalid",)) - response = self.client.get(url) - self.assertEqual(response.status_code, 404) + @patch("pydis_site.apps.resources.utils.RESOURCES_PATH", TESTING_RESOURCES_PATH) + def test_filter_resource_list(self): + """TODO: Check that we can correctly filter resources with GET parameters.""" + pass diff --git a/pydis_site/apps/resources/tests/testing_resources/testing/_category_info.yaml b/pydis_site/apps/resources/tests/testing_resources/testing/_category_info.yaml deleted file mode 100644 index bae17ea3..00000000 --- a/pydis_site/apps/resources/tests/testing_resources/testing/_category_info.yaml +++ /dev/null @@ -1 +0,0 @@ -name: Testing diff --git a/pydis_site/apps/resources/tests/testing_resources/testing/foobar/_category_info.yaml b/pydis_site/apps/resources/tests/testing_resources/testing/foobar/_category_info.yaml deleted file mode 100644 index eaac32d9..00000000 --- a/pydis_site/apps/resources/tests/testing_resources/testing/foobar/_category_info.yaml +++ /dev/null @@ -1 +0,0 @@ -name: Foobar -- cgit v1.2.3 From 7c67ea311eebeb5273d02469295fa4218348e213 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Sun, 23 May 2021 10:51:55 +0200 Subject: Test boilerplate --- pydis_site/apps/resources/tests/test_resources.py | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 pydis_site/apps/resources/tests/test_resources.py (limited to 'pydis_site/apps/resources/tests') diff --git a/pydis_site/apps/resources/tests/test_resources.py b/pydis_site/apps/resources/tests/test_resources.py new file mode 100644 index 00000000..81638e2f --- /dev/null +++ b/pydis_site/apps/resources/tests/test_resources.py @@ -0,0 +1,9 @@ +from django.test import TestCase + + +class TestResources(TestCase): + """Test our resource filtering systems.""" + + def test_utils_to_retrieve_tags(self): + """Test that the utils that retrieve the tags work as intended.""" + pass -- cgit v1.2.3 From d89c65a8fdd0ca6c997f186bd7b5af581c23be2f Mon Sep 17 00:00:00 2001 From: swfarnsworth Date: Fri, 3 Sep 2021 16:48:35 -0400 Subject: Rename `utils.py` to `resource_search.py`. --- pydis_site/apps/resources/resource_search.py | 57 +++++++++++++++++++++++ pydis_site/apps/resources/tests/test_views.py | 2 +- pydis_site/apps/resources/utils.py | 57 ----------------------- pydis_site/apps/resources/views/resources.py | 2 +- pydis_site/apps/resources/views/resources_list.py | 2 +- 5 files changed, 60 insertions(+), 60 deletions(-) create mode 100644 pydis_site/apps/resources/resource_search.py delete mode 100644 pydis_site/apps/resources/utils.py (limited to 'pydis_site/apps/resources/tests') diff --git a/pydis_site/apps/resources/resource_search.py b/pydis_site/apps/resources/resource_search.py new file mode 100644 index 00000000..8454451a --- /dev/null +++ b/pydis_site/apps/resources/resource_search.py @@ -0,0 +1,57 @@ +import typing as t +from collections import defaultdict +from functools import reduce +from operator import and_, or_ +from pathlib import Path +from types import MappingProxyType + +import yaml +from django.conf import settings + + +def _transform_name(resource_name: str) -> str: + return resource_name.title().replace('And', 'and', -1) + + +Resource = dict[str, t.Union[str, list[dict[str, str]], dict[str, list[str]]]] + +RESOURCES_PATH = Path(settings.BASE_DIR, "pydis_site", "apps", "resources", "resources") + +RESOURCES: MappingProxyType[str, Resource] = MappingProxyType({ + path.stem: yaml.safe_load(path.read_text()) + for path in RESOURCES_PATH.rglob("*.yaml") +}) + +_resource_table = {category: defaultdict(set) for category in ( + "topics", + "payment_tiers", + "complexity", + "type" +)} + +for name, resource in RESOURCES.items(): + for category, tags in resource['tags'].items(): + for tag in tags: + _resource_table[category][_transform_name(tag)].add(name) + +# Freeze the resources table +RESOURCE_TABLE = MappingProxyType({ + category: MappingProxyType(d) + for category, d in _resource_table.items() +}) + + +def get_resources_from_search(search_categories: dict[str, set[str]]) -> list[Resource]: + """Returns a list of all resources that match the given search terms.""" + resource_names_that_match = reduce( + and_, + ( + reduce( + or_, + (RESOURCE_TABLE[category][label] for label in labels), + set() + ) + for category, labels in search_categories.items() + ) + ) + return [RESOURCES[name_] for name_ in resource_names_that_match] diff --git a/pydis_site/apps/resources/tests/test_views.py b/pydis_site/apps/resources/tests/test_views.py index 568f4d13..2e9efc1d 100644 --- a/pydis_site/apps/resources/tests/test_views.py +++ b/pydis_site/apps/resources/tests/test_views.py @@ -25,7 +25,7 @@ class TestResourcesListView(TestCase): response = self.client.get(url) self.assertEqual(response.status_code, 200) - @patch("pydis_site.apps.resources.utils.RESOURCES_PATH", TESTING_RESOURCES_PATH) + @patch("pydis_site.apps.resources.resource_search.RESOURCES_PATH", TESTING_RESOURCES_PATH) def test_filter_resource_list(self): """TODO: Check that we can correctly filter resources with GET parameters.""" pass diff --git a/pydis_site/apps/resources/utils.py b/pydis_site/apps/resources/utils.py deleted file mode 100644 index 8454451a..00000000 --- a/pydis_site/apps/resources/utils.py +++ /dev/null @@ -1,57 +0,0 @@ -import typing as t -from collections import defaultdict -from functools import reduce -from operator import and_, or_ -from pathlib import Path -from types import MappingProxyType - -import yaml -from django.conf import settings - - -def _transform_name(resource_name: str) -> str: - return resource_name.title().replace('And', 'and', -1) - - -Resource = dict[str, t.Union[str, list[dict[str, str]], dict[str, list[str]]]] - -RESOURCES_PATH = Path(settings.BASE_DIR, "pydis_site", "apps", "resources", "resources") - -RESOURCES: MappingProxyType[str, Resource] = MappingProxyType({ - path.stem: yaml.safe_load(path.read_text()) - for path in RESOURCES_PATH.rglob("*.yaml") -}) - -_resource_table = {category: defaultdict(set) for category in ( - "topics", - "payment_tiers", - "complexity", - "type" -)} - -for name, resource in RESOURCES.items(): - for category, tags in resource['tags'].items(): - for tag in tags: - _resource_table[category][_transform_name(tag)].add(name) - -# Freeze the resources table -RESOURCE_TABLE = MappingProxyType({ - category: MappingProxyType(d) - for category, d in _resource_table.items() -}) - - -def get_resources_from_search(search_categories: dict[str, set[str]]) -> list[Resource]: - """Returns a list of all resources that match the given search terms.""" - resource_names_that_match = reduce( - and_, - ( - reduce( - or_, - (RESOURCE_TABLE[category][label] for label in labels), - set() - ) - for category, labels in search_categories.items() - ) - ) - return [RESOURCES[name_] for name_ in resource_names_that_match] diff --git a/pydis_site/apps/resources/views/resources.py b/pydis_site/apps/resources/views/resources.py index 087cdfb6..a7c631dc 100644 --- a/pydis_site/apps/resources/views/resources.py +++ b/pydis_site/apps/resources/views/resources.py @@ -1,7 +1,7 @@ from django.http import HttpRequest, HttpResponse from django.shortcuts import render -from pydis_site.apps.resources.utils import RESOURCE_TABLE, get_resources_from_search +from pydis_site.apps.resources.resource_search import RESOURCE_TABLE, get_resources_from_search RESOURCE_META_TAGS = {k: list(v) for k, v in RESOURCE_TABLE.items()} diff --git a/pydis_site/apps/resources/views/resources_list.py b/pydis_site/apps/resources/views/resources_list.py index 9d74be91..30498c8f 100644 --- a/pydis_site/apps/resources/views/resources_list.py +++ b/pydis_site/apps/resources/views/resources_list.py @@ -2,7 +2,7 @@ from typing import Any, Dict from django.views.generic import TemplateView -from pydis_site.apps.resources.utils import RESOURCES +from pydis_site.apps.resources.resource_search import RESOURCES class ResourcesListView(TemplateView): -- cgit v1.2.3 From 4ee8d527a2cf0ac7e4fd977ffd29e560b3cd48cb Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Thu, 27 Jan 2022 10:16:52 +0100 Subject: Greatly simplify the backend. Here we're getting rid of all filtering and search functionality on the backend. We'll be handling this on the client-side from now on. --- pydis_site/apps/resources/resource_search.py | 59 ---------------------- pydis_site/apps/resources/tests/test_views.py | 13 ----- pydis_site/apps/resources/urls.py | 3 +- pydis_site/apps/resources/views/__init__.py | 5 +- pydis_site/apps/resources/views/resources_list.py | 18 ------- pydis_site/templates/resources/resources_list.html | 52 ------------------- 6 files changed, 3 insertions(+), 147 deletions(-) delete mode 100644 pydis_site/apps/resources/resource_search.py delete mode 100644 pydis_site/apps/resources/views/resources_list.py delete mode 100644 pydis_site/templates/resources/resources_list.html (limited to 'pydis_site/apps/resources/tests') diff --git a/pydis_site/apps/resources/resource_search.py b/pydis_site/apps/resources/resource_search.py deleted file mode 100644 index 1e23089b..00000000 --- a/pydis_site/apps/resources/resource_search.py +++ /dev/null @@ -1,59 +0,0 @@ -import typing as t -from collections import defaultdict -from functools import reduce -from operator import and_, or_ -from pathlib import Path -from types import MappingProxyType - -import yaml -from django.conf import settings - - -def _transform_name(resource_name: str) -> str: - return resource_name.title().replace('And', 'and', -1) - - -Resource = dict[str, t.Union[str, list[dict[str, str]], dict[str, list[str]]]] - -RESOURCES_PATH = Path(settings.BASE_DIR, "pydis_site", "apps", "resources", "resources") - -RESOURCES: MappingProxyType[str, Resource] = MappingProxyType({ - path.stem: yaml.safe_load(path.read_text()) - for path in RESOURCES_PATH.rglob("*.yaml") -}) - -_resource_table = {category: defaultdict(set) for category in ( - "topics", - "payment_tiers", - "complexity", - "type" -)} - -for name, resource in RESOURCES.items(): - for category, tags in resource['tags'].items(): - for tag in tags: - _resource_table[category][_transform_name(tag)].add(name) - -# Freeze the resources table -RESOURCE_TABLE = MappingProxyType({ - category: MappingProxyType(d) - for category, d in _resource_table.items() -}) - -ALL_RESOURCE_NAMES = frozenset(RESOURCES.keys()) - - -def get_resources_from_search(search_categories: dict[str, set[str]]) -> list[Resource]: - """Returns a list of all resources that match the given search terms.""" - resource_names_that_match = reduce( - and_, - ( - reduce( - or_, - (RESOURCE_TABLE[category][label] for label in labels), - set() - ) or ALL_RESOURCE_NAMES - for category, labels in search_categories.items() - ) - ) - return [RESOURCES[name_] for name_ in resource_names_that_match] diff --git a/pydis_site/apps/resources/tests/test_views.py b/pydis_site/apps/resources/tests/test_views.py index 2e9efc1d..f96a04b0 100644 --- a/pydis_site/apps/resources/tests/test_views.py +++ b/pydis_site/apps/resources/tests/test_views.py @@ -16,16 +16,3 @@ class TestResourcesView(TestCase): url = reverse("resources:index") response = self.client.get(url) self.assertEqual(response.status_code, 200) - - -class TestResourcesListView(TestCase): - def test_valid_resource_list_200(self): - """Check does site return code 200 when visiting valid resource list.""" - url = reverse("resources:resources") - response = self.client.get(url) - self.assertEqual(response.status_code, 200) - - @patch("pydis_site.apps.resources.resource_search.RESOURCES_PATH", TESTING_RESOURCES_PATH) - def test_filter_resource_list(self): - """TODO: Check that we can correctly filter resources with GET parameters.""" - pass diff --git a/pydis_site/apps/resources/urls.py b/pydis_site/apps/resources/urls.py index c8d441df..3db26417 100644 --- a/pydis_site/apps/resources/urls.py +++ b/pydis_site/apps/resources/urls.py @@ -4,6 +4,5 @@ from pydis_site.apps.resources import views app_name = "resources" urlpatterns = [ - path("", views.resources.resource_view, name="index"), - path("list/", views.ResourcesListView.as_view(), name="resources") + path("", views.resources.ResourceView.as_view(), name="index"), ] diff --git a/pydis_site/apps/resources/views/__init__.py b/pydis_site/apps/resources/views/__init__.py index c89071c5..986f3e10 100644 --- a/pydis_site/apps/resources/views/__init__.py +++ b/pydis_site/apps/resources/views/__init__.py @@ -1,4 +1,3 @@ -from .resources import resource_view -from .resources_list import ResourcesListView +from .resources import ResourceView -__all__ = ["resource_view", "ResourcesListView"] +__all__ = ["ResourceView"] diff --git a/pydis_site/apps/resources/views/resources_list.py b/pydis_site/apps/resources/views/resources_list.py deleted file mode 100644 index 30498c8f..00000000 --- a/pydis_site/apps/resources/views/resources_list.py +++ /dev/null @@ -1,18 +0,0 @@ -from typing import Any, Dict - -from django.views.generic import TemplateView - -from pydis_site.apps.resources.resource_search import RESOURCES - - -class ResourcesListView(TemplateView): - """Shows specific resources list.""" - - template_name = "resources/resources_list.html" - - def get_context_data(self, **kwargs) -> Dict[str, Any]: - """Add resources and subcategories data into context.""" - context = super().get_context_data(**kwargs) - context["resources"] = RESOURCES - - return context diff --git a/pydis_site/templates/resources/resources_list.html b/pydis_site/templates/resources/resources_list.html deleted file mode 100644 index e2be3cb7..00000000 --- a/pydis_site/templates/resources/resources_list.html +++ /dev/null @@ -1,52 +0,0 @@ -{% extends "base/base.html" %} -{% load as_icon %} -{% load static %} - -{% block title %}{{ category_info.name }}{% endblock %} -{% block head %} - -{% endblock %} - -{% block content %} - {% include "base/navbar.html" %} - - - -
-
-
-

{{ category_info.name }}

-

{{ category_info.description|safe }}

-
- {% for resource in resources|dictsort:"position" %} - {% include "resources/resource_box.html" %} - {% endfor %} - - {% for subcategory in subcategories|dictsort:"category_info.position" %} -

- - {{ subcategory.category_info.name }} - -

-

{{ subcategory.category_info.description|safe }}

- - {% for resource in subcategory.resources|dictsort:"position" %} - {% with category_info=subcategory.category_info %} - {% include "resources/resource_box.html" %} - {% endwith %} - {% endfor %} - {% endfor %} -
-
-
-
-{% endblock %} -- cgit v1.2.3 From 325d7076ee7b426e50fdf513caed07536bfdb9b5 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Sat, 29 Jan 2022 14:55:01 +0100 Subject: Sort all the resources alphabetically. --- pydis_site/apps/resources/tests/test_views.py | 1 - pydis_site/apps/resources/views/resources.py | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'pydis_site/apps/resources/tests') diff --git a/pydis_site/apps/resources/tests/test_views.py b/pydis_site/apps/resources/tests/test_views.py index f96a04b0..dab3599d 100644 --- a/pydis_site/apps/resources/tests/test_views.py +++ b/pydis_site/apps/resources/tests/test_views.py @@ -1,5 +1,4 @@ from pathlib import Path -from unittest.mock import patch from django.conf import settings from django.test import TestCase diff --git a/pydis_site/apps/resources/views/resources.py b/pydis_site/apps/resources/views/resources.py index 14b3d0bf..d0b8bae7 100644 --- a/pydis_site/apps/resources/views/resources.py +++ b/pydis_site/apps/resources/views/resources.py @@ -2,7 +2,7 @@ from pathlib import Path import yaml from django.core.handlers.wsgi import WSGIRequest -from django.http import HttpRequest, HttpResponse +from django.http import HttpResponse from django.shortcuts import render from django.views import View @@ -24,6 +24,9 @@ class ResourceView(View): for path in RESOURCES_PATH.rglob("*.yaml") } + # Sort the resources alphabetically + self.resources = dict(sorted(self.resources.items())) + # Parse out all current tags resource_tags = { "topics": set(), -- cgit v1.2.3 From 71b1e7ec1ed5fd8f445015a759d74bfdd8828986 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Mon, 31 Jan 2022 22:29:18 +0100 Subject: Revert changes to pyproject.toml. These changes were not necessary. I am very sorry for the things that I did. --- pydis_site/apps/resources/tests/test_views.py | 2 +- pyproject.toml | 33 ++++++++++++++------------- 2 files changed, 18 insertions(+), 17 deletions(-) (limited to 'pydis_site/apps/resources/tests') diff --git a/pydis_site/apps/resources/tests/test_views.py b/pydis_site/apps/resources/tests/test_views.py index dab3599d..0af5ce5f 100644 --- a/pydis_site/apps/resources/tests/test_views.py +++ b/pydis_site/apps/resources/tests/test_views.py @@ -2,7 +2,7 @@ from pathlib import Path from django.conf import settings from django.test import TestCase -from django_hosts import reverse +from django.urls import reverse TESTING_RESOURCES_PATH = Path( settings.BASE_DIR, "pydis_site", "apps", "resources", "tests", "testing_resources" diff --git a/pyproject.toml b/pyproject.toml index 8525a16e..6392f871 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,26 +6,25 @@ authors = ["Python Discord "] license = "MIT" [tool.poetry.dependencies] +python = "3.9.*" django = "~=3.1.14" -django-distill = "~=2.9.0" django-environ = "~=0.4.5" django-filter = "~=21.1" -django-prometheus = "~=2.1" -django-simple-bulma = "~=2.4" djangorestframework = "~=3.12.0" -gunicorn = "~=20.0.4" -markdown = "~=3.3.4" psycopg2-binary = "~=2.8.0" -python = "3.9.*" -python-frontmatter = "~=1.0" -pyyaml = "~=5.1" +django-simple-bulma = "~=2.4" +whitenoise = "~=5.0" requests = "~=2.21" +pyyaml = "~=5.1" +gunicorn = "~=20.0.4" sentry-sdk = "~=0.19" -whitenoise = "~=5.0" +markdown = "~=3.3.4" +python-frontmatter = "~=1.0" +django-prometheus = "~=2.1" +django-distill = "~=2.9.0" [tool.poetry.dev-dependencies] coverage = "~=5.0" -coveralls = "~=2.1" flake8 = "~=3.7" flake8-annotations = "~=2.0" flake8-bandit = "~=2.1" @@ -39,18 +38,20 @@ mccabe = "~=0.6.1" pep8-naming = "~=0.9" pre-commit = "~=2.1" pyfakefs = "~=4.5" -python-dotenv = "~=0.17.1" +coveralls = "~=2.1" taskipy = "~=1.7.0" +python-dotenv = "~=0.17.1" [build-system] -build-backend = "poetry.core.masonry.api" requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" [tool.taskipy.tasks] +start = "python manage.py run --debug" +makemigrations = "python manage.py makemigrations" django_shell = "python manage.py shell" +test = "coverage run manage.py test" +report = "coverage report -m" lint = "pre-commit run --all-files" -makemigrations = "python manage.py makemigrations" precommit = "pre-commit install" -report = "coverage report -m" -start = "python manage.py run --debug" -test = "coverage run manage.py test" +static = "python manage.py distill-local build --traceback --force" -- cgit v1.2.3 From 47248a0a1e183871879ad1506b08a19a0b2042f4 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Mon, 31 Jan 2022 22:52:08 +0100 Subject: Add more tests for the new resources page. Coverage is now 100%. --- pydis_site/apps/resources/tests/test_views.py | 12 ++++++++++++ pyproject.toml | 1 + 2 files changed, 13 insertions(+) (limited to 'pydis_site/apps/resources/tests') diff --git a/pydis_site/apps/resources/tests/test_views.py b/pydis_site/apps/resources/tests/test_views.py index 0af5ce5f..a2a203ce 100644 --- a/pydis_site/apps/resources/tests/test_views.py +++ b/pydis_site/apps/resources/tests/test_views.py @@ -15,3 +15,15 @@ class TestResourcesView(TestCase): url = reverse("resources:index") response = self.client.get(url) self.assertEqual(response.status_code, 200) + + def test_resources_with_valid_argument(self): + """Check that you can resolve the resources when passing a valid argument.""" + url = reverse("resources:index", kwargs={"resource_type": "book"}) + response = self.client.get(url) + self.assertEqual(response.status_code, 200) + + def test_resources_with_invalid_argument(self): + """Check that you can resolve the resources when passing an invalid argument.""" + url = reverse("resources:index", kwargs={"resource_type": "urinal-cake"}) + response = self.client.get(url) + self.assertEqual(response.status_code, 404) diff --git a/pyproject.toml b/pyproject.toml index 6392f871..b350836e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,6 +51,7 @@ start = "python manage.py run --debug" makemigrations = "python manage.py makemigrations" django_shell = "python manage.py shell" test = "coverage run manage.py test" +coverage = "coverage run manage.py test --no-input; coverage report -m" report = "coverage report -m" lint = "pre-commit run --all-files" precommit = "pre-commit install" -- cgit v1.2.3 From f3bccff688a7f5a9eb619dbed3f726ef2c07c402 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Tue, 1 Feb 2022 20:54:39 +0100 Subject: Refactor as_css_class to 'to_kebabcase'. We're making a few changes here - Changing the name to 'to_kebabcase' - Covering all edge cases - Adding a unit test for this utility --- .../apps/resources/templatetags/as_css_class.py | 18 ---------- .../apps/resources/templatetags/to_kebabcase.py | 39 ++++++++++++++++++++++ pydis_site/apps/resources/tests/test_resources.py | 9 ----- .../apps/resources/tests/test_to_kebabcase.py | 19 +++++++++++ .../testing/foobar/resource_test.yaml | 1 - .../testing_resources/testing/my_resource.yaml | 1 - pydis_site/apps/resources/views/resources.py | 14 ++++---- pydis_site/templates/resources/resource_box.html | 10 +++--- pydis_site/templates/resources/resources.html | 22 ++++++------ 9 files changed, 80 insertions(+), 53 deletions(-) delete mode 100644 pydis_site/apps/resources/templatetags/as_css_class.py create mode 100644 pydis_site/apps/resources/templatetags/to_kebabcase.py delete mode 100644 pydis_site/apps/resources/tests/test_resources.py create mode 100644 pydis_site/apps/resources/tests/test_to_kebabcase.py delete mode 100644 pydis_site/apps/resources/tests/testing_resources/testing/foobar/resource_test.yaml delete mode 100644 pydis_site/apps/resources/tests/testing_resources/testing/my_resource.yaml (limited to 'pydis_site/apps/resources/tests') diff --git a/pydis_site/apps/resources/templatetags/as_css_class.py b/pydis_site/apps/resources/templatetags/as_css_class.py deleted file mode 100644 index 8b628dc9..00000000 --- a/pydis_site/apps/resources/templatetags/as_css_class.py +++ /dev/null @@ -1,18 +0,0 @@ -from django import template - -register = template.Library() - - -@register.filter -def as_css_class(class_name: str) -> str: - """ - Convert any string to a css-class name. - - For example, convert - "Favorite FROOT_is_LEMON" to - "favorite-froot-is-lemon" - """ - class_name = class_name.lower() - class_name = class_name.replace(" ", "-") - class_name = class_name.replace("_", "-") - return class_name diff --git a/pydis_site/apps/resources/templatetags/to_kebabcase.py b/pydis_site/apps/resources/templatetags/to_kebabcase.py new file mode 100644 index 00000000..41e2ac85 --- /dev/null +++ b/pydis_site/apps/resources/templatetags/to_kebabcase.py @@ -0,0 +1,39 @@ +import re + +from django import template + +REGEX_CONSECUTIVE_NON_LETTERS = r"[^A-Za-z0-9]+" +register = template.Library() + + +def _to_kebabcase(class_name: str) -> str: + """ + Convert any string to kebab-case. + + For example, convert + "__Favorite FROOT¤#/$?is----LeMON???" to + "favorite-froot-is-lemon" + """ + # First, make it lowercase, and just remove any apostrophes. + # We remove the apostrophes because "wasnt" is better than "wasn-t" + class_name = class_name.casefold() + class_name = class_name.replace("'", '') + + # Now, replace any non-letter that remains with a dash. + # If there are multiple consecutive non-letters, just replace them with a single dash. + # my-favorite-class is better than my-favorite------class + class_name = re.sub( + REGEX_CONSECUTIVE_NON_LETTERS, + "-", + class_name, + ) + + # Now we use strip to get rid of any leading or trailing dashes. + class_name = class_name.strip("-") + return class_name + + +@register.filter +def to_kebabcase(class_name: str) -> str: + """Convert a string to kebab-case.""" + return _to_kebabcase(class_name) diff --git a/pydis_site/apps/resources/tests/test_resources.py b/pydis_site/apps/resources/tests/test_resources.py deleted file mode 100644 index 81638e2f..00000000 --- a/pydis_site/apps/resources/tests/test_resources.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.test import TestCase - - -class TestResources(TestCase): - """Test our resource filtering systems.""" - - def test_utils_to_retrieve_tags(self): - """Test that the utils that retrieve the tags work as intended.""" - pass diff --git a/pydis_site/apps/resources/tests/test_to_kebabcase.py b/pydis_site/apps/resources/tests/test_to_kebabcase.py new file mode 100644 index 00000000..a141143d --- /dev/null +++ b/pydis_site/apps/resources/tests/test_to_kebabcase.py @@ -0,0 +1,19 @@ +from django.test import TestCase + +from pydis_site.apps.resources.templatetags.to_kebabcase import _to_kebabcase + + +class TestToKebabcase(TestCase): + """Tests for the `as_css_class` template tag.""" + + def test_to_kebabcase(self): + """Test the to_kebabcase utility and template tag.""" + weird_input = ( + "_-_--_A_LEm0n?in&¤'the##trEE£$@€@€@@£is-NOT----QUITE//" + "as#good! as one __IN-YOUR|||HaND" + ) + + self.assertEqual( + _to_kebabcase(weird_input), + "a-lem0n-in-the-tree-is-not-quite-as-good-as-one-in-your-hand", + ) diff --git a/pydis_site/apps/resources/tests/testing_resources/testing/foobar/resource_test.yaml b/pydis_site/apps/resources/tests/testing_resources/testing/foobar/resource_test.yaml deleted file mode 100644 index 22835090..00000000 --- a/pydis_site/apps/resources/tests/testing_resources/testing/foobar/resource_test.yaml +++ /dev/null @@ -1 +0,0 @@ -name: Resource Test diff --git a/pydis_site/apps/resources/tests/testing_resources/testing/my_resource.yaml b/pydis_site/apps/resources/tests/testing_resources/testing/my_resource.yaml deleted file mode 100644 index 61df6173..00000000 --- a/pydis_site/apps/resources/tests/testing_resources/testing/my_resource.yaml +++ /dev/null @@ -1 +0,0 @@ -name: My Resource diff --git a/pydis_site/apps/resources/views/resources.py b/pydis_site/apps/resources/views/resources.py index ac9e8355..2375f722 100644 --- a/pydis_site/apps/resources/views/resources.py +++ b/pydis_site/apps/resources/views/resources.py @@ -9,7 +9,7 @@ from django.shortcuts import render from django.views import View from pydis_site import settings -from pydis_site.apps.resources.templatetags.as_css_class import as_css_class +from pydis_site.apps.resources.templatetags.to_kebabcase import to_kebabcase RESOURCES_PATH = Path(settings.BASE_DIR, "pydis_site", "apps", "resources", "resources") @@ -58,9 +58,7 @@ class ResourceView(View): # Make a CSS class friendly representation too, while we're already iterating. for tag in tags: - css_tag = f"{tag_type}-{tag}" - css_tag = css_tag.replace("_", "-") - css_tag = css_tag.replace(" ", "-") + css_tag = to_kebabcase(f"{tag_type}-{tag}") css_classes.append(css_tag) # Now add the css classes back to the resource, so we can use them in the template. @@ -96,12 +94,12 @@ class ResourceView(View): # A complete list of valid filter names self.valid_filters = { - "topics": [as_css_class(topic) for topic in self.filters["Topics"]["filters"]], + "topics": [to_kebabcase(topic) for topic in self.filters["Topics"]["filters"]], "payment_tiers": [ - as_css_class(tier) for tier in self.filters["Payment tiers"]["filters"] + to_kebabcase(tier) for tier in self.filters["Payment tiers"]["filters"] ], - "type": [as_css_class(type_) for type_ in self.filters["Type"]["filters"]], - "difficulty": [as_css_class(tier) for tier in self.filters["Difficulty"]["filters"]], + "type": [to_kebabcase(type_) for type_ in self.filters["Type"]["filters"]], + "difficulty": [to_kebabcase(tier) for tier in self.filters["Difficulty"]["filters"]], } def get(self, request: WSGIRequest, resource_type: t.Optional[str] = None) -> HttpResponse: diff --git a/pydis_site/templates/resources/resource_box.html b/pydis_site/templates/resources/resource_box.html index 2ec233cb..e26203e9 100644 --- a/pydis_site/templates/resources/resource_box.html +++ b/pydis_site/templates/resources/resource_box.html @@ -1,5 +1,5 @@ {% load as_icon %} -{% load as_css_class %} +{% load to_kebabcase %} {% load get_category_icon %}
@@ -38,7 +38,7 @@ {{ tag|title }} @@ -48,7 +48,7 @@ {{ tag|title }} @@ -58,7 +58,7 @@ {{ tag|title }} @@ -68,7 +68,7 @@ {{ tag|title }} diff --git a/pydis_site/templates/resources/resources.html b/pydis_site/templates/resources/resources.html index c221c8a3..70fad097 100644 --- a/pydis_site/templates/resources/resources.html +++ b/pydis_site/templates/resources/resources.html @@ -1,6 +1,6 @@ {% extends 'base/base.html' %} {% load as_icon %} -{% load as_css_class %} +{% load to_kebabcase %} {% load get_category_icon %} {% load static %} @@ -44,8 +44,8 @@ {% if filter_name == "Difficulty" %} {{ filter_item|title }} @@ -55,8 +55,8 @@ {% if filter_name == "Type" %} {{ filter_item|title }} @@ -66,8 +66,8 @@ {% if filter_name == "Payment tiers" %} {{ filter_item|title }} @@ -77,8 +77,8 @@ {% if filter_name == "Topics" %} {{ filter_item|title }} @@ -127,8 +127,8 @@ {{ filter_item }} -- cgit v1.2.3