aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site
diff options
context:
space:
mode:
authorGravatar Johannes Christ <[email protected]>2022-02-28 18:13:01 +0100
committerGravatar GitHub <[email protected]>2022-02-28 18:13:01 +0100
commit193f0a977471539859d0b72c56f8db55a0d9f3c7 (patch)
tree16429114e21a429ae336d1b9d8ba90512bbc2712 /pydis_site
parentMerge pull request #682 from python-discord/add-channel_id-to-clean-logs (diff)
parentAdd link to contributing guide (diff)
Merge pull request #683 from python-discord/readme-for-project-directory
Add a README for the project directory, remove unused apps
Diffstat (limited to 'pydis_site')
-rw-r--r--pydis_site/README.md68
-rw-r--r--pydis_site/apps/home/views/home.py7
-rw-r--r--pydis_site/constants.py6
-rw-r--r--pydis_site/context_processors.py5
-rw-r--r--pydis_site/settings.py10
-rw-r--r--pydis_site/utils/resources.py91
6 files changed, 82 insertions, 105 deletions
diff --git a/pydis_site/README.md b/pydis_site/README.md
new file mode 100644
index 00000000..db402743
--- /dev/null
+++ b/pydis_site/README.md
@@ -0,0 +1,68 @@
+# `pydis_site` project directory
+
+This directory hosts the root of our **Django project**[^1], and is responsible
+for all logic powering our website. Let's go over the directories in detail:
+
+- [`apps`](./apps) contains our **Django apps**, which are the building blocks
+ that make up our Django project. A Django project must always consist of one
+ or more apps, and these apps can be made completely modular and reusable
+ across any Django project. In our project, each app controls a distinct part
+ of our website, such as the API or our resources system.
+
+ For more information on reusable apps, see the official Django tutorial,
+ [which has a section on reusable
+ apps](https://docs.djangoproject.com/en/dev/intro/reusable-apps/). To learn
+ more about our specific apps, see the README inside the app folder itself.
+
+- [`static`](./static) contains our **static files**, such as CSS, JavaScript,
+ images, and anything else that isn't either content or Python code. Static
+ files relevant for a specific application are put into subdirectories named
+ after the application. For example, static files used by the `resources` app go in `static/resources`.
+
+- [`templates`](./templates) contains our **[Django
+ templates](https://docs.djangoproject.com/en/dev/topics/templates/)**. Like
+ with static files, templates specific to a single application are stored in a
+ subdirectory named after that application. We also have two special templates
+ here:
+
+ - `404.html`, which is our error page shown when a site was not found.
+
+ - `500.html`, which is our error page shown in the astronomically rare case
+ that we encounter an internal server error.
+
+
+Note that for both `static` and `templates`, we are not using the default Django
+directory structure which puts these directories in a directory per app (in our
+case, this would for example be ``pydis_site/apps/content/static/``).
+
+We also have a few files in here that are relevant or useful in large parts of
+the website:
+
+- [`context_processors.py`](./context_processors.py), which contains custom
+ *context processors* that add variables to the Django template context. To
+ read more, see the [`RequestContext` documentation from
+ Django](https://docs.djangoproject.com/en/dev/ref/templates/api/#django.template.RequestContext)
+
+- [`settings.py`](./settings.py), our Django settings file. This controls all
+ manner of crucial things, for instance, we use it to configure logging, our
+ connection to the database, which applications are run by the project, which
+ middleware we are using, and variables for `django-simple-bulma` (which
+ determines frontend colours & extensions for our pages).
+
+- [`urls.py`](./urls.py), the URL configuration for the project itself. Here we
+ can forward certain URL paths to our different apps, which have their own
+ `urls.py` files to configure where their subpaths will lead. These files
+ determine _which URLs will lead to which Django views_.
+
+- [`wsgi.py`](./wsgi.py), which serves as an adapter for
+ [`gunicorn`](https://github.com/benoitc/gunicorn),
+ [`uwsgi`](https://github.com/unbit/uwsgi), or other application servers to run
+ our application in production. Unless you want to test an interaction between
+ our application and those servers, you probably won't need to touch this.
+
+
+For more information about contributing to our projects, please see our
+[Contributing
+page](https://www.pythondiscord.com/pages/guides/pydis-guides/contributing/).
+
+[^1]: See [Django Glossary: project](https://docs.djangoproject.com/en/dev/glossary/#term-project)
diff --git a/pydis_site/apps/home/views/home.py b/pydis_site/apps/home/views/home.py
index e28a3a00..69e706c5 100644
--- a/pydis_site/apps/home/views/home.py
+++ b/pydis_site/apps/home/views/home.py
@@ -10,7 +10,6 @@ from django.views import View
from pydis_site import settings
from pydis_site.apps.home.models import RepositoryMetadata
-from pydis_site.constants import GITHUB_TOKEN, TIMEOUT_PERIOD
log = logging.getLogger(__name__)
@@ -43,8 +42,8 @@ class HomeView(View):
# specifically, GitHub will reject any requests from us due to the
# invalid header. We can make a limited number of anonymous requests
# though, which is useful for testing.
- if GITHUB_TOKEN:
- self.headers = {"Authorization": f"token {GITHUB_TOKEN}"}
+ if settings.GITHUB_TOKEN:
+ self.headers = {"Authorization": f"token {settings.GITHUB_TOKEN}"}
else:
self.headers = {}
@@ -60,7 +59,7 @@ class HomeView(View):
api_data: List[dict] = requests.get(
self.github_api,
headers=self.headers,
- timeout=TIMEOUT_PERIOD
+ timeout=settings.TIMEOUT_PERIOD
).json()
except requests.exceptions.Timeout:
log.error("Request to fetch GitHub repository metadata for timed out!")
diff --git a/pydis_site/constants.py b/pydis_site/constants.py
deleted file mode 100644
index e913f40f..00000000
--- a/pydis_site/constants.py
+++ /dev/null
@@ -1,6 +0,0 @@
-import os
-
-GIT_SHA = os.environ.get("GIT_SHA", "development")
-GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN")
-# How long to wait for synchronous requests before timing out
-TIMEOUT_PERIOD = int(os.environ.get("TIMEOUT_PERIOD", 5))
diff --git a/pydis_site/context_processors.py b/pydis_site/context_processors.py
index 6937a3db..0e8b4a94 100644
--- a/pydis_site/context_processors.py
+++ b/pydis_site/context_processors.py
@@ -1,8 +1,7 @@
+from django.conf import settings
from django.template import RequestContext
-from pydis_site.constants import GIT_SHA
-
def git_sha_processor(_: RequestContext) -> dict:
"""Expose the git SHA for this repo to all views."""
- return {'git_sha': GIT_SHA}
+ return {'git_sha': settings.GIT_SHA}
diff --git a/pydis_site/settings.py b/pydis_site/settings.py
index 3b146f2c..4f2b4aef 100644
--- a/pydis_site/settings.py
+++ b/pydis_site/settings.py
@@ -20,15 +20,20 @@ import environ
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration
-from pydis_site.constants import GIT_SHA
env = environ.Env(
DEBUG=(bool, False),
SITE_DSN=(str, ""),
BUILDING_DOCKER=(bool, False),
STATIC_BUILD=(bool, False),
+ GIT_SHA=(str, 'development'),
+ TIMEOUT_PERIOD=(int, 5),
+ GITHUB_TOKEN=(str, None),
)
+GIT_SHA = env("GIT_SHA")
+GITHUB_TOKEN = env("GITHUB_TOKEN")
+
sentry_sdk.init(
dsn=env('SITE_DSN'),
integrations=[DjangoIntegration()],
@@ -288,3 +293,6 @@ CONTENT_PAGES_PATH = Path(BASE_DIR, "pydis_site", "apps", "content", "resources"
# Path for redirection links
REDIRECTIONS_PATH = Path(BASE_DIR, "pydis_site", "apps", "redirect", "redirects.yaml")
+
+# How long to wait for synchronous requests before timing out
+TIMEOUT_PERIOD = env("TIMEOUT_PERIOD")
diff --git a/pydis_site/utils/resources.py b/pydis_site/utils/resources.py
deleted file mode 100644
index 637fd785..00000000
--- a/pydis_site/utils/resources.py
+++ /dev/null
@@ -1,91 +0,0 @@
-from __future__ import annotations
-
-import glob
-import typing
-from dataclasses import dataclass
-
-import yaml
-
-
-@dataclass
-class URL:
- """A class representing a link to a resource."""
-
- icon: str
- title: str
- url: str
-
-
-class Resource:
- """A class representing a resource on the resource page."""
-
- description: str
- name: str
- payment: str
- payment_description: typing.Optional[str]
- urls: typing.List[URL]
-
- def __repr__(self):
- """Return a representation of the resource."""
- return f"<Resource name={self.name}>"
-
- @classmethod
- def construct_from_yaml(cls, yaml_data: typing.TextIO) -> Resource:
- """Construct a Resource object from the provided YAML."""
- resource = cls()
-
- loaded = yaml.safe_load(yaml_data)
-
- resource.__dict__.update(loaded)
-
- resource.__dict__["urls"] = []
-
- for url in loaded["urls"]:
- resource.__dict__["urls"].append(URL(**url))
-
- return resource
-
-
-class Category:
- """A class representing a resource on the resources page."""
-
- resources: typing.List[Resource]
- name: str
- description: str
-
- def __repr__(self):
- """Return a representation of the category."""
- return f"<Category name={self.name}>"
-
- @classmethod
- def construct_from_directory(cls, directory: str) -> Category:
- """Construct a Category object from the provided directory."""
- category = cls()
-
- with open(f"{directory}/_category_info.yaml") as category_info:
- category_data = yaml.safe_load(category_info)
-
- category.__dict__.update(category_data)
-
- category.resources = []
-
- for resource in glob.glob(f"{directory}/*.yaml"):
- if resource == f"{directory}/_category_info.yaml":
- continue
-
- with open(resource) as res_file:
- category.resources.append(
- Resource.construct_from_yaml(res_file)
- )
-
- return category
-
-
-def load_categories(order: typing.List[str]) -> typing.List[Category]:
- """Load the categories specified in the order list and return them."""
- categories = []
- for cat in order:
- direc = "pydis_site/apps/home/resources/" + cat
- categories.append(Category.construct_from_directory(direc))
-
- return categories