aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site/apps
diff options
context:
space:
mode:
authorGravatar RohanJnr <[email protected]>2024-02-11 12:26:39 +0530
committerGravatar RohanJnr <[email protected]>2024-02-11 12:26:39 +0530
commit6cea8884316f3b3343cf7df6525358d2805520ac (patch)
tree9b1125d7fbe9e375cbe8acce373af755c300709a /pydis_site/apps
parentMerge pull request #1227 from python-discord/dependabot/pip/sentry-sdk-1.40.2 (diff)
Move resorce loading from view init() to AppConfig ready() method
This is done to load the resources only once on startup instead of loading it everytime the view is initialized which is done whenever a request is made to the resources endpoint.
Diffstat (limited to 'pydis_site/apps')
-rw-r--r--pydis_site/apps/resources/apps.py92
-rw-r--r--pydis_site/apps/resources/views.py103
2 files changed, 101 insertions, 94 deletions
diff --git a/pydis_site/apps/resources/apps.py b/pydis_site/apps/resources/apps.py
index 93117654..51cb064b 100644
--- a/pydis_site/apps/resources/apps.py
+++ b/pydis_site/apps/resources/apps.py
@@ -1,7 +1,99 @@
+from pathlib import Path
+
+import yaml
from django.apps import AppConfig
+from pydis_site import settings
+from pydis_site.apps.resources.templatetags.to_kebabcase import to_kebabcase
+
+RESOURCES_PATH = Path(settings.BASE_DIR, "pydis_site", "apps", "resources", "resources")
+
class ResourcesConfig(AppConfig):
"""AppConfig instance for Resources app."""
name = 'pydis_site.apps.resources'
+
+ @staticmethod
+ def _sort_key_disregard_the(tuple_: tuple) -> str:
+ """Sort a tuple by its key alphabetically, disregarding 'the' as a prefix."""
+ name, resource = tuple_
+ name = name.casefold()
+ if name.startswith(("the ", "the_")):
+ return name[4:]
+ return name
+
+
+ def ready(self) -> None:
+ """Set up all the resources."""
+ # Load the resources from the yaml files in /resources/
+ self.resources = {
+ path.stem: yaml.safe_load(path.read_text())
+ for path in RESOURCES_PATH.rglob("*.yaml")
+ }
+
+ # Sort the resources alphabetically
+ self.resources = dict(sorted(self.resources.items(), key=self._sort_key_disregard_the))
+
+ # Parse out all current tags
+ resource_tags = {
+ "topics": set(),
+ "payment_tiers": set(),
+ "difficulty": set(),
+ "type": set(),
+ }
+ for resource_name, resource in self.resources.items():
+ css_classes = []
+ for tag_type in resource_tags:
+ # Store the tags into `resource_tags`
+ tags = resource.get("tags", {}).get(tag_type, [])
+ for tag in tags:
+ tag = tag.title()
+ tag = tag.replace("And", "and")
+ resource_tags[tag_type].add(tag)
+
+ # Make a CSS class friendly representation too, while we're already iterating.
+ for tag in tags:
+ 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.
+ self.resources[resource_name]["css_classes"] = " ".join(css_classes)
+
+ # Set up all the filter checkbox metadata
+ self.filters = {
+ "Difficulty": {
+ "filters": sorted(resource_tags.get("difficulty")),
+ "icon": "fas fa-brain",
+ "hidden": False,
+ },
+ "Type": {
+ "filters": sorted(resource_tags.get("type")),
+ "icon": "fas fa-photo-video",
+ "hidden": False,
+ },
+ "Payment tiers": {
+ "filters": sorted(resource_tags.get("payment_tiers")),
+ "icon": "fas fa-dollar-sign",
+ "hidden": True,
+ },
+ "Topics": {
+ "filters": sorted(resource_tags.get("topics")),
+ "icon": "fas fa-lightbulb",
+ "hidden": True,
+ }
+ }
+
+ # The bottom topic should always be "Other".
+ self.filters["Topics"]["filters"].remove("Other")
+ self.filters["Topics"]["filters"].append("Other")
+
+ # A complete list of valid filter names
+ self.valid_filters = {
+ "topics": [to_kebabcase(topic) for topic in self.filters["Topics"]["filters"]],
+ "payment_tiers": [
+ to_kebabcase(tier) for tier in self.filters["Payment tiers"]["filters"]
+ ],
+ "type": [to_kebabcase(type_) for type_ in self.filters["Type"]["filters"]],
+ "difficulty": [to_kebabcase(tier) for tier in self.filters["Difficulty"]["filters"]],
+ }
diff --git a/pydis_site/apps/resources/views.py b/pydis_site/apps/resources/views.py
index a2cd8d0c..3632b2e2 100644
--- a/pydis_site/apps/resources/views.py
+++ b/pydis_site/apps/resources/views.py
@@ -1,114 +1,29 @@
import json
-from pathlib import Path
-import yaml
+from django.apps import apps
from django.core.handlers.wsgi import WSGIRequest
from django.http import HttpResponse, HttpResponseNotFound
from django.shortcuts import render
from django.views import View
-from pydis_site import settings
-from pydis_site.apps.resources.templatetags.to_kebabcase import to_kebabcase
-RESOURCES_PATH = Path(settings.BASE_DIR, "pydis_site", "apps", "resources", "resources")
+APP_NAME = "resources"
class ResourceView(View):
"""Our curated list of good learning resources."""
- @staticmethod
- def _sort_key_disregard_the(tuple_: tuple) -> str:
- """Sort a tuple by its key alphabetically, disregarding 'the' as a prefix."""
- name, resource = tuple_
- name = name.casefold()
- if name.startswith(("the ", "the_")):
- return name[4:]
- return name
-
- def __init__(self, *args, **kwargs):
- """Set up all the resources."""
- super().__init__(*args, **kwargs)
-
- # Load the resources from the yaml files in /resources/
- self.resources = {
- path.stem: yaml.safe_load(path.read_text())
- for path in RESOURCES_PATH.rglob("*.yaml")
- }
-
- # Sort the resources alphabetically
- self.resources = dict(sorted(self.resources.items(), key=self._sort_key_disregard_the))
-
- # Parse out all current tags
- resource_tags = {
- "topics": set(),
- "payment_tiers": set(),
- "difficulty": set(),
- "type": set(),
- }
- for resource_name, resource in self.resources.items():
- css_classes = []
- for tag_type in resource_tags:
- # Store the tags into `resource_tags`
- tags = resource.get("tags", {}).get(tag_type, [])
- for tag in tags:
- tag = tag.title()
- tag = tag.replace("And", "and")
- resource_tags[tag_type].add(tag)
-
- # Make a CSS class friendly representation too, while we're already iterating.
- for tag in tags:
- 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.
- self.resources[resource_name]["css_classes"] = " ".join(css_classes)
-
- # Set up all the filter checkbox metadata
- self.filters = {
- "Difficulty": {
- "filters": sorted(resource_tags.get("difficulty")),
- "icon": "fas fa-brain",
- "hidden": False,
- },
- "Type": {
- "filters": sorted(resource_tags.get("type")),
- "icon": "fas fa-photo-video",
- "hidden": False,
- },
- "Payment tiers": {
- "filters": sorted(resource_tags.get("payment_tiers")),
- "icon": "fas fa-dollar-sign",
- "hidden": True,
- },
- "Topics": {
- "filters": sorted(resource_tags.get("topics")),
- "icon": "fas fa-lightbulb",
- "hidden": True,
- }
- }
-
- # The bottom topic should always be "Other".
- self.filters["Topics"]["filters"].remove("Other")
- self.filters["Topics"]["filters"].append("Other")
-
- # A complete list of valid filter names
- self.valid_filters = {
- "topics": [to_kebabcase(topic) for topic in self.filters["Topics"]["filters"]],
- "payment_tiers": [
- to_kebabcase(tier) for tier in self.filters["Payment tiers"]["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: str | None = None) -> HttpResponse:
"""List out all the resources, and any filtering options from the URL."""
# Add type filtering if the request is made to somewhere like /resources/video.
# We also convert all spaces to dashes, so they'll correspond with the filters.
+
+ app = apps.get_app_config(APP_NAME)
+
if resource_type:
dashless_resource_type = resource_type.replace("-", " ")
- if dashless_resource_type.title() not in self.filters["Type"]["filters"]:
+ if dashless_resource_type.title() not in app.filters["Type"]["filters"]:
return HttpResponseNotFound()
resource_type = resource_type.replace(" ", "-")
@@ -117,9 +32,9 @@ class ResourceView(View):
request,
template_name="resources/resources.html",
context={
- "resources": self.resources,
- "filters": self.filters,
- "valid_filters": json.dumps(self.valid_filters),
+ "resources": app.resources,
+ "filters": app.filters,
+ "valid_filters": json.dumps(app.valid_filters),
"resource_type": resource_type,
}
)