fix settings and add dummy view

This introduces customisation to `settings.py` that
- allow controlling the relevant parameters from our systemd wrapper
  (more brittle and non-obvious than it should be, see TODOs)
- correctly configure SASS processing and static file compression
  (not as easy as it sounds)
This commit is contained in:
Valentin Gagarin 2025-02-12 23:59:51 +01:00
parent 7c33e8aaf3
commit f97dc7e121
6 changed files with 100 additions and 5 deletions

View file

@ -10,6 +10,12 @@ For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/ https://docs.djangoproject.com/en/4.2/ref/settings/
""" """
import sys
import os
import importlib.util
import dj_database_url
from os import environ as env
from pathlib import Path from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'. # Build paths inside the project like this: BASE_DIR / 'subdir'.
@ -19,8 +25,22 @@ BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ # See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
def get_secret(name: str, encoding: str = "utf-8") -> str:
credentials_dir = env.get("CREDENTIALS_DIRECTORY")
if credentials_dir is None:
raise RuntimeError("No credentials directory available.")
try:
with open(f"{credentials_dir}/{name}", encoding=encoding) as f:
secret = f.read().removesuffix("\n")
except FileNotFoundError:
raise RuntimeError(f"No secret named {name} found in {credentials_dir}.")
return secret
# SECURITY WARNING: keep the secret key used in production secret! # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-9*i_k2o@x-c7w%o!*@b88t%n)eh=c2nj2f2m*-=$gwfn#zoso7' SECRET_KEY = get_secret("SECRET_KEY")
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True DEBUG = True
@ -31,12 +51,14 @@ ALLOWED_HOSTS = []
# Application definition # Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [
"panel",
'django.contrib.admin', 'django.contrib.admin',
'django.contrib.auth', 'django.contrib.auth',
'django.contrib.contenttypes', 'django.contrib.contenttypes',
'django.contrib.sessions', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'compressor',
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -72,12 +94,10 @@ WSGI_APPLICATION = 'panel.wsgi.application'
# Database # Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases # https://docs.djangoproject.com/en/4.2/ref/settings/#databases
# https://github.com/jazzband/dj-database-url
DATABASES = { DATABASES = {
'default': { 'default': dj_database_url.config(),
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
} }
@ -117,7 +137,35 @@ USE_TZ = True
STATIC_URL = 'static/' STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
STATICFILES_FINDERS = [
"django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
"compressor.finders.CompressorFinder",
]
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
COMPRESS_PRECOMPILERS = [
("text/x-sass", "django_libsass.SassCompiler"),
]
# Default primary key field type # Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field # https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# Customization via user settings
# This must be at the end, as it must be able to override the above
# TODO: we may want to do this with a flat environment instead, and get all values from `os.environ.get()`.
# this would make it more obvious which moving parts there are, if that environment is specified for development/staging/production in a visible place.
user_settings_file = env.get("USER_SETTINGS_FILE", None)
if user_settings_file is not None:
spec = importlib.util.spec_from_file_location("user_settings", user_settings_file)
if spec is None or spec.loader is None:
raise RuntimeError("User settings specification failed!")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
sys.modules["user_settings"] = module
from user_settings import * # noqa: F403 # pyright: ignore [reportMissingImports]

View file

@ -0,0 +1,5 @@
body
padding: 0
margin: 0
font-family: sans-serif
box-sizing: border-box

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>{% block title %}Fediversity Panel{% endblock %}</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
{% load compress %}
{% compress css %}
<link rel="stylesheet" type="text/x-sass" href="/static/style.sass" />
{% endcompress %}
{% block extra_head %}{% endblock extra_head %}
</head>
<body>
{% block navigation %}
<nav>
</nav>
{% endblock navigation %}
{% block layout %}
<article>
{% block content %}{% endblock content %}
</article>
{% endblock layout %}
</body>
</html>

View file

@ -0,0 +1,7 @@
{% extends "base.html" %}
{% block content %}
<h1>Fediversity Panel</h1>
<p>Hello world!</p>
{% endblock %}

View file

@ -16,7 +16,9 @@ Including another URLconf
""" """
from django.contrib import admin from django.contrib import admin
from django.urls import path from django.urls import path
from panel import views
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('', views.Index.as_view(), name='index'),
] ]

4
panel/src/panel/views.py Normal file
View file

@ -0,0 +1,4 @@
from django.views.generic import TemplateView
class Index(TemplateView):
template_name = 'index.html'