diff --git a/.gitignore b/.gitignore index 67588a1..e1dba2e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,7 @@ /build -*/mediafiles -*/staticfiles +*/uploads __pycache__ *.pyc .venv -.env* *.sqlite3 diff --git a/README.md b/README.md index cc8fb86..d7112f5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Web backend for hosting a wedding website. -# Run Local server: +## Run development server: ```sh source .venv/bin/activate @@ -10,49 +10,10 @@ cd wedding_site python manage.py runserver ``` -# Do Migrations +## Do Migrations ```sh cd wedding_site python manage.py makemigrations primary python manage.py migrate -``` - -# Run Dev Server in container - -```sh -podman-compose -f compose.yaml up -d --build -``` - -Bring it down with: - -```sh -podman-compose down -v -``` - -# Run Prod Server - -```sh -podman-compose -f compose.prod.yaml up -d --build -``` - -Sync static files: - -```sh -podman-compose -f compose.prod.yaml exec web python manage.py collectstatic --no-input --clear -``` - -Check cert - -```sh -podman-compose -f compose.prod.yaml exec acme-companion /app/cert_status -``` - -Force renew cert: - -```sh -podman-compose -f compose.prod.yaml exec acme-companion /app/force_renew -``` - - - +``` \ No newline at end of file diff --git a/compose.prod.yaml b/compose.prod.yaml deleted file mode 100644 index a60429c..0000000 --- a/compose.prod.yaml +++ /dev/null @@ -1,52 +0,0 @@ -version: '3.8' - -services: - web: - build: ./wedding_site - command: gunicorn wedding_site.wsgi:application --bind 0.0.0.0:8000 - volumes: - - ./wedding_site/:/usr/src/app/ - - static_volume:/staticfiles - - media_volume:/mediafiles - expose: - - 8000 - env_file: - - ./.env.prod - - nginx-proxy: - container_name: nginx-proxy - build: ./nginx - restart: always - ports: - - 443:443 - - 80:80 - volumes: - - static_volume:/staticfiles - - media_volume:/mediafiles - - certs:/etc/nginx/certs - - html:/usr/share/nginx/html - - vhost:/etc/nginx/vhost.d - - /var/run/docker.sock:/tmp/docker.sock:ro - depends_on: - - web - - acme-companion: - image: docker.io/nginxproxy/acme-companion - env_file: - - ./.env.prod.proxy-companion - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - - certs:/etc/nginx/certs - - html:/usr/share/nginx/html - - vhost:/etc/nginx/vhost.d - - acme:/etc/acme.sh - depends_on: - - nginx-proxy - -volumes: - static_volume: - media_volume: - certs: - html: - vhost: - acme: \ No newline at end of file diff --git a/compose.staging.yaml b/compose.staging.yaml deleted file mode 100644 index 5d151a9..0000000 --- a/compose.staging.yaml +++ /dev/null @@ -1,52 +0,0 @@ -version: '3.8' - -services: - web: - build: ./wedding_site - command: gunicorn wedding_site.wsgi:application --bind 0.0.0.0:8000 - volumes: - - ./wedding_site/:/usr/src/app/ - - static_volume:/staticfiles - - media_volume:/mediafiles - expose: - - 8000 - env_file: - - ./.env.staging - - nginx-proxy: - container_name: nginx-proxy - build: ./nginx - restart: always - ports: - - 443:443 - - 80:80 - volumes: - - static_volume:/staticfiles - - media_volume:/mediafiles - - certs:/etc/nginx/certs - - html:/usr/share/nginx/html - - vhost:/etc/nginx/vhost.d - - /var/run/docker.sock:/tmp/docker.sock:ro - depends_on: - - web - - acme-companion: - image: docker.io/nginxproxy/acme-companion - env_file: - - ./.env.staging.proxy-companion - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - - certs:/etc/nginx/certs - - html:/usr/share/nginx/html - - vhost:/etc/nginx/vhost.d - - acme:/etc/acme.sh - depends_on: - - nginx-proxy - -volumes: - static_volume: - media_volume: - certs: - html: - vhost: - acme: \ No newline at end of file diff --git a/compose.yaml b/compose.yaml deleted file mode 100644 index ddaa801..0000000 --- a/compose.yaml +++ /dev/null @@ -1,12 +0,0 @@ -version: '3.8' - -services: - web: - build: ./wedding_site - command: python manage.py runserver 0.0.0.0:8000 - volumes: - - ./wedding_site/:/usr/src/app/ - ports: - - 8000:8000 - env_file: - - ./.env.dev \ No newline at end of file diff --git a/infra/install_arch_deps.sh b/infra/install_arch_deps.sh deleted file mode 100644 index 8937870..0000000 --- a/infra/install_arch_deps.sh +++ /dev/null @@ -1 +0,0 @@ -pacman -Sy podman aardvark-dns \ No newline at end of file diff --git a/nginx/Dockerfile b/nginx/Dockerfile deleted file mode 100644 index 98aa030..0000000 --- a/nginx/Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM docker.io/nginxproxy/nginx-proxy - -COPY vhost.d/default /etc/nginx/vhost.d/default -COPY custom.conf /etc/nginx/conf.d/custom.conf \ No newline at end of file diff --git a/nginx/custom.conf b/nginx/custom.conf deleted file mode 100644 index e9a5e8e..0000000 --- a/nginx/custom.conf +++ /dev/null @@ -1 +0,0 @@ -client_max_body_size 100M; \ No newline at end of file diff --git a/nginx/vhost.d/default b/nginx/vhost.d/default deleted file mode 100644 index bd8fd4d..0000000 --- a/nginx/vhost.d/default +++ /dev/null @@ -1,9 +0,0 @@ -location /static/ { - alias /staticfiles/; - add_header Access-Control-Allow-Origin *; -} - -location /media/ { - alias /mediafiles/; - add_header Access-Control-Allow-Origin *; -} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index e7584bd..2e2e3ab 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,4 @@ -podman-compose \ No newline at end of file +django +markdown +pillow +beautifulsoup4 diff --git a/wedding_site/Dockerfile b/wedding_site/Dockerfile deleted file mode 100644 index 0b84079..0000000 --- a/wedding_site/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -# pull official base image -FROM python:3.11.4-slim-buster - -# set environment variables -ENV PYTHONDONTWRITEBYTECODE 1 -ENV PYTHONUNBUFFERED 1 - -# install dependencies -RUN pip install --upgrade pip -COPY ./requirements.txt . -RUN pip install -r requirements.txt - -RUN mkdir staticfiles -RUN mkdir mediafiles - -ADD ./mediafiles /mediafiles - -# copy project -COPY . . \ No newline at end of file diff --git a/wedding_site/primary/migrations/0010_page_prority.py b/wedding_site/primary/migrations/0010_page_prority.py deleted file mode 100644 index 01223ed..0000000 --- a/wedding_site/primary/migrations/0010_page_prority.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 5.0.2 on 2024-02-18 09:58 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('primary', '0009_page_pretty_name'), - ] - - operations = [ - migrations.AddField( - model_name='page', - name='prority', - field=models.IntegerField(default=0), - ), - ] diff --git a/wedding_site/primary/migrations/0011_rename_prority_page_priority.py b/wedding_site/primary/migrations/0011_rename_prority_page_priority.py deleted file mode 100644 index 42ac5dd..0000000 --- a/wedding_site/primary/migrations/0011_rename_prority_page_priority.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 5.0.2 on 2024-02-18 10:02 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('primary', '0010_page_prority'), - ] - - operations = [ - migrations.RenameField( - model_name='page', - old_name='prority', - new_name='priority', - ), - ] diff --git a/wedding_site/primary/models.py b/wedding_site/primary/models.py index ac7603e..a73c009 100644 --- a/wedding_site/primary/models.py +++ b/wedding_site/primary/models.py @@ -18,7 +18,6 @@ class Page(models.Model): pretty_name = models.CharField(max_length=200, default="") published = models.BooleanField(default=False) navigable = models.BooleanField(default=False) - priority = models.IntegerField(default=0) def __str__(self): return self.name diff --git a/wedding_site/primary/static/primary/favicon.ico b/wedding_site/primary/static/primary/favicon.ico deleted file mode 100755 index 115ea84..0000000 Binary files a/wedding_site/primary/static/primary/favicon.ico and /dev/null differ diff --git a/wedding_site/primary/static/primary/style.css b/wedding_site/primary/static/primary/style.css index b1383e3..8384158 100755 --- a/wedding_site/primary/static/primary/style.css +++ b/wedding_site/primary/static/primary/style.css @@ -33,9 +33,9 @@ body { img { margin:0 auto; + width: 100%; display: flex; justify-content: center; - max-width:100%; max-height:300px; border-radius: 8px; box-shadow: 0 4px 8px 0; @@ -107,10 +107,6 @@ ul { list-style-position: inside; } -ul li { - padding: 5px 0px; -} - .login-input{ margin-top: 30px; text-align: center; @@ -147,7 +143,7 @@ input[type=submit] { margin-top: 30px; text-align: center; font-size: 20px; - width: 75%; + width: 50%; margin:0 auto; font-family: GlacialIndifference; } diff --git a/wedding_site/primary/templates/header.html b/wedding_site/primary/templates/header.html index 32bb550..6574036 100644 --- a/wedding_site/primary/templates/header.html +++ b/wedding_site/primary/templates/header.html @@ -3,5 +3,4 @@ content="width=device-width, initial-scale=1"> {% load static %} - \ No newline at end of file diff --git a/wedding_site/primary/urls.py b/wedding_site/primary/urls.py index 2fe363b..bb59882 100644 --- a/wedding_site/primary/urls.py +++ b/wedding_site/primary/urls.py @@ -7,7 +7,6 @@ urlpatterns = [ path("", views.index, name="index"), path('login', views.login_view, name="login"), path("home", views.home, name="home"), - path("afters", views.afters, name="afters"), path("schedule", views.schedule, name="schedule"), path("thingstodo", views.things_to_do, name="thingstodo"), path("travel", views.travel, name="travel"), diff --git a/wedding_site/primary/views.py b/wedding_site/primary/views.py index 30ffb5d..f9295ff 100644 --- a/wedding_site/primary/views.py +++ b/wedding_site/primary/views.py @@ -6,8 +6,6 @@ from django.template import Context from django.contrib.auth import authenticate, login from django.contrib.auth.decorators import login_required -from django.views.defaults import page_not_found - import markdown from bs4 import BeautifulSoup @@ -26,17 +24,6 @@ _TEMPLATE = """ """ -def handler404(request, exception, template_name="404.html"): - page_names = ["home", "schedule", "thingstodo", "afters"] - working_path = request.path.lower() - if working_path and working_path[0] == "/": - working_path = working_path[1:] - if working_path and working_path[-1] == "/": - working_path = working_path[:-1] - if working_path in page_names: - return redirect(working_path) - return page_not_found(request, exception, template_name) - def get_site_header(site): template = Template(site.header) context = Context({"site": site}) @@ -59,11 +46,8 @@ def index(request): return HttpResponse(soup.prettify()) def login_view(request): - if request.method == "GET": - token = request.GET["token"] - else: - token = request.POST["token"] - user = authenticate(request, username="guest", password=token.lower()) + token = request.POST["token"] + user = authenticate(request, username="guest", password=token) if user is not None: login(request, user) return redirect("home") @@ -74,13 +58,9 @@ def login_view(request): def home(request): return get_page("Home") -@login_required(login_url="/") -def afters(request): - return get_page("Afters") - def get_page_header(site: Site): - pages = site.page_set.order_by("priority").filter(navigable=True) + pages = site.page_set.filter(navigable=True) template = Template(site.page_header) context = Context({"pages" : pages}) return template.render(context) @@ -107,8 +87,7 @@ def get_page(name:str): img_name = img["src"] db_images = Image.objects.filter(name=img_name) if db_images: - url = db_images[0].content.url.replace("uploads/","") - img["src"] = url + img["src"] = db_images[0].content.url return HttpResponse(soup.prettify()) diff --git a/wedding_site/requirements.txt b/wedding_site/requirements.txt deleted file mode 100644 index 2666a26..0000000 --- a/wedding_site/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -django -markdown -pillow -beautifulsoup4 -gunicorn \ No newline at end of file diff --git a/wedding_site/wedding_site/settings.py b/wedding_site/wedding_site/settings.py index b9b91cd..c43b4ba 100644 --- a/wedding_site/wedding_site/settings.py +++ b/wedding_site/wedding_site/settings.py @@ -11,7 +11,6 @@ https://docs.djangoproject.com/en/5.0/ref/settings/ """ from pathlib import Path -import os # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -20,15 +19,13 @@ BASE_DIR = Path(__file__).resolve().parent.parent # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/ -SECRET_KEY = os.environ.get("SECRET_KEY") +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-bj9fez3qztt5e2lrzpgh%%nat@w^kn!k@l92l=+#%wm)4)p^5m' -if "DJANGO_DEBUG" in os.environ: - DEBUG = os.environ.get("DJANGO_DEBUG") == 1 -else: - DEBUG=False +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True -if "DJANGO_ALLOWED_HOSTS" in os.environ: - ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS").split(" ") +ALLOWED_HOSTS = [] # Application definition @@ -115,29 +112,12 @@ USE_I18N = True USE_TZ = True -SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") - -if "CSRF_TRUSTED_ORIGINS" in os.environ: - CSRF_TRUSTED_ORIGINS = os.environ.get("CSRF_TRUSTED_ORIGINS").split(" ") - # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/5.0/howto/static-files/ STATIC_URL = 'static/' -if "DJANGO_STATIC_ROOT" in os.environ: - STATIC_ROOT = os.environ.get("DJANGO_STATIC_ROOT") -else: - STATIC_ROOT = BASE_DIR / "staticfiles" - -MEDIA_URL = 'media/' - -if "DJANGO_MEDIA_ROOT" in os.environ: - MEDIA_ROOT = os.environ.get("DJANGO_MEDIA_ROOT") -else: - MEDIA_ROOT = BASE_DIR / "mediafiles" - # Default primary key field type # https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field diff --git a/wedding_site/wedding_site/urls.py b/wedding_site/wedding_site/urls.py index 0b74776..6528297 100644 --- a/wedding_site/wedding_site/urls.py +++ b/wedding_site/wedding_site/urls.py @@ -19,16 +19,7 @@ from django.urls import path, include from django.conf import settings from django.conf.urls.static import static -import os - -if "DJANGO_ADMIN_PATH" in os.environ: - ADMIN_URL = os.environ.get("DJANGO_ADMIN_PATH") + "/" -else: - ADMIN_URL = "admin/" - urlpatterns = [ path("", include('primary.urls')), - path(ADMIN_URL, admin.site.urls), + path('admin/', admin.site.urls), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) - -handler404 = 'primary.views.handler404'