Skip to content

Commit f4bd495

Browse files
authored
feat: Build endpoints for admin and setup WSGI (#9)
- Endpoint for banning and unbanning - Proper WSGI setup in docker compose to actually serve files - Map deletion endpoint - Update readme for the changes to docker-compose - Improve docs for how static and media file serving works with django. - Better container names - Make the upload tests work on OSs that recognize map files as `ini` instead of just `text`. - Beginnings of a make file - Update `tmp_media_root` to stop overwriting the tmp folder path when `MEDIA_ROOT` is an absolute path - Emulate file serving in pytest so that nginx doesn't need to run to run the test suite - Update black and the line-length to match github - Fix ci for changed env vars
1 parent 2ce9b6f commit f4bd495

35 files changed

+643
-178
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,5 @@ cython_debug/
163163
data/
164164

165165
test.bmp
166+
# Photoshop files
167+
image-source/

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
repos:
22
- repo: https://github.com/pre-commit/pre-commit-hooks
3-
rev: v2.3.0
3+
rev: v5.0.0
44
hooks:
55
- id: check-yaml
66
- id: end-of-file-fixer
77
- id: trailing-whitespace
88
- repo: https://github.com/psf/black
9-
rev: 22.6.0
9+
rev: 25.1.0
1010
hooks:
1111
- id: black

Dockerfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ COPY .env /cncnet-map-api/
1010
# Copy files needed for build
1111
COPY requirements.txt /cncnet-map-api
1212
COPY requirements-dev.txt /cncnet-map-api
13-
COPY start.sh /cncnet-map-api
13+
COPY web_entry_point.sh /cncnet-map-api
1414

1515
RUN apt-get update && apt-get install -y liblzo2-dev # Compression library used by westwood.
1616
RUN apt-get install libmagic1 # File type checking.
1717
RUN pip install --upgrade pip
1818
# The cflags are needed to build the lzo library on Apple silicon.
1919
RUN CFLAGS=-I$(brew --prefix)/include LDFLAGS=-L$(brew --prefix)/lib pip install -r ./requirements-dev.txt
2020

21-
RUN chmod +x /cncnet-map-api/start.sh
22-
ENTRYPOINT "/cncnet-map-api/start.sh"
21+
RUN chmod +x /cncnet-map-api/web_entry_point.sh
22+
ENTRYPOINT "/cncnet-map-api/web_entry_point.sh"

Makefile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#desolate:
2+
# POSTGRES_DATA_DIR = $(shell cat .env | grep POSTGRES_DATA_DIR)
3+
4+
serve:
5+
docker compose build django
6+
docker compose up nginx-server
7+
8+
stop:
9+
docker compose stop
10+
11+
test:
12+
docker compose build django
13+
docker compose run test

README.md

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,32 @@ The mascot for the backend API is Kirovy, by [Direct & Dominate](https://www.you
1717

1818
## Frontend devs
1919

20-
Just set up your environment file and run the full docker compose.
20+
Just set up your environment file and run `docker compose up web -d`.
21+
22+
This will launch the database, run the migrations, and start the django web server.
2123

2224
[Example env file](example.env)
2325

2426
## Backend devs
2527

26-
You can use the docker files if you'd like, but Django + docker is known to have issue attaching
27-
to debuggers and hitting breakpoints, so here are the native OS instructions.
28+
You can use docker compose if you'd like, but here are the native OS instructions.
29+
30+
### Linux and Mac
2831

2932
1. Download and install [pyenv](https://github.com/pyenv/pyenv)
33+
> You don't have to use `pyenv` but it makes life much easier when dealing with virtual environments.
3034
2. Install [PostgreSQL](https://www.postgresql.org/) for your system. This is required for Django
3135
- On Mac you can do `brew install postgresql` if you have brew installed.
3236
3. Install LibMagic for [Python Magic](https://github.com/ahupp/python-magic)
33-
- On Mac you can do `brew install libmagic` if you have breq installed.
37+
- On Mac you can do `brew install libmagic` if you have brew installed.
38+
> LibMagic is used for checking file types.
3439
4. Checkout the repository
3540
5. Switch to the repository directory
3641
6. Setup Python
3742
- Install Python 3.12 `pyenv install 3.12` or whatever the latest python is.
3843
- Setup the virtual environments `pyenv virtualenv 3.12 cncnet-map-api`
39-
- Set the virtual enviornment for the directory `pyenv local cncnet-map-api`
40-
7. Setup requirements `pip install -r requirements-dev.txt`
44+
- Set the virtual environment for the directory `pyenv local cncnet-map-api`
45+
7. Install the dev requirements `pip install -r requirements-dev.txt`
4146
- On Apple Silicon you'll need to install lzo with `brew install lzo` then run
4247
`CFLAGS=-I$(brew --prefix)/include LDFLAGS=-L$(brew --prefix)/lib pip install -r requirements-dev.txt`
4348
to get `python-lzo` to install. You shouldn't need to include those flags again unless `python-lzo` updates.
@@ -49,23 +54,37 @@ to debuggers and hitting breakpoints, so here are the native OS instructions.
4954
- If the app doesn't run due to a missing required variable, add said variable to `example.env` because the person
5055
who made the variable forgot to do so.
5156
10. Run the `db` service in `docker-compose`
52-
11. Load your `.env` file into your shell, (you can use `source load_env.sh && read_env`)
57+
11. Load your `.env` file into your shell, (you can use `source load_env.sh && read_env`)<a name="load-shell-env"></a>
5358
then migrate the database `./manage.py migrate`
54-
12. `./manage.py runserver`
59+
12. Run the django server with `./manage.py runserver`
60+
61+
Tests can be run by following [these instructions](#running-tests-backend-devs)
62+
63+
64+
### Windows
65+
66+
Chairman Bing of the Massivesoft corporation strikes again; getting the `LZO` libraries running
67+
natively on Windows is a... less-than-pleasant effort. So use docker instead.
68+
69+
1. Install docker for windows. I have had success with [Rancher Desktop](https://rancherdesktop.io/)
70+
or [Docker Desktop](https://docs.docker.com/desktop/setup/install/windows-install/)
71+
2. After docker is running, switch to your local git repo and run `docker compose up windows-dev -d`.
72+
Make sure the build succeeds.
73+
3. Set `windows-dev` as your python interpreter for whichever editor you use.
5574

56-
You can technically use PyCharm to launch everything via `docker-compose`, but there is some
57-
weird issue with breakpoints not triggering.
75+
> [!TIP]
76+
> In Pycharm you go to `Settings > Project > Python Interpreter > Add Interpreter > Docker Compose`
5877
5978

60-
## Running tests
79+
## Running tests (backend devs)
6180

62-
I **strongly** recommend using PyCharm and the `.env` plugin for running the PyTests.
81+
I strongly recommend using PyCharm (or any other Python IDE with breakpoints) and the `.env` plugin for running the PyTests.
6382
All you need to do is run the database from `docker-compose`, then launch the tests via PyCharm.
6483

6584
**If you want to run the tests via CLI:**
6685

6786
- Make sure your database is running from the docker compose file. `docker-compose start db`
68-
- Make sure your environment variables are setup and loaded to your shell. See [backend dev setup](#backend-devs)
87+
- Make sure your environment variables are setup and loaded to your shell. See [backend dev setup](#load-shell-env)
6988
- Run `DJANGO_SETTINGS_MODULE="kirovy.settings.testing" pytest tests`
7089

7190
Django should automatically run migrations as part of the test startup.

ci.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ POSTGRES_USER=kane
33
POSTGRES_PASSWORD=cidevelopmentpasswordtechnologyofpeace
44
POSTGRES_PORT=5432
55
POSTGRES_DATA_DIR=/data/db/
6-
MEDIA_ROOT=/data/cnc_net_files/
7-
STATIC_ROOT=/data/cnc_net_static/
6+
HOST_MEDIA_ROOT=/data/cnc_net_files/
7+
HOST_STATIC_ROOT=/data/cnc_net_static/
88
POSTGRES_TEST_HOST=db
99
SECRET_KEY=";thetechnologyofpeaceforcidevwork6352722!@#$$#@"
1010
RUN_ENVIRONMENT=ci

docker-compose.yml

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: "3.9"
2-
31
services:
42
db:
53
image: postgres
@@ -14,18 +12,35 @@ services:
1412
ports:
1513
- "127.0.0.1:${POSTGRES_PORT}:${POSTGRES_PORT}"
1614
command: -p ${POSTGRES_PORT}
17-
web:
15+
16+
django:
17+
# Won't serve files on its own. Launch nginx-server to run the whoe app.
1818
build: .
1919
volumes:
2020
- .:/cncnet-map-api
21-
- ${MEDIA_ROOT}:/data/cncnet_files
22-
- ${STATIC_ROOT}:/data/cncnet_static
21+
- ${HOST_MEDIA_ROOT}:/data/cncnet_silo # django will save user-uploaded files here. MEDIA_ROOT
22+
- ${HOST_STATIC_ROOT}:/data/cncnet_static # django will gather static files here. STATIC_ROOT
2323
ports:
2424
- "8000:8000"
2525
env_file:
2626
- .env
2727
depends_on:
2828
- db
29+
30+
nginx-server:
31+
# This is the prod server service.
32+
# `docker compose up nginx -d` will run the whole app.
33+
# nginx proxies requests to django via gunicorn.
34+
image: nginx:latest
35+
volumes:
36+
- ./nginx.conf:/etc/nginx/nginx.conf:ro
37+
- ${HOST_STATIC_ROOT}:/usr/share/nginx/html/static # website static assets.
38+
- ${HOST_MEDIA_ROOT}:/usr/share/nginx/html/silo # website user-uploaded files.
39+
ports:
40+
- "80:80"
41+
depends_on:
42+
- django
43+
2944
test:
3045
build:
3146
context: ./
@@ -40,3 +55,18 @@ services:
4055
- db
4156
command:
4257
- pytest
58+
59+
windows-dev:
60+
# Use this for windows. The LZO libraries are annoying to deal with without using docker.
61+
# Chairman Bing of Massivesoft strikes again.
62+
build:
63+
context: ./
64+
dockerfile: test.DockerFile
65+
volumes:
66+
- .:/cncnet-map-api
67+
env_file:
68+
- .env
69+
environment:
70+
POSTGRES_TEST_HOST: db # Necessary to connect to docker db. Overrides the .env setting.
71+
depends_on:
72+
- db

example.env

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,18 @@ POSTGRES_TEST_HOST=localhost
1919
# Port for postgres
2020
POSTGRES_PORT=5432
2121

22-
# Required. The location where the app data (maps and such) will be saved. The docker volume mounts here
23-
MEDIA_ROOT=./data/cncnet_files/
24-
25-
# Required. The location where static files will be served from.
26-
# Make sure to configure the webserver to serve files from here and run ``./manage.py collectstatic``
27-
STATIC_ROOT=./data/cncnet_static/
22+
# Required. The location where the app data (maps and such) will be saved on the docker host.
23+
# The docker volume mounts here.
24+
# You should have this backed up because it's where user-uploaded files will live.
25+
# nginx and django will serve these files under the url ``/silo/``
26+
HOST_MEDIA_ROOT=./data/cncnet_silo/
27+
28+
# Required. The directory where collected static files will be saved on the docker host.
29+
# The docker volume mounts here.
30+
# ``collectstatic`` will gather all static assets here to be served by nginx.
31+
# Remember to run ``./manage.py collectstatic`` during build so that this directory will be populated.
32+
# nginx and django will serve these files under the url ``/static/``
33+
HOST_STATIC_ROOT=./data/cncnet_static/
2834

2935
# Django debug, never enable on prod
3036
DEBUG=0

kirovy/exceptions/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""
22
All exceptions for our app belong in this package.
33
"""
4+
45
from django.core.exceptions import * # Import django exceptions for use elsewhere.
56
from typing import Optional
67
from django.utils.translation import gettext_lazy as _
@@ -74,3 +75,12 @@ def __init__(
7475
code: Optional[int] = None,
7576
):
7677
super().__init__(game_name_or_slug, detail, code)
78+
79+
80+
class BanException(Exception):
81+
"""Raised when there is an issue during the ban process.
82+
83+
``str(e)`` will be returned to the UI.
84+
"""
85+
86+
pass

kirovy/models/__init__.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1+
import typing
2+
3+
from django.db.models import UUIDField, Model
4+
15
from .cnc_game import CncGame, CncFileExtension
26
from .cnc_map import CncMap, CncMapFile, MapCategory
37
from .cnc_user import CncUser
48
from .file_base import CncNetFileBaseModel
59
from .map_preview import MapPreview
10+
11+
12+
class SupportsBan(typing.Protocol):
13+
def set_ban(self, is_banned: bool, banned_by: CncUser) -> None:
14+
...

0 commit comments

Comments
 (0)