diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..25fd9c2 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,34 @@ +name: Docker + +on: + push: + branches: [ master, develop ] + pull_request: + branches: [ master, develop ] + +jobs: + test: + strategy: + matrix: + dockerfile-suffix: [ + "alt10", "sisyphus", + "buster", "bullseye", "bookworm", "trixie", + "focal", "jammy", "noble" + ] + + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Build image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile.develop.${{ matrix.dockerfile-suffix }} + push: false + load: true + tags: test:latest + - name: Test + run: docker run --rm test:latest diff --git a/Dockerfile.develop b/Dockerfile.develop deleted file mode 100644 index f405c10..0000000 --- a/Dockerfile.develop +++ /dev/null @@ -1,23 +0,0 @@ -FROM python:3.7-stretch - -RUN echo "deb https://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main" > /etc/apt/sources.list.d/pgdg.list -RUN wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - - -RUN apt-get update - -RUN DEBIAN_FRONTEND=noninteractive apt-get install -y postgresql-9.6 - -ENV PATH="/usr/lib/postgresql/9.6/bin:${PATH}" -# take out coverage report from source directory -ENV COVERAGE_FILE="/tmp/qllr.coverage" - -COPY --chown=www-data . /opt/qllr - -WORKDIR /opt/qllr - -RUN python3 -m pip install -r requirements.txt -RUN python3 -m pip install -r requirements_dev.txt - -USER www-data - -CMD ["./scripts/test"] diff --git a/Dockerfile.develop.alt10 b/Dockerfile.develop.alt10 new file mode 100644 index 0000000..677592e --- /dev/null +++ b/Dockerfile.develop.alt10 @@ -0,0 +1,34 @@ +FROM alt:p10 + +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ + python3-module-async-timeout \ + python3-module-cachetools \ + python3-module-jinja2 \ + python3-module-pip \ + python3-module-psycopg2 \ + python3-module-requests \ + python3-module-starlette \ + python3-module-uvicorn \ + && find /var/lib/apt/lists/ -type f -delete + +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y \ + git \ + postgresql15-server \ + python3-modules-sqlite3 \ + && find /var/lib/apt/lists/ -type f -delete + +ENV PATH="/usr/lib/postgresql/15/bin:${PATH}" +# take out coverage report from source directory +ENV COVERAGE_FILE="/tmp/qllr.coverage" + +COPY --chown=apache . /opt/qllr + +WORKDIR /opt/qllr + +RUN python3 -m pip install --no-deps -r requirements.txt +RUN python3 -m pip install -r requirements_dev.txt + +USER apache + +CMD ["./scripts/test"] diff --git a/Dockerfile.develop.bookworm b/Dockerfile.develop.bookworm new file mode 100644 index 0000000..e4233f0 --- /dev/null +++ b/Dockerfile.develop.bookworm @@ -0,0 +1,34 @@ +FROM debian:bookworm + +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ + python3-asyncpg \ + python3-cachetools \ + python3-jinja2 \ + python3-pip \ + python3-psycopg2 \ + python3-requests \ + python3-starlette \ + python3-uvicorn \ + && rm -rf /var/lib/apt/lists/* + +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + git \ + postgresql-15 \ + && rm -rf /var/lib/apt/lists/* + +ENV PATH="/usr/lib/postgresql/15/bin:${PATH}" +# take out coverage report from source directory +ENV COVERAGE_FILE="/tmp/qllr.coverage" +ENV PIP_BREAK_SYSTEM_PACKAGES=1 + +COPY --chown=www-data . /opt/qllr + +WORKDIR /opt/qllr + +RUN python3 -m pip install -r requirements.txt +RUN python3 -m pip install -r requirements_dev.txt + +USER www-data + +CMD ["./scripts/test"] diff --git a/Dockerfile.develop.bullseye b/Dockerfile.develop.bullseye new file mode 100644 index 0000000..91704f0 --- /dev/null +++ b/Dockerfile.develop.bullseye @@ -0,0 +1,33 @@ +FROM debian:bullseye + +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ + python3-asyncpg \ + python3-cachetools \ + python3-jinja2 \ + python3-pip \ + python3-psycopg2 \ + python3-requests \ + python3-starlette \ + python3-uvicorn \ + && rm -rf /var/lib/apt/lists/* + +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + git \ + postgresql-13 \ + && rm -rf /var/lib/apt/lists/* + +ENV PATH="/usr/lib/postgresql/13/bin:${PATH}" +# take out coverage report from source directory +ENV COVERAGE_FILE="/tmp/qllr.coverage" + +COPY --chown=www-data . /opt/qllr + +WORKDIR /opt/qllr + +RUN python3 -m pip install -r requirements.txt +RUN python3 -m pip install -r requirements_dev.txt + +USER www-data + +CMD ["./scripts/test"] diff --git a/Dockerfile.develop.buster b/Dockerfile.develop.buster new file mode 100644 index 0000000..b6c629c --- /dev/null +++ b/Dockerfile.develop.buster @@ -0,0 +1,36 @@ +FROM debian:buster + +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ + python3-asgiref \ + python3-click \ + python3-cachetools \ + python3-h11 \ + python3-idna \ + python3-jinja2 \ + python3-pip \ + python3-psycopg2 \ + python3-requests \ + python3-sniffio \ + python3-typing-extensions \ + && rm -rf /var/lib/apt/lists/* + +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + git \ + postgresql-11 \ + && rm -rf /var/lib/apt/lists/* + +ENV PATH="/usr/lib/postgresql/11/bin:${PATH}" +# take out coverage report from source directory +ENV COVERAGE_FILE="/tmp/qllr.coverage" + +COPY --chown=www-data . /opt/qllr + +WORKDIR /opt/qllr + +RUN python3 -m pip install -r requirements.txt +RUN python3 -m pip install -r requirements_dev.txt + +USER www-data + +CMD ["./scripts/test"] diff --git a/Dockerfile.develop.focal b/Dockerfile.develop.focal new file mode 100644 index 0000000..9d0108c --- /dev/null +++ b/Dockerfile.develop.focal @@ -0,0 +1,35 @@ +FROM ubuntu:focal + +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ + python3-asyncpg \ + python3-cachetools \ + python3-idna \ + python3-jinja2 \ + python3-pip \ + python3-psycopg2 \ + python3-requests \ + python3-sniffio \ + python3-typing-extensions \ + python3-uvicorn \ + && rm -rf /var/lib/apt/lists/* + +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + git \ + postgresql-12 \ + && rm -rf /var/lib/apt/lists/* + +ENV PATH="/usr/lib/postgresql/12/bin:${PATH}" +# take out coverage report from source directory +ENV COVERAGE_FILE="/tmp/qllr.coverage" + +COPY --chown=www-data . /opt/qllr + +WORKDIR /opt/qllr + +RUN python3 -m pip install -r requirements.txt +RUN python3 -m pip install -r requirements_dev.txt + +USER www-data + +CMD ["./scripts/test"] diff --git a/Dockerfile.develop.jammy b/Dockerfile.develop.jammy new file mode 100644 index 0000000..3a90aa5 --- /dev/null +++ b/Dockerfile.develop.jammy @@ -0,0 +1,33 @@ +FROM ubuntu:jammy + +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ + python3-asyncpg \ + python3-cachetools \ + python3-jinja2 \ + python3-pip \ + python3-psycopg2 \ + python3-requests \ + python3-starlette \ + python3-uvicorn \ + && rm -rf /var/lib/apt/lists/* + +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + git \ + postgresql-14 \ + && rm -rf /var/lib/apt/lists/* + +ENV PATH="/usr/lib/postgresql/14/bin:${PATH}" +# take out coverage report from source directory +ENV COVERAGE_FILE="/tmp/qllr.coverage" + +COPY --chown=www-data . /opt/qllr + +WORKDIR /opt/qllr + +RUN python3 -m pip install -r requirements.txt +RUN python3 -m pip install -r requirements_dev.txt + +USER www-data + +CMD ["./scripts/test"] diff --git a/Dockerfile.develop.noble b/Dockerfile.develop.noble new file mode 100644 index 0000000..d9de119 --- /dev/null +++ b/Dockerfile.develop.noble @@ -0,0 +1,34 @@ +FROM ubuntu:noble + +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ + python3-asyncpg \ + python3-cachetools \ + python3-jinja2 \ + python3-pip \ + python3-psycopg2 \ + python3-requests \ + python3-starlette \ + python3-uvicorn \ + && rm -rf /var/lib/apt/lists/* + +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + git \ + postgresql-16 \ + && rm -rf /var/lib/apt/lists/* + +ENV PATH="/usr/lib/postgresql/16/bin:${PATH}" +# take out coverage report from source directory +ENV COVERAGE_FILE="/tmp/qllr.coverage" +ENV PIP_BREAK_SYSTEM_PACKAGES=1 + +COPY --chown=www-data . /opt/qllr + +WORKDIR /opt/qllr + +RUN python3 -m pip install -r requirements.txt +RUN python3 -m pip install -r requirements_dev.txt + +USER www-data + +CMD ["./scripts/test"] diff --git a/Dockerfile.develop.sisyphus b/Dockerfile.develop.sisyphus new file mode 100644 index 0000000..63899d5 --- /dev/null +++ b/Dockerfile.develop.sisyphus @@ -0,0 +1,34 @@ +FROM alt:sisyphus + +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ + python3-module-asyncpg \ + python3-module-cachetools \ + python3-module-jinja2 \ + python3-module-pip \ + python3-module-psycopg2 \ + python3-module-requests \ + python3-module-starlette \ + python3-module-uvicorn \ + && find /var/lib/apt/lists/ -type f -delete + +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y \ + git \ + postgresql15-server \ + python3-modules-sqlite3 \ + && find /var/lib/apt/lists/ -type f -delete + +ENV PATH="/usr/lib/postgresql/15/bin:${PATH}" +# take out coverage report from source directory +ENV COVERAGE_FILE="/tmp/qllr.coverage" + +COPY --chown=apache . /opt/qllr + +WORKDIR /opt/qllr + +RUN python3 -m pip install -r requirements.txt +RUN python3 -m pip install -r requirements_dev.txt + +USER apache + +CMD ["./scripts/test"] diff --git a/Dockerfile.develop.trixie b/Dockerfile.develop.trixie new file mode 100644 index 0000000..3021b79 --- /dev/null +++ b/Dockerfile.develop.trixie @@ -0,0 +1,34 @@ +FROM debian:trixie + +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ + python3-asyncpg \ + python3-cachetools \ + python3-jinja2 \ + python3-pip \ + python3-psycopg2 \ + python3-requests \ + python3-starlette \ + python3-uvicorn \ + && rm -rf /var/lib/apt/lists/* + +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + git \ + postgresql-16 \ + && rm -rf /var/lib/apt/lists/* + +ENV PATH="/usr/lib/postgresql/16/bin:${PATH}" +# take out coverage report from source directory +ENV COVERAGE_FILE="/tmp/qllr.coverage" +ENV PIP_BREAK_SYSTEM_PACKAGES=1 + +COPY --chown=www-data . /opt/qllr + +WORKDIR /opt/qllr + +RUN python3 -m pip install -r requirements.txt +RUN python3 -m pip install -r requirements_dev.txt + +USER www-data + +CMD ["./scripts/test"] diff --git a/Dockerfile.production b/Dockerfile.production index 6170bb4..4051c47 100644 --- a/Dockerfile.production +++ b/Dockerfile.production @@ -1,4 +1,18 @@ -FROM python:3.7-stretch +FROM debian:buster + +RUN apt-get update && apt-get install -y \ + python3-asgiref \ + python3-click \ + python3-cachetools \ + python3-h11 \ + python3-jinja2 \ + python3-idna \ + python3-pip \ + python3-psycopg2 \ + python3-requests \ + python3-sniffio \ + python3-typing-extensions \ + && rm -rf /var/lib/apt/lists/* COPY --chown=www-data . /opt/qllr diff --git a/README.md b/README.md index 7d347e7..aa79e41 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ For feeder: For development: ``` -docker build . -t em92/qllr-dev -f Dockerfile.develop +docker build . -t em92/qllr-dev -f Dockerfile.develop.buster ``` For production: diff --git a/docker-compose.yml b/docker-compose.yml index ed9166f..0f82580 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,9 +5,10 @@ services: context: . dockerfile: Dockerfile.production ports: - - "7081:7081" + - "127.0.0.1:7081:8000" environment: HOST: 0.0.0.0 + PORT: 8000 env_file: - .env depends_on: ["db"] @@ -21,9 +22,11 @@ services: volumes: - ./sql/init.sql:/docker-entrypoint-initdb.d/init.sql - test: + dev: build: context: . - dockerfile: Dockerfile.develop + dockerfile: Dockerfile.develop.buster volumes: - .:/opt/qllr + ports: + - "127.0.0.1:7081:8000" diff --git a/docs/install.md b/docs/install.md index 5340d99..d7c39f3 100644 --- a/docs/install.md +++ b/docs/install.md @@ -2,11 +2,22 @@ ## Installing and configuring QLLR ``` -# base apps -sudo apt-get install python3 python3-pip python3-venv postgresql git - -# psycopg2 build prerequires -sudo apt-get install python3-dev libpq-dev gcc +# dependecies +sudo apt-get install -y + git \ + postgresql + python3-asgiref \ + python3-click \ + python3-cachetools \ + python3-h11 \ + python3-idna \ + python3-jinja2 \ + python3-pip \ + python3-psycopg2 \ + python3-requests \ + python3-sniffio \ + python3-typing-extensions \ + python3-venv # install qllr git clone https://github.com/em92/quakelive-local-ratings @@ -16,6 +27,7 @@ cd ./quakelive-local-ratings python3 -m venv venv source venv/bin/activate +# install other dependencies python3 -m pip install -r requirements.txt ``` diff --git a/qllr/templating.py b/qllr/templating.py index 8162ca6..0266f49 100644 --- a/qllr/templating.py +++ b/qllr/templating.py @@ -1,9 +1,19 @@ import typing from urllib.parse import ParseResult, urlparse -from jinja2 import Undefined, contextfunction, escape +from jinja2 import Undefined from starlette.templating import Jinja2Templates +try: + from jinja2 import contextfunction +except ImportError: # pragma: nocover + from jinja2 import pass_context as contextfunction + +try: + from jinja2 import escape +except ImportError: # pragma: nocover + from markupsafe import escape + def render_ql_nickname(nickname): nickname = str(escape(nickname)) diff --git a/requirements.txt b/requirements.txt index 2fdf1a7..7be9416 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,13 +1,11 @@ -psycopg2==2.9.1; python_version < '3.11' -psycopg2==2.9.9; python_version >= '3.11' +psycopg2<3 trueskill==0.4.4 -starlette==0.27.0; -asyncpg==0.24.0; python_version < '3.11' -asyncpg==0.29.0; python_version >= '3.11' -uvicorn==0.14.0 +starlette +asyncpg +uvicorn requests -Jinja2==2.11.3 -cachetools==3.1.1 +Jinja2 +cachetools -MarkupSafe<2.1 # https://github.com/pallets/jinja/issues/1658 +MarkupSafe<2.1; python_version <= '3.7' # https://github.com/pallets/jinja/issues/1658 diff --git a/tests/test_export_ratings.py b/tests/test_export_ratings.py index 96e55a4..7e8b8b9 100644 --- a/tests/test_export_ratings.py +++ b/tests/test_export_ratings.py @@ -21,7 +21,7 @@ def test_ratings_ad_redirect_bad_format(service): def test_ratings_ad_csv(service): resp = service.get("/export_rating/ad.csv") - assert resp.encoding == "utf-8" + assert resp.encoding.lower() == "utf-8" assert resp.text == read_sample("exported_ratings_ad.csv")