Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
168657bd14 | |||
6d49db5081 | |||
9a6ade0d96 | |||
a6e9b55837 | |||
356f6ad76f | |||
fbdebec6c8 | |||
10fccc17f7 | |||
0cf7b27f89 | |||
0ac2ca73ec | |||
7b67a2f758 | |||
8b86145519 | |||
ac7a8dd90e | |||
6903b7f768 | |||
2e8b8d7330 | |||
b4d5375954 |
26
.gitea/actions/get-build-options/action.yaml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
name: "Get Build Options"
|
||||||
|
description: "Sanitizies and unifies the environment into build options"
|
||||||
|
outputs:
|
||||||
|
short-sha:
|
||||||
|
description: "Shortened hash if the current commit"
|
||||||
|
build-arch:
|
||||||
|
description: "Docker-compatible representation of build arch"
|
||||||
|
build-platform:
|
||||||
|
description: "Docker-compatible representation of build platform"
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: "Compute Build Options"
|
||||||
|
shell: "bash"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
SHORT_SHA="${GITHUB_SHA::8}"
|
||||||
|
BUILD_ARCH="amd64"
|
||||||
|
BUILD_PLATFORM="linux/amd64"
|
||||||
|
if [ "${RUNNER_ARCH}" = "ARM64" ];then
|
||||||
|
BUILD_ARCH="arm64"
|
||||||
|
BUILD_PLATFORM="linux/arm64"
|
||||||
|
fi
|
||||||
|
echo "short-sha=$SHORT_SHA" >> $GITHUB_OUTPUT
|
||||||
|
echo "build-arch=$BUILD_ARCH" >> $GITHUB_OUTPUT
|
||||||
|
echo "build-platform=$BUILD_PLATFORM" >> $GITHUB_OUTPUT
|
17
.gitea/actions/get-run-info/action.yaml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
name: "Get Run Info"
|
||||||
|
description: "Sanitizies and unifies the environment into run info"
|
||||||
|
inputs:
|
||||||
|
compose-project-base:
|
||||||
|
description: "Base for the Compose project"
|
||||||
|
required: true
|
||||||
|
outputs:
|
||||||
|
compose-project:
|
||||||
|
description: "Compose project name"
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: "Compute Run Info"
|
||||||
|
shell: "bash"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
echo "compose-project=${{ inputs.compose-project-base }}-${GITHUB_RUN_NUMBER}" >> $GITHUB_OUTPUT
|
27
.gitea/actions/get-service-version/action.yaml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
name: "Get Run Info"
|
||||||
|
description: "Sanitizies and unifies the environment into run info"
|
||||||
|
inputs:
|
||||||
|
service:
|
||||||
|
description: "The service to work on"
|
||||||
|
required: true
|
||||||
|
outputs:
|
||||||
|
version:
|
||||||
|
description: "Service version"
|
||||||
|
build-number:
|
||||||
|
description: "Build number"
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: "Compute Service Version"
|
||||||
|
shell: "bash"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
if [[ ! -z "${GITHUB_HEAD_REF}" || "${GITHUB_REF_NAME}" = "development" ]]; then
|
||||||
|
VERSION="${GITHUB_SHA::8}"
|
||||||
|
BUILD="${GITHUB_RUN_NUMBER}"
|
||||||
|
else
|
||||||
|
VERSION="v$(grep -Po '(?<=^version\s=\s")[^"]+' services/${{ inputs.service }}/pyproject.toml)"
|
||||||
|
BUILD="01"
|
||||||
|
fi
|
||||||
|
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||||
|
echo "build-number=$BUILD" >> $GITHUB_OUTPUT
|
32
.gitea/actions/setup-k8s/action.yaml
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
name: "Set up k8s"
|
||||||
|
description: "Downloads and installs k8s tools"
|
||||||
|
inputs:
|
||||||
|
arch:
|
||||||
|
description: "Architecture"
|
||||||
|
required: true
|
||||||
|
kubectl-version:
|
||||||
|
description: "kubectl version to install"
|
||||||
|
required: false
|
||||||
|
default: "1.33.4"
|
||||||
|
kustomize-version:
|
||||||
|
description: "kustomize version to install"
|
||||||
|
required: false
|
||||||
|
default: "5.7.1"
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: "Install k8s tools"
|
||||||
|
shell: "bash"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
mkdir -p /opt/k8s/bin /opt/k8s/etc /opt/k8s/src
|
||||||
|
|
||||||
|
wget -O /opt/k8s/src/kubectl "https://nexus.bthlabs.pl/repository/ops-tools/k8s/kubectl-${{ inputs.kubectl-version }}-linux-${{ inputs.arch }}"
|
||||||
|
chmod a+x /opt/k8s/src/kubectl
|
||||||
|
mv /opt/k8s/src/kubectl /opt/k8s/bin
|
||||||
|
|
||||||
|
wget -O /opt/k8s/src/kustomize "https://nexus.bthlabs.pl/repository/ops-tools/k8s/kustomize-${{ inputs.kustomize-version }}-linux-${{ inputs.arch }}"
|
||||||
|
chmod a+x /opt/k8s/src/kustomize
|
||||||
|
mv /opt/k8s/src/kustomize /opt/k8s/bin
|
||||||
|
|
||||||
|
rm -rf /opt/k8s/src/
|
28
.gitea/tools/render-docker-compose-ci.sh
Executable file
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
set +x
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
cat >"./docker-compose-ci-${COMPOSE_PROJECT}.yaml" <<EOF
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/postgres:15.13-${COMPOSE_PROJECT}"
|
||||||
|
|
||||||
|
keycloak:
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/keycloak:22.0.3-${COMPOSE_PROJECT}"
|
||||||
|
|
||||||
|
rabbitmq:
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/rabbitmq:3.10.8-${COMPOSE_PROJECT}"
|
||||||
|
|
||||||
|
apple-ci:
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/apple:ci-${COMPOSE_PROJECT}"
|
||||||
|
|
||||||
|
backend-ci:
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:ci-${COMPOSE_PROJECT}"
|
||||||
|
|
||||||
|
extension-ci:
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/extension:ci-${COMPOSE_PROJECT}"
|
||||||
|
|
||||||
|
packages-ci:
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/packages:ci-${COMPOSE_PROJECT}"
|
||||||
|
EOF
|
|
@ -17,8 +17,24 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout the code"
|
- name: "Checkout the code"
|
||||||
uses: "actions/checkout@v2"
|
uses: "actions/checkout@v2"
|
||||||
|
- name: "Get run info"
|
||||||
|
id: "get-run-info"
|
||||||
|
uses: "./.gitea/actions/get-run-info"
|
||||||
|
with:
|
||||||
|
compose-project-base: "${{ vars.COMPOSE_PROJECT_BASE }}"
|
||||||
|
- name: "Get build options"
|
||||||
|
id: "get-build-options"
|
||||||
|
uses: "./.gitea/actions/get-build-options"
|
||||||
- name: "Set up Docker Buildx"
|
- name: "Set up Docker Buildx"
|
||||||
|
id: "setup-docker-buildx"
|
||||||
uses: "docker/setup-buildx-action@v3"
|
uses: "docker/setup-buildx-action@v3"
|
||||||
|
with:
|
||||||
|
driver: "remote"
|
||||||
|
endpoint: "tcp://builder-01.bthlab:2375"
|
||||||
|
platforms: "linux/amd64"
|
||||||
|
append: |
|
||||||
|
- endpoint: "tcp://builder-mac-01.bthlab:2375"
|
||||||
|
platforms: "linux/arm64"
|
||||||
- name: "Build `postgres` image"
|
- name: "Build `postgres` image"
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
|
@ -26,7 +42,10 @@ jobs:
|
||||||
context: "services/"
|
context: "services/"
|
||||||
push: false
|
push: false
|
||||||
load: true
|
load: true
|
||||||
tags: "docker-hosted.nexus.bthlabs.pl/hotpocket/postgres:15.13-local"
|
tags: "docker-hosted.nexus.bthlabs.pl/hotpocket/postgres:15.13-${{ steps.get-run-info.outputs.compose-project }}"
|
||||||
|
platforms: "${{ steps.get-build-options.outputs.build-platform }}"
|
||||||
|
cache-from: "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket"
|
||||||
|
cache-to: "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket,mode=max"
|
||||||
- name: "Build `keycloak` image"
|
- name: "Build `keycloak` image"
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
|
@ -34,7 +53,10 @@ jobs:
|
||||||
context: "services/"
|
context: "services/"
|
||||||
push: false
|
push: false
|
||||||
load: true
|
load: true
|
||||||
tags: "docker-hosted.nexus.bthlabs.pl/hotpocket/keycloak:22.0.3-local"
|
tags: "docker-hosted.nexus.bthlabs.pl/hotpocket/keycloak:22.0.3-${{ steps.get-run-info.outputs.compose-project }}"
|
||||||
|
platforms: "${{ steps.get-build-options.outputs.build-platform }}"
|
||||||
|
cache-from: "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket"
|
||||||
|
cache-to: "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket,mode=max"
|
||||||
- name: "Build `rabbitmq` image"
|
- name: "Build `rabbitmq` image"
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
|
@ -42,7 +64,10 @@ jobs:
|
||||||
context: "services/"
|
context: "services/"
|
||||||
push: false
|
push: false
|
||||||
load: true
|
load: true
|
||||||
tags: "docker-hosted.nexus.bthlabs.pl/hotpocket/rabbitmq:3.10.8-local"
|
tags: "docker-hosted.nexus.bthlabs.pl/hotpocket/rabbitmq:3.10.8-${{ steps.get-run-info.outputs.compose-project }}"
|
||||||
|
platforms: "${{ steps.get-build-options.outputs.build-platform }}"
|
||||||
|
cache-from: "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket"
|
||||||
|
cache-to: "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket,mode=max"
|
||||||
- name: "Build `backend-ci` image"
|
- name: "Build `backend-ci` image"
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
|
@ -51,7 +76,10 @@ jobs:
|
||||||
target: "ci"
|
target: "ci"
|
||||||
push: false
|
push: false
|
||||||
load: true
|
load: true
|
||||||
tags: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:ci-local"
|
tags: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:ci-${{ steps.get-run-info.outputs.compose-project }}"
|
||||||
|
platforms: "${{ steps.get-build-options.outputs.build-platform }}"
|
||||||
|
cache-from: "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket"
|
||||||
|
cache-to: "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket,mode=max"
|
||||||
- name: "Build `packages-ci` image"
|
- name: "Build `packages-ci` image"
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
|
@ -60,7 +88,10 @@ jobs:
|
||||||
target: "ci"
|
target: "ci"
|
||||||
push: false
|
push: false
|
||||||
load: true
|
load: true
|
||||||
tags: "docker-hosted.nexus.bthlabs.pl/hotpocket/packages:ci-local"
|
tags: "docker-hosted.nexus.bthlabs.pl/hotpocket/packages:ci-${{ steps.get-run-info.outputs.compose-project }}"
|
||||||
|
platforms: "${{ steps.get-build-options.outputs.build-platform }}"
|
||||||
|
cache-from: "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket"
|
||||||
|
cache-to: "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket,mode=max"
|
||||||
- name: "Build `extension-ci` image"
|
- name: "Build `extension-ci` image"
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
|
@ -69,23 +100,91 @@ jobs:
|
||||||
target: "ci"
|
target: "ci"
|
||||||
push: false
|
push: false
|
||||||
load: true
|
load: true
|
||||||
tags: "docker-hosted.nexus.bthlabs.pl/hotpocket/extension:ci-local"
|
tags: "docker-hosted.nexus.bthlabs.pl/hotpocket/extension:ci-${{ steps.get-run-info.outputs.compose-project }}"
|
||||||
|
platforms: "${{ steps.get-build-options.outputs.build-platform }}"
|
||||||
|
cache-from: "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket"
|
||||||
|
cache-to: "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket,mode=max"
|
||||||
|
- name: "Build `apple-ci` image"
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
file: "services/apple/Dockerfile"
|
||||||
|
context: "services/"
|
||||||
|
target: "ci"
|
||||||
|
push: false
|
||||||
|
load: true
|
||||||
|
tags: "docker-hosted.nexus.bthlabs.pl/hotpocket/apple:ci-${{ steps.get-run-info.outputs.compose-project }}"
|
||||||
|
platforms: "${{ steps.get-build-options.outputs.build-platform }}"
|
||||||
|
cache-from: "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket"
|
||||||
|
cache-to: "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket,mode=max"
|
||||||
|
- name: "Prepare the build"
|
||||||
|
id: "prepare"
|
||||||
|
env:
|
||||||
|
COMPOSE_PROJECT: "${{ steps.get-run-info.outputs.compose-project }}"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
./.gitea/tools/render-docker-compose-ci.sh
|
||||||
- name: "Run `backend` checks"
|
- name: "Run `backend` checks"
|
||||||
|
if: "steps.prepare.conclusion == 'success'"
|
||||||
|
env:
|
||||||
|
COMPOSE_PROJECT: "${{ steps.get-run-info.outputs.compose-project }}"
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
docker compose -f docker-compose.yaml -f docker-compose-ci.yaml run --rm backend-ci inv ci
|
docker compose \
|
||||||
|
-p "${COMPOSE_PROJECT}" \
|
||||||
|
-f "docker-compose.yaml" \
|
||||||
|
-f "docker-compose-ci.yaml" \
|
||||||
|
-f "docker-compose-ci-${COMPOSE_PROJECT}.yaml" \
|
||||||
|
run --rm \
|
||||||
|
backend-ci inv ci
|
||||||
- name: "Run `packages` checks"
|
- name: "Run `packages` checks"
|
||||||
if: always()
|
if: "steps.prepare.conclusion == 'success'"
|
||||||
|
env:
|
||||||
|
COMPOSE_PROJECT: "${{ steps.get-run-info.outputs.compose-project }}"
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
docker compose -f docker-compose.yaml -f docker-compose-ci.yaml run --rm packages-ci inv ci
|
docker compose \
|
||||||
|
-p "${COMPOSE_PROJECT}" \
|
||||||
|
-f "docker-compose.yaml" \
|
||||||
|
-f "docker-compose-ci.yaml" \
|
||||||
|
-f "docker-compose-ci-${COMPOSE_PROJECT}.yaml" \
|
||||||
|
run --rm \
|
||||||
|
packages-ci inv ci
|
||||||
- name: "Run `extension` checks"
|
- name: "Run `extension` checks"
|
||||||
if: always()
|
if: "steps.prepare.conclusion == 'success'"
|
||||||
|
env:
|
||||||
|
COMPOSE_PROJECT: "${{ steps.get-run-info.outputs.compose-project }}"
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
docker compose -f docker-compose.yaml -f docker-compose-ci.yaml run --rm extension-ci inv ci
|
docker compose \
|
||||||
|
-p "${COMPOSE_PROJECT}" \
|
||||||
|
-f "docker-compose.yaml" \
|
||||||
|
-f "docker-compose-ci.yaml" \
|
||||||
|
-f "docker-compose-ci-${COMPOSE_PROJECT}.yaml" \
|
||||||
|
run --rm \
|
||||||
|
extension-ci inv ci
|
||||||
|
- name: "Run `apple` checks"
|
||||||
|
if: "steps.prepare.conclusion == 'success'"
|
||||||
|
env:
|
||||||
|
COMPOSE_PROJECT: "${{ steps.get-run-info.outputs.compose-project }}"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
docker compose \
|
||||||
|
-p "${COMPOSE_PROJECT}" \
|
||||||
|
-f "docker-compose.yaml" \
|
||||||
|
-f "docker-compose-ci.yaml" \
|
||||||
|
-f "docker-compose-ci-${COMPOSE_PROJECT}.yaml" \
|
||||||
|
run --rm \
|
||||||
|
apple-ci inv ci
|
||||||
- name: "Clean up"
|
- name: "Clean up"
|
||||||
if: always()
|
if: always()
|
||||||
|
env:
|
||||||
|
COMPOSE_PROJECT: "${{ steps.get-run-info.outputs.compose-project }}"
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
docker compose -f docker-compose.yaml -f docker-compose-ci.yaml down --volumes
|
docker compose \
|
||||||
|
-p "${COMPOSE_PROJECT}" \
|
||||||
|
-f "docker-compose.yaml" \
|
||||||
|
-f "docker-compose-ci.yaml" \
|
||||||
|
-f "docker-compose-ci-${COMPOSE_PROJECT}.yaml" \
|
||||||
|
down --volumes --rmi all || true
|
||||||
|
rm -f "docker-compose-ci-${COMPOSE_PROJECT}.yaml" || true
|
||||||
|
|
163
.gitea/workflows/development.yaml
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
name: "Deploy to development"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "development"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-deployment-images:
|
||||||
|
name: "Build deployment images"
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
steps:
|
||||||
|
- name: "Checkout the code"
|
||||||
|
uses: "actions/checkout@v2"
|
||||||
|
- name: "Get build options"
|
||||||
|
id: "get-build-options"
|
||||||
|
uses: "./.gitea/actions/get-build-options"
|
||||||
|
- name: "Get `backend` version"
|
||||||
|
id: "get-backend-version"
|
||||||
|
uses: "./.gitea/actions/get-service-version"
|
||||||
|
with:
|
||||||
|
service: "backend"
|
||||||
|
- name: "Import Secrets"
|
||||||
|
id: "import-secrets"
|
||||||
|
uses: "hashicorp/vault-action@v2"
|
||||||
|
with:
|
||||||
|
url: "https://vault.bthlabs.pl/"
|
||||||
|
method: "approle"
|
||||||
|
roleId: "${{ secrets.VAULT_ROLE_ID }}"
|
||||||
|
secretId: "${{ secrets.VAULT_SECRET_ID }}"
|
||||||
|
secrets: |
|
||||||
|
gitea/data/docker-hosted.nexus.bthlabs.pl username | DOCKER_USERNAME ;
|
||||||
|
gitea/data/docker-hosted.nexus.bthlabs.pl password | DOCKER_PASSWORD
|
||||||
|
- name: "Set up Docker Buildx"
|
||||||
|
id: "setup-docker-buildx"
|
||||||
|
uses: "docker/setup-buildx-action@v3"
|
||||||
|
with:
|
||||||
|
driver: "remote"
|
||||||
|
endpoint: "tcp://builder-01.bthlab:2375"
|
||||||
|
platforms: "linux/amd64"
|
||||||
|
append: |
|
||||||
|
- endpoint: "tcp://builder-mac-01.bthlab:2375"
|
||||||
|
platforms: "linux/arm64"
|
||||||
|
- name: "Login to Docket Registry"
|
||||||
|
uses: "docker/login-action@v3"
|
||||||
|
with:
|
||||||
|
registry: "docker-hosted.nexus.bthlabs.pl"
|
||||||
|
username: "${{ steps.import-secrets.outputs.DOCKER_USERNAME }}"
|
||||||
|
password: "${{ steps.import-secrets.outputs.DOCKER_PASSWORD }}"
|
||||||
|
- name: "Build `backend-deployment` image"
|
||||||
|
env:
|
||||||
|
SHORT_SHA: "${{ steps.get-build-options.outputs.short-sha }}"
|
||||||
|
VERSION: "${{ steps.get-backend-version.outputs.version }}"
|
||||||
|
BUILD: "${{ steps.get-backend-version.outputs.build-number }}"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
docker buildx build \
|
||||||
|
--cache-from "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket" \
|
||||||
|
--cache-to "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket,mode=max" \
|
||||||
|
--push \
|
||||||
|
--platform linux/amd64,linux/arm64 \
|
||||||
|
--build-arg IMAGE_ID="deployment.${SHORT_SHA}" \
|
||||||
|
-f services/backend/Dockerfile \
|
||||||
|
--target deployment \
|
||||||
|
-t "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-${VERSION}-${BUILD}" \
|
||||||
|
services/
|
||||||
|
- name: "Build `backend-aio` image"
|
||||||
|
env:
|
||||||
|
SHORT_SHA: "${{ steps.get-build-options.outputs.short-sha }}"
|
||||||
|
VERSION: "${{ steps.get-backend-version.outputs.version }}"
|
||||||
|
BUILD: "${{ steps.get-backend-version.outputs.build-number }}"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
docker buildx build \
|
||||||
|
--cache-from "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket" \
|
||||||
|
--cache-to "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket,mode=max" \
|
||||||
|
--push \
|
||||||
|
--platform linux/amd64,linux/arm64 \
|
||||||
|
--build-arg IMAGE_ID="aio.${SHORT_SHA}" \
|
||||||
|
-f services/backend/Dockerfile \
|
||||||
|
--target aio \
|
||||||
|
-t "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:aio-${VERSION}-${BUILD}" \
|
||||||
|
services/
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
name: "Deploy"
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
needs:
|
||||||
|
- "build-deployment-images"
|
||||||
|
env:
|
||||||
|
KUBERNETES_NAMESPACE: "hotpocket-development"
|
||||||
|
KUBERNETES_CLUSTER: "k8s.bthlab"
|
||||||
|
steps:
|
||||||
|
- name: "Checkout the code"
|
||||||
|
uses: "actions/checkout@v2"
|
||||||
|
- name: "Get run info"
|
||||||
|
id: "get-run-info"
|
||||||
|
uses: "./.gitea/actions/get-run-info"
|
||||||
|
with:
|
||||||
|
compose-project-base: "${{ vars.COMPOSE_PROJECT_BASE }}"
|
||||||
|
- name: "Get build options"
|
||||||
|
id: "get-build-options"
|
||||||
|
uses: "./.gitea/actions/get-build-options"
|
||||||
|
- name: "Get `backend` version"
|
||||||
|
id: "get-backend-version"
|
||||||
|
uses: "./.gitea/actions/get-service-version"
|
||||||
|
with:
|
||||||
|
service: "backend"
|
||||||
|
- name: "Setup k8s"
|
||||||
|
uses: "./.gitea/actions/setup-k8s"
|
||||||
|
with:
|
||||||
|
arch: "${{ steps.get-build-options.outputs.build-arch }}"
|
||||||
|
- name: "Import Secrets"
|
||||||
|
id: "import-secrets"
|
||||||
|
uses: "hashicorp/vault-action@v2"
|
||||||
|
with:
|
||||||
|
url: "https://vault.bthlabs.pl/"
|
||||||
|
method: "approle"
|
||||||
|
roleId: "${{ secrets.VAULT_ROLE_ID }}"
|
||||||
|
secretId: "${{ secrets.VAULT_SECRET_ID }}"
|
||||||
|
secrets: |
|
||||||
|
gitea/data/k8s.bthlab config | KUBECONFIG_PAYLOAD
|
||||||
|
- name: "Set up kubeconfig"
|
||||||
|
env:
|
||||||
|
COMPOSE_PROJECT: "${{ steps.get-run-info.outputs.compose-project }}"
|
||||||
|
KUBECONFIG_PAYLOAD: "${{ steps.import-secrets.outputs.KUBECONFIG_PAYLOAD }}"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
|
||||||
|
echo ${KUBECONFIG_PAYLOAD} | base64 -d >"/opt/k8s/etc/kubeconfig"
|
||||||
|
export KUBECONFIG="/opt/k8s/etc/kubeconfig"
|
||||||
|
|
||||||
|
/opt/k8s/bin/kubectl config use-context ${KUBERNETES_CLUSTER}
|
||||||
|
/opt/k8s/bin/kubectl get node
|
||||||
|
- name: "Run `backend` Django migrations"
|
||||||
|
env:
|
||||||
|
COMPOSE_PROJECT: "${{ steps.get-run-info.outputs.compose-project }}"
|
||||||
|
BACKEND_TAG: "deployment-${{ steps.get-backend-version.outputs.version }}-${{ steps.get-backend-version.outputs.build-number }}"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
|
||||||
|
(
|
||||||
|
cd deployment/hotpocket.bthlab ;
|
||||||
|
export KUBECONFIG="/opt/k8s/etc/kubeconfig" ;
|
||||||
|
/opt/k8s/bin/kubectl config use-context ${KUBERNETES_CLUSTER} ;
|
||||||
|
/opt/k8s/bin/kubectl -n ${KUBERNETES_NAMESPACE} set image cronjobs/backend-job-migrations migrations=docker-hosted.nexus.bthlabs.pl/hotpocket/backend:${BACKEND_TAG} ;
|
||||||
|
/opt/k8s/bin/kubectl -n ${KUBERNETES_NAMESPACE} delete jobs --ignore-not-found=true backend-job-migrations ;
|
||||||
|
/opt/k8s/bin/kubectl -n ${KUBERNETES_NAMESPACE} create job backend-job-migrations --from=cronjob/backend-job-migrations ;
|
||||||
|
/opt/k8s/bin/kubectl -n ${KUBERNETES_NAMESPACE} wait --for=condition=complete --timeout=300s job/backend-job-migrations
|
||||||
|
)
|
||||||
|
- name: "Deploy"
|
||||||
|
env:
|
||||||
|
COMPOSE_PROJECT: "${{ steps.get-run-info.outputs.compose-project }}"
|
||||||
|
BACKEND_TAG: "deployment-${{ steps.get-backend-version.outputs.version }}-${{ steps.get-backend-version.outputs.build-number }}"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
(
|
||||||
|
cd deployment/hotpocket.bthlab ;
|
||||||
|
export KUBECONFIG="/opt/k8s/etc/kubeconfig" ;
|
||||||
|
/opt/k8s/bin/kubectl config use-context ${KUBERNETES_CLUSTER} ;
|
||||||
|
/opt/k8s/bin/kustomize edit set image hotpocket-backend=docker-hosted.nexus.bthlabs.pl/hotpocket/backend:${BACKEND_TAG} ;
|
||||||
|
/opt/k8s/bin/kustomize build . | /opt/k8s/bin/kubectl apply -f -
|
||||||
|
)
|
2
.gitignore
vendored
|
@ -1,2 +1,4 @@
|
||||||
|
.ci/
|
||||||
.envrc*
|
.envrc*
|
||||||
.ipythonhome/
|
.ipythonhome/
|
||||||
|
/docker-compose-ci-*.yaml
|
||||||
|
|
|
@ -86,3 +86,9 @@ Licensed under terms of the MIT License
|
||||||
Pepper Hot Solid icon
|
Pepper Hot Solid icon
|
||||||
Copyright (c) Icons8
|
Copyright (c) Icons8
|
||||||
Licensed under terms of the MIT License
|
Licensed under terms of the MIT License
|
||||||
|
|
||||||
|
Spinner Loader CSS from https://css-loaders.com/
|
||||||
|
|
||||||
|
cosmo, sandstone, sketchy and solar Bootswatch Themes
|
||||||
|
Copyright 2012-2025 Thomas Park
|
||||||
|
Licensed under terms of the MIT License
|
||||||
|
|
|
@ -66,7 +66,7 @@ $ docker run --rm -it \
|
||||||
-e HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME=hotpocket \
|
-e HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME=hotpocket \
|
||||||
-e HOTPOCKET_BACKEND_INITIAL_ACCOUNT_PASSWORD=hotpocketm4st3r \
|
-e HOTPOCKET_BACKEND_INITIAL_ACCOUNT_PASSWORD=hotpocketm4st3r \
|
||||||
-p 8000:8000 \
|
-p 8000:8000 \
|
||||||
docker-hosted.nexus.bthlabs.pl/hotpocket/backend:aio-v25.10.4-01
|
docker-hosted.nexus.bthlabs.pl/hotpocket/backend:aio-v25.10.21-01
|
||||||
```
|
```
|
||||||
|
|
||||||
The command above will set up and start the application. The SQLite file will
|
The command above will set up and start the application. The SQLite file will
|
||||||
|
@ -76,8 +76,7 @@ credentials. The Web app will be reachable at `http://127.0.0.1:8000/`.
|
||||||
The admin will be reachable at `http://127.0.0.1:8000/admin/`.
|
The admin will be reachable at `http://127.0.0.1:8000/admin/`.
|
||||||
|
|
||||||
The `DJANGO_SETTINGS_MODULE` environment variable defaults to
|
The `DJANGO_SETTINGS_MODULE` environment variable defaults to
|
||||||
`hotpocket_backend.settings.deployment.webapp`. This should be set to
|
`hotpocket_backend.settings.deployment.aio`.
|
||||||
`hotpocket_backend.settings.deployment.admin` in the Admin container.
|
|
||||||
|
|
||||||
**NOTE:** The command above specifies wildly insecure `SECRET_KEY` which is
|
**NOTE:** The command above specifies wildly insecure `SECRET_KEY` which is
|
||||||
used among other things to secure the session cookie. Please *please*
|
used among other things to secure the session cookie. Please *please*
|
||||||
|
@ -94,7 +93,8 @@ backend etc. The final deployment will require services for at least the Web
|
||||||
app, the Celery worker and Celery Beat. Admin is optional.
|
app, the Celery worker and Celery Beat. Admin is optional.
|
||||||
|
|
||||||
The `DJANGO_SETTINGS_MODULE` environment variable defaults to
|
The `DJANGO_SETTINGS_MODULE` environment variable defaults to
|
||||||
`hotpocket_backend.settings.deployment.aio`.
|
`hotpocket_backend.settings.deployment.webapp`. This should be set to
|
||||||
|
`hotpocket_backend.settings.deployment.admin` in the Admin container.
|
||||||
|
|
||||||
The `deployment/fullstack/docker-compose.yaml` file can be used as a
|
The `deployment/fullstack/docker-compose.yaml` file can be used as a
|
||||||
starting point for full-stack deployments.
|
starting point for full-stack deployments.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
services:
|
services:
|
||||||
backend:
|
backend:
|
||||||
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:aio-v25.10.4-01"
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:aio-v25.10.21-01"
|
||||||
environment:
|
environment:
|
||||||
HOTPOCKET_BACKEND_SECRET_KEY: "thisisntright"
|
HOTPOCKET_BACKEND_SECRET_KEY: "thisisntright"
|
||||||
HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME: "hotpocket"
|
HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME: "hotpocket"
|
||||||
|
|
|
@ -8,7 +8,7 @@ x-backend-environment: &x-backend-environment
|
||||||
|
|
||||||
services:
|
services:
|
||||||
webapp:
|
webapp:
|
||||||
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v25.10.4-01"
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v25.10.21-01"
|
||||||
environment:
|
environment:
|
||||||
<<: *x-backend-environment
|
<<: *x-backend-environment
|
||||||
HOTPOCKET_BACKEND_ALLOWED_HOSTS: "app.staging.hotpocket.bthlab.bthlabs.net"
|
HOTPOCKET_BACKEND_ALLOWED_HOSTS: "app.staging.hotpocket.bthlab.bthlabs.net"
|
||||||
|
@ -21,7 +21,7 @@ services:
|
||||||
restart: "unless-stopped"
|
restart: "unless-stopped"
|
||||||
|
|
||||||
admin:
|
admin:
|
||||||
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v25.10.4-01"
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v25.10.21-01"
|
||||||
environment:
|
environment:
|
||||||
<<: *x-backend-environment
|
<<: *x-backend-environment
|
||||||
HOTPOCKET_BACKEND_APP: "admin"
|
HOTPOCKET_BACKEND_APP: "admin"
|
||||||
|
@ -35,7 +35,7 @@ services:
|
||||||
restart: "unless-stopped"
|
restart: "unless-stopped"
|
||||||
|
|
||||||
celery-worker:
|
celery-worker:
|
||||||
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v25.10.4-01"
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v25.10.21-01"
|
||||||
command:
|
command:
|
||||||
- "/srv/venv/bin/celery"
|
- "/srv/venv/bin/celery"
|
||||||
- "-A"
|
- "-A"
|
||||||
|
@ -57,7 +57,7 @@ services:
|
||||||
restart: "unless-stopped"
|
restart: "unless-stopped"
|
||||||
|
|
||||||
celery-beat:
|
celery-beat:
|
||||||
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v25.10.4-01"
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v25.10.21-01"
|
||||||
command:
|
command:
|
||||||
- "/srv/venv/bin/celery"
|
- "/srv/venv/bin/celery"
|
||||||
- "-A"
|
- "-A"
|
||||||
|
|
5
deployment/hotpocket.bthlab/configs/backend/admin
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
DJANGO_SETTINGS_MODULE=hotpocket_backend.settings.deployment.admin
|
||||||
|
HOTPOCKET_BACKEND_GUNICORN_WORKERS=2
|
||||||
|
HOTPOCKET_BACKEND_APP=admin
|
||||||
|
HOTPOCKET_BACKEND_SECRET_KEY=thisissecret
|
||||||
|
HOTPOCKET_BACKEND_ALLOWED_HOSTS=thisissecret
|
8
deployment/hotpocket.bthlab/configs/backend/base
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
HOTPOCKET_BACKEND_ENV=deployment
|
||||||
|
HOTPOCKET_BACKEND_DATABASE_NAME=hotpocket_development_backend
|
||||||
|
HOTPOCKET_BACKEND_DATABASE_USER=thisissecret
|
||||||
|
HOTPOCKET_BACKEND_DATABASE_PASSWORD=thisissecret
|
||||||
|
HOTPOCKET_BACKEND_DATABASE_HOST=databases.bthlab
|
||||||
|
HOTPOCKET_BACKEND_CELERY_BROKER_URL=thisissecret
|
||||||
|
HOTPOCKET_BACKEND_CELERY_RESULT_BACKEND=thisissecret
|
||||||
|
HOTPOCKET_BACKEND_MODEL_AUTH_IS_DISABLED=false
|
7
deployment/hotpocket.bthlab/configs/backend/webapp
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
DJANGO_SETTINGS_MODULE=hotpocket_backend.settings.deployment.webapp
|
||||||
|
HOTPOCKET_BACKEND_GUNICORN_WORKERS=2
|
||||||
|
HOTPOCKET_BACKEND_APP=webapp
|
||||||
|
HOTPOCKET_BACKEND_SECRET_KEY=thisissecret
|
||||||
|
HOTPOCKET_BACKEND_ALLOWED_HOSTS=thisissecret
|
||||||
|
HOTPOCKET_BACKEND_SAVES_SAVE_ADAPTER=hotpocket_backend.apps.saves.adapters.postgres:PostgresSaveAdapter
|
||||||
|
HOTPOCKET_BACKEND_SAVES_ASSOCIATION_ADAPTER=hotpocket_backend.apps.saves.adapters.postgres:PostgresAssociationAdapter
|
39
deployment/hotpocket.bthlab/kustomization.yaml
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
|
||||||
|
resources:
|
||||||
|
- resources/namespace.yaml
|
||||||
|
- resources/volumes.yaml
|
||||||
|
- resources/backend/job-migrations.yaml
|
||||||
|
- resources/backend/webapp.yaml
|
||||||
|
- resources/backend/webapp-service.yaml
|
||||||
|
- resources/backend/webapp-ingress.yaml
|
||||||
|
- resources/backend/admin.yaml
|
||||||
|
- resources/backend/admin-service.yaml
|
||||||
|
- resources/backend/admin-ingress.yaml
|
||||||
|
- resources/backend/celery-worker.yaml
|
||||||
|
- resources/backend/celery-beat.yaml
|
||||||
|
|
||||||
|
configMapGenerator:
|
||||||
|
- behavior: create
|
||||||
|
namespace: hotpocket-development
|
||||||
|
envs:
|
||||||
|
- configs/backend/base
|
||||||
|
name: backend-base-config
|
||||||
|
- behavior: create
|
||||||
|
namespace: hotpocket-development
|
||||||
|
envs:
|
||||||
|
- configs/backend/webapp
|
||||||
|
name: backend-webapp-config
|
||||||
|
- behavior: create
|
||||||
|
namespace: hotpocket-development
|
||||||
|
envs:
|
||||||
|
- configs/backend/admin
|
||||||
|
name: backend-admin-config
|
||||||
|
|
||||||
|
patches: []
|
||||||
|
|
||||||
|
images:
|
||||||
|
- name: hotpocket-backend
|
||||||
|
newName: docker-hosted.nexus.bthlabs.pl/hotpocket/backend
|
||||||
|
newTag: deployment-v25.10.4-01
|
|
@ -0,0 +1,19 @@
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: backend-admin-ingress
|
||||||
|
namespace: hotpocket-development
|
||||||
|
annotations:
|
||||||
|
traefik.ingress.kubernetes.io/router.entrypoints: "web"
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- host: admin.hotpocket.bthlab.bthlabs.net
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: backend-admin-service
|
||||||
|
port:
|
||||||
|
name: http
|
|
@ -0,0 +1,14 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: backend-admin-service
|
||||||
|
namespace: hotpocket-development
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/app: backend-admin
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
protocol: TCP
|
||||||
|
port: 8000
|
||||||
|
targetPort: http
|
101
deployment/hotpocket.bthlab/resources/backend/admin.yaml
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: backend-admin
|
||||||
|
namespace: hotpocket-development
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/app: backend-admin
|
||||||
|
spec:
|
||||||
|
minReadySeconds: 30
|
||||||
|
progressDeadlineSeconds: 600
|
||||||
|
replicas: 1
|
||||||
|
revisionHistoryLimit: 1
|
||||||
|
strategy:
|
||||||
|
rollingUpdate:
|
||||||
|
maxSurge: 1
|
||||||
|
maxUnavailable: 1
|
||||||
|
type: RollingUpdate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/app: backend-admin
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/app: backend-admin
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: app
|
||||||
|
image: hotpocket-backend:latest
|
||||||
|
command:
|
||||||
|
- "/srv/venv/bin/gunicorn"
|
||||||
|
- "-c"
|
||||||
|
- "/srv/lib/gunicorn.conf.py"
|
||||||
|
- "hotpocket_backend.wsgi:application"
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: backend-base-config
|
||||||
|
- configMapRef:
|
||||||
|
name: backend-admin-config
|
||||||
|
env:
|
||||||
|
- name: HOTPOCKET_BACKEND_SECRET_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-admin
|
||||||
|
key: secret_key
|
||||||
|
- name: HOTPOCKET_BACKEND_ALLOWED_HOSTS
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-admin
|
||||||
|
key: allowed_hosts
|
||||||
|
- name: HOTPOCKET_BACKEND_DATABASE_USER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-postgres
|
||||||
|
key: username
|
||||||
|
- name: HOTPOCKET_BACKEND_DATABASE_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-postgres
|
||||||
|
key: password
|
||||||
|
- name: HOTPOCKET_BACKEND_CELERY_BROKER_URL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-celery
|
||||||
|
key: broker_url
|
||||||
|
- name: HOTPOCKET_BACKEND_CELERY_RESULT_BACKEND
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-celery
|
||||||
|
key: result_backend
|
||||||
|
ports:
|
||||||
|
- containerPort: 8000
|
||||||
|
name: http
|
||||||
|
protocol: TCP
|
||||||
|
- containerPort: 8001
|
||||||
|
name: healthcheck
|
||||||
|
protocol: TCP
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: "/"
|
||||||
|
port: 8001
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 10
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: "/"
|
||||||
|
port: 8001
|
||||||
|
initialDelaySeconds: 2
|
||||||
|
periodSeconds: 5
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /dev/shm
|
||||||
|
name: shm
|
||||||
|
- mountPath: /srv/run
|
||||||
|
name: backend-admin-srv-run
|
||||||
|
dnsPolicy: ClusterFirst
|
||||||
|
restartPolicy: Always
|
||||||
|
volumes:
|
||||||
|
- name: shm
|
||||||
|
emptyDir:
|
||||||
|
medium: Memory
|
||||||
|
- name: backend-admin-srv-run
|
||||||
|
emptyDir: {}
|
|
@ -0,0 +1,85 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: backend-celery-beat
|
||||||
|
namespace: hotpocket-development
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/app: backend-celery-beat
|
||||||
|
spec:
|
||||||
|
minReadySeconds: 30
|
||||||
|
replicas: 1
|
||||||
|
revisionHistoryLimit: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/app: backend-celery-beat
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/app: backend-celery-beat
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: app
|
||||||
|
image: hotpocket-backend:latest
|
||||||
|
command:
|
||||||
|
- "/srv/venv/bin/celery"
|
||||||
|
- "-A"
|
||||||
|
- "hotpocket_backend.celery:app"
|
||||||
|
- "beat"
|
||||||
|
- "-l"
|
||||||
|
- "INFO"
|
||||||
|
- "-s"
|
||||||
|
- "/srv/run/celery-beat-schedule"
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: backend-base-config
|
||||||
|
- configMapRef:
|
||||||
|
name: backend-webapp-config
|
||||||
|
env:
|
||||||
|
- name: HOTPOCKET_BACKEND_SECRET_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-webapp
|
||||||
|
key: secret_key
|
||||||
|
- name: HOTPOCKET_BACKEND_ALLOWED_HOSTS
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-webapp
|
||||||
|
key: allowed_hosts
|
||||||
|
- name: HOTPOCKET_BACKEND_DATABASE_USER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-postgres
|
||||||
|
key: username
|
||||||
|
- name: HOTPOCKET_BACKEND_DATABASE_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-postgres
|
||||||
|
key: password
|
||||||
|
- name: HOTPOCKET_BACKEND_CELERY_BROKER_URL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-celery
|
||||||
|
key: broker_url
|
||||||
|
- name: HOTPOCKET_BACKEND_CELERY_RESULT_BACKEND
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-celery
|
||||||
|
key: result_backend
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /dev/shm
|
||||||
|
name: shm
|
||||||
|
- mountPath: /srv/run
|
||||||
|
name: backend-celery-beat-srv-run
|
||||||
|
- mountPath: /srv/uploads
|
||||||
|
name: backend-celery-beat-srv-uploads
|
||||||
|
dnsPolicy: ClusterFirst
|
||||||
|
restartPolicy: Always
|
||||||
|
volumes:
|
||||||
|
- name: shm
|
||||||
|
emptyDir:
|
||||||
|
medium: Memory
|
||||||
|
- name: backend-celery-beat-srv-run
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: backend-celery-beat-run
|
||||||
|
- name: backend-celery-beat-srv-uploads
|
||||||
|
emptyDir: {}
|
|
@ -0,0 +1,93 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: backend-celery-worker
|
||||||
|
namespace: hotpocket-development
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/app: backend-celery-worker
|
||||||
|
spec:
|
||||||
|
minReadySeconds: 30
|
||||||
|
progressDeadlineSeconds: 600
|
||||||
|
replicas: 1
|
||||||
|
revisionHistoryLimit: 1
|
||||||
|
strategy:
|
||||||
|
rollingUpdate:
|
||||||
|
maxSurge: 1
|
||||||
|
maxUnavailable: 1
|
||||||
|
type: RollingUpdate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/app: backend-celery-worker
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/app: backend-celery-worker
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: app
|
||||||
|
image: hotpocket-backend:latest
|
||||||
|
command:
|
||||||
|
- "/srv/venv/bin/celery"
|
||||||
|
- "-A"
|
||||||
|
- "hotpocket_backend.celery:app"
|
||||||
|
- "worker"
|
||||||
|
- "-l"
|
||||||
|
- "INFO"
|
||||||
|
- "-Q"
|
||||||
|
- "celery,webapp"
|
||||||
|
- "-c"
|
||||||
|
- "2"
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: backend-base-config
|
||||||
|
- configMapRef:
|
||||||
|
name: backend-webapp-config
|
||||||
|
env:
|
||||||
|
- name: HOTPOCKET_BACKEND_SECRET_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-webapp
|
||||||
|
key: secret_key
|
||||||
|
- name: HOTPOCKET_BACKEND_ALLOWED_HOSTS
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-webapp
|
||||||
|
key: allowed_hosts
|
||||||
|
- name: HOTPOCKET_BACKEND_DATABASE_USER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-postgres
|
||||||
|
key: username
|
||||||
|
- name: HOTPOCKET_BACKEND_DATABASE_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-postgres
|
||||||
|
key: password
|
||||||
|
- name: HOTPOCKET_BACKEND_CELERY_BROKER_URL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-celery
|
||||||
|
key: broker_url
|
||||||
|
- name: HOTPOCKET_BACKEND_CELERY_RESULT_BACKEND
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-celery
|
||||||
|
key: result_backend
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /dev/shm
|
||||||
|
name: shm
|
||||||
|
- mountPath: /srv/run
|
||||||
|
name: backend-celery-worker-srv-run
|
||||||
|
- mountPath: /srv/uploads
|
||||||
|
name: backend-celery-worker-srv-uploads
|
||||||
|
dnsPolicy: ClusterFirst
|
||||||
|
restartPolicy: Always
|
||||||
|
volumes:
|
||||||
|
- name: shm
|
||||||
|
emptyDir:
|
||||||
|
medium: Memory
|
||||||
|
- name: backend-celery-worker-srv-run
|
||||||
|
emptyDir: {}
|
||||||
|
- name: backend-celery-worker-srv-uploads
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: backend-uploads
|
|
@ -0,0 +1,80 @@
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: CronJob
|
||||||
|
metadata:
|
||||||
|
name: backend-job-migrations
|
||||||
|
namespace: hotpocket-development
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/app: backend-job-migrations
|
||||||
|
spec:
|
||||||
|
concurrencyPolicy: "Forbid"
|
||||||
|
successfulJobsHistoryLimit: 1
|
||||||
|
failedJobsHistoryLimit: 1
|
||||||
|
startingDeadlineSeconds: 180
|
||||||
|
schedule: "* * * * *"
|
||||||
|
suspend: true
|
||||||
|
jobTemplate:
|
||||||
|
spec:
|
||||||
|
backoffLimit: 1
|
||||||
|
completions: 1
|
||||||
|
parallelism: 1
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: migrations
|
||||||
|
image: hotpocket-backend:latest
|
||||||
|
command:
|
||||||
|
- "./manage.py"
|
||||||
|
- "migrate"
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: backend-base-config
|
||||||
|
- configMapRef:
|
||||||
|
name: backend-webapp-config
|
||||||
|
env:
|
||||||
|
- name: HOTPOCKET_BACKEND_SECRET_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-webapp
|
||||||
|
key: secret_key
|
||||||
|
- name: HOTPOCKET_BACKEND_ALLOWED_HOSTS
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-webapp
|
||||||
|
key: allowed_hosts
|
||||||
|
- name: HOTPOCKET_BACKEND_DATABASE_USER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-postgres
|
||||||
|
key: username
|
||||||
|
- name: HOTPOCKET_BACKEND_DATABASE_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-postgres
|
||||||
|
key: password
|
||||||
|
- name: HOTPOCKET_BACKEND_CELERY_BROKER_URL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-celery
|
||||||
|
key: broker_url
|
||||||
|
- name: HOTPOCKET_BACKEND_CELERY_RESULT_BACKEND
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-celery
|
||||||
|
key: result_backend
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /dev/shm
|
||||||
|
name: shm
|
||||||
|
- mountPath: /srv/run
|
||||||
|
name: backend-webapp-srv-run
|
||||||
|
- mountPath: /srv/uploads
|
||||||
|
name: backend-webapp-srv-uploads
|
||||||
|
dnsPolicy: ClusterFirst
|
||||||
|
restartPolicy: Never
|
||||||
|
volumes:
|
||||||
|
- name: shm
|
||||||
|
emptyDir:
|
||||||
|
medium: Memory
|
||||||
|
- name: backend-webapp-srv-run
|
||||||
|
emptyDir: {}
|
||||||
|
- name: backend-webapp-srv-uploads
|
||||||
|
emptyDir: {}
|
|
@ -0,0 +1,19 @@
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: backend-webapp-ingress
|
||||||
|
namespace: hotpocket-development
|
||||||
|
annotations:
|
||||||
|
traefik.ingress.kubernetes.io/router.entrypoints: "web"
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- host: app.hotpocket.bthlab.bthlabs.net
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: backend-webapp-service
|
||||||
|
port:
|
||||||
|
name: http
|
|
@ -0,0 +1,14 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: backend-webapp-service
|
||||||
|
namespace: hotpocket-development
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/app: backend-webapp
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
protocol: TCP
|
||||||
|
port: 8000
|
||||||
|
targetPort: http
|
106
deployment/hotpocket.bthlab/resources/backend/webapp.yaml
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: backend-webapp
|
||||||
|
namespace: hotpocket-development
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/app: backend-webapp
|
||||||
|
spec:
|
||||||
|
minReadySeconds: 30
|
||||||
|
progressDeadlineSeconds: 600
|
||||||
|
replicas: 1
|
||||||
|
revisionHistoryLimit: 1
|
||||||
|
strategy:
|
||||||
|
rollingUpdate:
|
||||||
|
maxSurge: 1
|
||||||
|
maxUnavailable: 1
|
||||||
|
type: RollingUpdate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/app: backend-webapp
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/app: backend-webapp
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: app
|
||||||
|
image: hotpocket-backend:latest
|
||||||
|
command:
|
||||||
|
- "/srv/venv/bin/gunicorn"
|
||||||
|
- "-c"
|
||||||
|
- "/srv/lib/gunicorn.conf.py"
|
||||||
|
- "hotpocket_backend.wsgi:application"
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: backend-base-config
|
||||||
|
- configMapRef:
|
||||||
|
name: backend-webapp-config
|
||||||
|
env:
|
||||||
|
- name: HOTPOCKET_BACKEND_SECRET_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-webapp
|
||||||
|
key: secret_key
|
||||||
|
- name: HOTPOCKET_BACKEND_ALLOWED_HOSTS
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-webapp
|
||||||
|
key: allowed_hosts
|
||||||
|
- name: HOTPOCKET_BACKEND_DATABASE_USER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-postgres
|
||||||
|
key: username
|
||||||
|
- name: HOTPOCKET_BACKEND_DATABASE_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-postgres
|
||||||
|
key: password
|
||||||
|
- name: HOTPOCKET_BACKEND_CELERY_BROKER_URL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-celery
|
||||||
|
key: broker_url
|
||||||
|
- name: HOTPOCKET_BACKEND_CELERY_RESULT_BACKEND
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backend-celery
|
||||||
|
key: result_backend
|
||||||
|
ports:
|
||||||
|
- containerPort: 8000
|
||||||
|
name: http
|
||||||
|
protocol: TCP
|
||||||
|
- containerPort: 8001
|
||||||
|
name: healthcheck
|
||||||
|
protocol: TCP
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: "/"
|
||||||
|
port: 8001
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 10
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: "/"
|
||||||
|
port: 8001
|
||||||
|
initialDelaySeconds: 2
|
||||||
|
periodSeconds: 5
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /dev/shm
|
||||||
|
name: shm
|
||||||
|
- mountPath: /srv/run
|
||||||
|
name: backend-webapp-srv-run
|
||||||
|
- mountPath: /srv/uploads
|
||||||
|
name: backend-webapp-srv-uploads
|
||||||
|
dnsPolicy: ClusterFirst
|
||||||
|
restartPolicy: Always
|
||||||
|
volumes:
|
||||||
|
- name: shm
|
||||||
|
emptyDir:
|
||||||
|
medium: Memory
|
||||||
|
- name: backend-webapp-srv-run
|
||||||
|
emptyDir: {}
|
||||||
|
- name: backend-webapp-srv-uploads
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: backend-uploads
|
4
deployment/hotpocket.bthlab/resources/namespace.yaml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: hotpocket-development
|
26
deployment/hotpocket.bthlab/resources/volumes.yaml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: backend-uploads
|
||||||
|
namespace: hotpocket-development
|
||||||
|
spec:
|
||||||
|
storageClassName: nfs-client
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteMany
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: "1Gi"
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: backend-celery-beat-run
|
||||||
|
namespace: hotpocket-development
|
||||||
|
spec:
|
||||||
|
storageClassName: nfs-client
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteMany
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: "1Gi"
|
|
@ -2,6 +2,7 @@
|
||||||
"group": {
|
"group": {
|
||||||
"default": {
|
"default": {
|
||||||
"targets": [
|
"targets": [
|
||||||
|
"apple-management",
|
||||||
"backend-management",
|
"backend-management",
|
||||||
"caddy",
|
"caddy",
|
||||||
"extension-management",
|
"extension-management",
|
||||||
|
@ -13,6 +14,28 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"target": {
|
"target": {
|
||||||
|
"apple-management": {
|
||||||
|
"context": "services/",
|
||||||
|
"dockerfile": "apple/Dockerfile",
|
||||||
|
"tags": [
|
||||||
|
"docker-hosted.nexus.bthlabs.pl/hotpocket/apple:local"
|
||||||
|
],
|
||||||
|
"target": "development",
|
||||||
|
"output": [
|
||||||
|
"type=docker,load=true,push=false"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"apple-ci": {
|
||||||
|
"context": "services/",
|
||||||
|
"dockerfile": "apple/Dockerfile",
|
||||||
|
"tags": [
|
||||||
|
"docker-hosted.nexus.bthlabs.pl/hotpocket/apple:ci-local"
|
||||||
|
],
|
||||||
|
"target": "ci",
|
||||||
|
"output": [
|
||||||
|
"type=docker,load=true,push=false"
|
||||||
|
]
|
||||||
|
},
|
||||||
"backend-management": {
|
"backend-management": {
|
||||||
"context": "services/",
|
"context": "services/",
|
||||||
"dockerfile": "backend/Dockerfile",
|
"dockerfile": "backend/Dockerfile",
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
ports: []
|
ports: !override []
|
||||||
|
|
||||||
keycloak:
|
keycloak:
|
||||||
command: "echo 'NOOP'"
|
command: "echo 'NOOP'"
|
||||||
ports: []
|
ports: !override []
|
||||||
restart: "no"
|
restart: "no"
|
||||||
|
|
||||||
rabbitmq:
|
rabbitmq:
|
||||||
ports: []
|
ports: !override []
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- path: "./services/backend/docker-compose-ci.yaml"
|
- path: "./services/backend/docker-compose-ci.yaml"
|
||||||
- path: "./services/packages/docker-compose-ci.yaml"
|
- path: "./services/packages/docker-compose-ci.yaml"
|
||||||
- path: "./services/extension/docker-compose-ci.yaml"
|
- path: "./services/extension/docker-compose-ci.yaml"
|
||||||
|
- path: "./services/apple/docker-compose-ci.yaml"
|
||||||
|
|
|
@ -6,6 +6,7 @@ include:
|
||||||
- path: "./services/backend/docker-compose.yaml"
|
- path: "./services/backend/docker-compose.yaml"
|
||||||
- path: "./services/packages/docker-compose.yaml"
|
- path: "./services/packages/docker-compose.yaml"
|
||||||
- path: "./services/extension/docker-compose.yaml"
|
- path: "./services/extension/docker-compose.yaml"
|
||||||
|
- path: "./services/apple/docker-compose.yaml"
|
||||||
|
|
||||||
volumes: {}
|
volumes: {}
|
||||||
|
|
||||||
|
|
16
poetry.lock
generated
|
@ -1,4 +1,4 @@
|
||||||
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
|
# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand.
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hotpocket-workspace-tools"
|
name = "hotpocket-workspace-tools"
|
||||||
|
@ -6,11 +6,12 @@ version = "1.0.0.dev0"
|
||||||
description = "HotPocket Workspace Tools"
|
description = "HotPocket Workspace Tools"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "^3.12"
|
python-versions = "^3.12"
|
||||||
|
groups = ["main"]
|
||||||
files = []
|
files = []
|
||||||
develop = true
|
develop = true
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
invoke = "2.2.0"
|
invoke = "2.2.1"
|
||||||
|
|
||||||
[package.source]
|
[package.source]
|
||||||
type = "directory"
|
type = "directory"
|
||||||
|
@ -18,16 +19,17 @@ url = "services/packages/workspace_tools"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "invoke"
|
name = "invoke"
|
||||||
version = "2.2.0"
|
version = "2.2.1"
|
||||||
description = "Pythonic task execution"
|
description = "Pythonic task execution"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
|
groups = ["main"]
|
||||||
files = [
|
files = [
|
||||||
{file = "invoke-2.2.0-py3-none-any.whl", hash = "sha256:6ea924cc53d4f78e3d98bc436b08069a03077e6f85ad1ddaa8a116d7dad15820"},
|
{file = "invoke-2.2.1-py3-none-any.whl", hash = "sha256:2413bc441b376e5cd3f55bb5d364f973ad8bdd7bf87e53c79de3c11bf3feecc8"},
|
||||||
{file = "invoke-2.2.0.tar.gz", hash = "sha256:ee6cbb101af1a859c7fe84f2a264c059020b0cb7fe3535f9424300ab568f6bd5"},
|
{file = "invoke-2.2.1.tar.gz", hash = "sha256:515bf49b4a48932b79b024590348da22f39c4942dff991ad1fb8b8baea1be707"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.1"
|
||||||
python-versions = "^3.12"
|
python-versions = "^3.12"
|
||||||
content-hash = "ec33c3b3ec0f988e333872bdd134c1adce0782e98512dd2484cb85009b3da6cb"
|
content-hash = "a7028d4a0260c82012077d9cc4b324b0ef5ab8ed24aa283a51cf941ba09685a9"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "hotpocket-workspace"
|
name = "hotpocket-workspace"
|
||||||
version = "25.10.4"
|
version = "25.10.21"
|
||||||
description = "HotPocket Workspace"
|
description = "HotPocket Workspace"
|
||||||
authors = ["Tomek Wójcik <contact@bthlabs.pl>"]
|
authors = ["Tomek Wójcik <contact@bthlabs.pl>"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
@ -9,7 +9,6 @@ package-mode = false
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.12"
|
python = "^3.12"
|
||||||
hotpocket-workspace-tools = {path = "services/packages/workspace_tools", develop = true}
|
hotpocket-workspace-tools = {path = "services/packages/workspace_tools", develop = true}
|
||||||
invoke = "2.2.0"
|
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core"]
|
requires = ["poetry-core"]
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
|
.mypy_cache/
|
||||||
|
.pytest_cache/
|
||||||
_tmp/
|
_tmp/
|
||||||
apple/
|
apple/build/
|
||||||
|
apple/DerivedData/
|
||||||
backend/node_modules/
|
backend/node_modules/
|
||||||
backend/ops/metal/
|
backend/ops/metal/
|
||||||
backend/hotpocket_backend/playground.py
|
backend/hotpocket_backend/playground.py
|
||||||
|
|
19
services/apple/Dockerfile
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
ARG APP_USER_UID=1000
|
||||||
|
ARG APP_USER_GID=1000
|
||||||
|
ARG IMAGE_ID=development.00000000
|
||||||
|
|
||||||
|
FROM docker-hosted.nexus.bthlabs.pl/hotpocket/base:build-node-20251014-01 AS development
|
||||||
|
|
||||||
|
ARG APP_USER_UID
|
||||||
|
ARG APP_USER_GID
|
||||||
|
ARG IMAGE_ID
|
||||||
|
|
||||||
|
# COPY --chown=$APP_USER_UID:$APP_USER_GID apple/ops/bin/*.sh /srv/bin/
|
||||||
|
|
||||||
|
VOLUME ["/srv/node_modules", "/srv/venv"]
|
||||||
|
|
||||||
|
FROM development AS ci
|
||||||
|
|
||||||
|
COPY --chown=$APP_USER_UID:$APP_USER_GID apple/ /srv/app/
|
||||||
|
COPY --chown=$APP_USER_UID:$APP_USER_GID packages/ /srv/packages/
|
||||||
|
COPY --chown=$APP_USER_UID:$APP_USER_GID tls/ /srv/tls/
|
|
@ -713,7 +713,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = "iOS (Share Extension)/iOS (Share Extension).entitlements";
|
CODE_SIGN_ENTITLEMENTS = "iOS (Share Extension)/iOS (Share Extension).entitlements";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 2025100401;
|
CURRENT_PROJECT_VERSION = 2025102101;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = "iOS (Share Extension)/Info.plist";
|
INFOPLIST_FILE = "iOS (Share Extension)/Info.plist";
|
||||||
|
@ -726,7 +726,7 @@
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 25.10.4;
|
MARKETING_VERSION = 25.10.21;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = pl.bthlabs.HotPocket.ShareExtension;
|
PRODUCT_BUNDLE_IDENTIFIER = pl.bthlabs.HotPocket.ShareExtension;
|
||||||
PRODUCT_NAME = "Save to HotPocket";
|
PRODUCT_NAME = "Save to HotPocket";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
@ -746,7 +746,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = "iOS (Share Extension)/iOS (Share Extension).entitlements";
|
CODE_SIGN_ENTITLEMENTS = "iOS (Share Extension)/iOS (Share Extension).entitlements";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 2025100401;
|
CURRENT_PROJECT_VERSION = 2025102101;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = "iOS (Share Extension)/Info.plist";
|
INFOPLIST_FILE = "iOS (Share Extension)/Info.plist";
|
||||||
|
@ -759,7 +759,7 @@
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 25.10.4;
|
MARKETING_VERSION = 25.10.21;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = pl.bthlabs.HotPocket.ShareExtension;
|
PRODUCT_BUNDLE_IDENTIFIER = pl.bthlabs.HotPocket.ShareExtension;
|
||||||
PRODUCT_NAME = "Save to HotPocket";
|
PRODUCT_NAME = "Save to HotPocket";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
@ -779,7 +779,7 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 2025100401;
|
CURRENT_PROJECT_VERSION = 2025102101;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = "iOS (Extension)/Info.plist";
|
INFOPLIST_FILE = "iOS (Extension)/Info.plist";
|
||||||
|
@ -792,7 +792,7 @@
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 25.10.4;
|
MARKETING_VERSION = 25.10.21;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
|
@ -814,7 +814,7 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 2025100401;
|
CURRENT_PROJECT_VERSION = 2025102101;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = "iOS (Extension)/Info.plist";
|
INFOPLIST_FILE = "iOS (Extension)/Info.plist";
|
||||||
|
@ -827,7 +827,7 @@
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 25.10.4;
|
MARKETING_VERSION = 25.10.21;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
|
@ -853,7 +853,7 @@
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_ENTITLEMENTS = "iOS (App)/HotPocket (iOS).entitlements";
|
CODE_SIGN_ENTITLEMENTS = "iOS (App)/HotPocket (iOS).entitlements";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 2025100401;
|
CURRENT_PROJECT_VERSION = 2025102101;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = "iOS (App)/Info.plist";
|
INFOPLIST_FILE = "iOS (App)/Info.plist";
|
||||||
|
@ -873,7 +873,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 25.10.4;
|
MARKETING_VERSION = 25.10.21;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
|
@ -899,7 +899,7 @@
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_ENTITLEMENTS = "iOS (App)/HotPocket (iOS).entitlements";
|
CODE_SIGN_ENTITLEMENTS = "iOS (App)/HotPocket (iOS).entitlements";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 2025100401;
|
CURRENT_PROJECT_VERSION = 2025102101;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = "iOS (App)/Info.plist";
|
INFOPLIST_FILE = "iOS (App)/Info.plist";
|
||||||
|
@ -919,7 +919,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 25.10.4;
|
MARKETING_VERSION = 25.10.21;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
|
@ -945,7 +945,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = "macOS (Extension)/HotPocket.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "macOS (Extension)/HotPocket.entitlements";
|
||||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 2025100401;
|
CURRENT_PROJECT_VERSION = 2025102101;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||||
|
@ -960,7 +960,7 @@
|
||||||
"@executable_path/../../../../Frameworks",
|
"@executable_path/../../../../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
||||||
MARKETING_VERSION = 25.10.4;
|
MARKETING_VERSION = 25.10.21;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
|
@ -980,7 +980,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = "macOS (Extension)/HotPocket.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "macOS (Extension)/HotPocket.entitlements";
|
||||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 2025100401;
|
CURRENT_PROJECT_VERSION = 2025102101;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||||
|
@ -995,7 +995,7 @@
|
||||||
"@executable_path/../../../../Frameworks",
|
"@executable_path/../../../../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
||||||
MARKETING_VERSION = 25.10.4;
|
MARKETING_VERSION = 25.10.21;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
|
@ -1017,7 +1017,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = "macOS (App)/HotPocket.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "macOS (App)/HotPocket.entitlements";
|
||||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 2025100401;
|
CURRENT_PROJECT_VERSION = 2025102101;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
@ -1033,7 +1033,7 @@
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
||||||
MARKETING_VERSION = 25.10.4;
|
MARKETING_VERSION = 25.10.21;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
|
@ -1056,7 +1056,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = "macOS (App)/HotPocket.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "macOS (App)/HotPocket.entitlements";
|
||||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 2025100401;
|
CURRENT_PROJECT_VERSION = 2025102101;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
@ -1072,7 +1072,7 @@
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
||||||
MARKETING_VERSION = 25.10.4;
|
MARKETING_VERSION = 25.10.21;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
|
@ -1206,7 +1206,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = "macOS (Share Extension)/macOS (Share Extension).entitlements";
|
CODE_SIGN_ENTITLEMENTS = "macOS (Share Extension)/macOS (Share Extension).entitlements";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 2025100401;
|
CURRENT_PROJECT_VERSION = 2025102101;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
@ -1220,7 +1220,7 @@
|
||||||
"@executable_path/../../../../Frameworks",
|
"@executable_path/../../../../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
||||||
MARKETING_VERSION = 25.10.4;
|
MARKETING_VERSION = 25.10.21;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = pl.bthlabs.HotPocket.ShareExtension;
|
PRODUCT_BUNDLE_IDENTIFIER = pl.bthlabs.HotPocket.ShareExtension;
|
||||||
PRODUCT_NAME = "Save to HotPocket";
|
PRODUCT_NAME = "Save to HotPocket";
|
||||||
REGISTER_APP_GROUPS = YES;
|
REGISTER_APP_GROUPS = YES;
|
||||||
|
@ -1236,7 +1236,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = "macOS (Share Extension)/macOS (Share Extension).entitlements";
|
CODE_SIGN_ENTITLEMENTS = "macOS (Share Extension)/macOS (Share Extension).entitlements";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 2025100401;
|
CURRENT_PROJECT_VERSION = 2025102101;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
@ -1250,7 +1250,7 @@
|
||||||
"@executable_path/../../../../Frameworks",
|
"@executable_path/../../../../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
||||||
MARKETING_VERSION = 25.10.4;
|
MARKETING_VERSION = 25.10.21;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = pl.bthlabs.HotPocket.ShareExtension;
|
PRODUCT_BUNDLE_IDENTIFIER = pl.bthlabs.HotPocket.ShareExtension;
|
||||||
PRODUCT_NAME = "Save to HotPocket";
|
PRODUCT_NAME = "Save to HotPocket";
|
||||||
REGISTER_APP_GROUPS = YES;
|
REGISTER_APP_GROUPS = YES;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "icon-1024.png",
|
"filename" : "icon-ios-light.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"platform" : "ios",
|
"platform" : "ios",
|
||||||
"size" : "1024x1024"
|
"size" : "1024x1024"
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
"value" : "dark"
|
"value" : "dark"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"filename" : "icon-1024 1.png",
|
"filename" : "icon-ios-dark.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"platform" : "ios",
|
"platform" : "ios",
|
||||||
"size" : "1024x1024"
|
"size" : "1024x1024"
|
||||||
|
@ -25,31 +25,31 @@
|
||||||
"value" : "tinted"
|
"value" : "tinted"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"filename" : "icon-1024 2.png",
|
"filename" : "icon-ios-tinted.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"platform" : "ios",
|
"platform" : "ios",
|
||||||
"size" : "1024x1024"
|
"size" : "1024x1024"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "icon-16.png",
|
"filename" : "icon-mac-16.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "16x16"
|
"size" : "16x16"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "icon-32.png",
|
"filename" : "icon-mac-32.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "16x16"
|
"size" : "16x16"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "icon-32 1.png",
|
"filename" : "icon-mac-32 1.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "32x32"
|
"size" : "32x32"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "icon-64.png",
|
"filename" : "icon-mac-64.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "32x32"
|
"size" : "32x32"
|
||||||
|
|
Before Width: | Height: | Size: 115 KiB |
Before Width: | Height: | Size: 115 KiB |
Before Width: | Height: | Size: 115 KiB |
Before Width: | Height: | Size: 874 B |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 285 KiB |
After Width: | Height: | Size: 323 KiB |
After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 116 KiB |
After Width: | Height: | Size: 828 B |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
23
services/apple/docker-compose-ci.yaml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
services:
|
||||||
|
apple-ci:
|
||||||
|
build:
|
||||||
|
context: ".."
|
||||||
|
dockerfile: "apple/Dockerfile"
|
||||||
|
target: "development"
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/apple:ci-local"
|
||||||
|
command: "echo 'NOOP'"
|
||||||
|
environment:
|
||||||
|
PYTHONBREAKPOINT: "ipdb.set_trace"
|
||||||
|
HOTPOCKET_PACKAGES_ENV: "${HOTPOCKET_EXTENSION_ENV:-docker}"
|
||||||
|
# REQUESTS_CA_BUNDLE: "/srv/tls/requests_ca_bundle.pem"
|
||||||
|
RUN_POETRY_INSTALL: "true"
|
||||||
|
RUN_YARN_INSTALL: "false"
|
||||||
|
SETUP_BACKEND: "true"
|
||||||
|
SETUP_FRONTEND: "false"
|
||||||
|
volumes:
|
||||||
|
- "apple_venv:/srv/venv"
|
||||||
|
- "apple_node_modules:/srv/node_modules"
|
||||||
|
- "../tls:/srv/tls"
|
||||||
|
restart: "no"
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
29
services/apple/docker-compose.yaml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
services:
|
||||||
|
apple-management:
|
||||||
|
build:
|
||||||
|
context: ".."
|
||||||
|
dockerfile: "apple/Dockerfile"
|
||||||
|
target: "development"
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/apple:local"
|
||||||
|
command: "echo 'NOOP'"
|
||||||
|
environment: &apple-env
|
||||||
|
PYTHONBREAKPOINT: "ipdb.set_trace"
|
||||||
|
HOTPOCKET_EXTENSION_ENV: "${HOTPOCKET_EXTENSION_ENV:-docker}"
|
||||||
|
REQUESTS_CA_BUNDLE: "/srv/tls/requests_ca_bundle.pem"
|
||||||
|
RUN_POETRY_INSTALL: "true"
|
||||||
|
RUN_YARN_INSTALL: "false"
|
||||||
|
SETUP_BACKEND: "true"
|
||||||
|
SETUP_FRONTEND: "false"
|
||||||
|
volumes:
|
||||||
|
- "apple_venv:/srv/venv"
|
||||||
|
- "apple_node_modules:/srv/node_modules"
|
||||||
|
- ".:/srv/app"
|
||||||
|
- "../packages:/srv/packages"
|
||||||
|
- "../tls:/srv/tls"
|
||||||
|
restart: "no"
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
apple_venv:
|
||||||
|
apple_node_modules:
|
0
services/apple/ops/bin/.placeholder
Normal file
160
services/apple/poetry.lock
generated
|
@ -1,4 +1,4 @@
|
||||||
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
|
# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand.
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "asttokens"
|
name = "asttokens"
|
||||||
|
@ -6,6 +6,7 @@ version = "3.0.0"
|
||||||
description = "Annotate AST trees with source code positions"
|
description = "Annotate AST trees with source code positions"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2"},
|
{file = "asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2"},
|
||||||
{file = "asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7"},
|
{file = "asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7"},
|
||||||
|
@ -21,6 +22,8 @@ version = "0.4.6"
|
||||||
description = "Cross-platform colored terminal text."
|
description = "Cross-platform colored terminal text."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||||
|
groups = ["dev"]
|
||||||
|
markers = "sys_platform == \"win32\""
|
||||||
files = [
|
files = [
|
||||||
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
|
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
|
||||||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||||
|
@ -32,6 +35,7 @@ version = "5.2.1"
|
||||||
description = "Decorators for Humans"
|
description = "Decorators for Humans"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a"},
|
{file = "decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a"},
|
||||||
{file = "decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360"},
|
{file = "decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360"},
|
||||||
|
@ -43,13 +47,14 @@ version = "2.2.1"
|
||||||
description = "Get the currently executing AST node of a frame, and other information"
|
description = "Get the currently executing AST node of a frame, and other information"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017"},
|
{file = "executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017"},
|
||||||
{file = "executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4"},
|
{file = "executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"]
|
tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich ; python_version >= \"3.11\""]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "factory-boy"
|
name = "factory-boy"
|
||||||
|
@ -57,6 +62,7 @@ version = "3.3.3"
|
||||||
description = "A versatile test fixtures replacement based on thoughtbot's factory_bot for Ruby."
|
description = "A versatile test fixtures replacement based on thoughtbot's factory_bot for Ruby."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "factory_boy-3.3.3-py2.py3-none-any.whl", hash = "sha256:1c39e3289f7e667c4285433f305f8d506efc2fe9c73aaea4151ebd5cdea394fc"},
|
{file = "factory_boy-3.3.3-py2.py3-none-any.whl", hash = "sha256:1c39e3289f7e667c4285433f305f8d506efc2fe9c73aaea4151ebd5cdea394fc"},
|
||||||
{file = "factory_boy-3.3.3.tar.gz", hash = "sha256:866862d226128dfac7f2b4160287e899daf54f2612778327dd03d0e2cb1e3d03"},
|
{file = "factory_boy-3.3.3.tar.gz", hash = "sha256:866862d226128dfac7f2b4160287e899daf54f2612778327dd03d0e2cb1e3d03"},
|
||||||
|
@ -71,13 +77,14 @@ doc = ["Sphinx", "sphinx-rtd-theme", "sphinxcontrib-spelling"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "faker"
|
name = "faker"
|
||||||
version = "37.6.0"
|
version = "37.11.0"
|
||||||
description = "Faker is a Python package that generates fake data for you."
|
description = "Faker is a Python package that generates fake data for you."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "faker-37.6.0-py3-none-any.whl", hash = "sha256:3c5209b23d7049d596a51db5d76403a0ccfea6fc294ffa2ecfef6a8843b1e6a7"},
|
{file = "faker-37.11.0-py3-none-any.whl", hash = "sha256:1508d2da94dfd1e0087b36f386126d84f8583b3de19ac18e392a2831a6676c57"},
|
||||||
{file = "faker-37.6.0.tar.gz", hash = "sha256:0f8cc34f30095184adf87c3c24c45b38b33ad81c35ef6eb0a3118f301143012c"},
|
{file = "faker-37.11.0.tar.gz", hash = "sha256:22969803849ba0618be8eee2dd01d0d9e2cd3b75e6ff1a291fa9abcdb34da5e6"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -89,6 +96,7 @@ version = "7.3.0"
|
||||||
description = "the modular source code checker: pep8 pyflakes and co"
|
description = "the modular source code checker: pep8 pyflakes and co"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "flake8-7.3.0-py2.py3-none-any.whl", hash = "sha256:b9696257b9ce8beb888cdbe31cf885c90d31928fe202be0889a7cdafad32f01e"},
|
{file = "flake8-7.3.0-py2.py3-none-any.whl", hash = "sha256:b9696257b9ce8beb888cdbe31cf885c90d31928fe202be0889a7cdafad32f01e"},
|
||||||
{file = "flake8-7.3.0.tar.gz", hash = "sha256:fe044858146b9fc69b551a4b490d69cf960fcb78ad1edcb84e7fbb1b4a8e3872"},
|
{file = "flake8-7.3.0.tar.gz", hash = "sha256:fe044858146b9fc69b551a4b490d69cf960fcb78ad1edcb84e7fbb1b4a8e3872"},
|
||||||
|
@ -105,6 +113,7 @@ version = "4.0.0"
|
||||||
description = "Flake8 lint for trailing commas."
|
description = "Flake8 lint for trailing commas."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "flake8_commas-4.0.0-py3-none-any.whl", hash = "sha256:cad476d71ba72e8b941a8508d5b9ffb6b03e50f7102982474f085ad0d674b685"},
|
{file = "flake8_commas-4.0.0-py3-none-any.whl", hash = "sha256:cad476d71ba72e8b941a8508d5b9ffb6b03e50f7102982474f085ad0d674b685"},
|
||||||
{file = "flake8_commas-4.0.0.tar.gz", hash = "sha256:a68834b42a9a31c94ca790efe557a932c0eae21a3479c6b9a23c4dc077e3ea96"},
|
{file = "flake8_commas-4.0.0.tar.gz", hash = "sha256:a68834b42a9a31c94ca790efe557a932c0eae21a3479c6b9a23c4dc077e3ea96"},
|
||||||
|
@ -119,11 +128,12 @@ version = "1.0.0.dev0"
|
||||||
description = "HotPocket Workspace Tools"
|
description = "HotPocket Workspace Tools"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "^3.12"
|
python-versions = "^3.12"
|
||||||
|
groups = ["dev"]
|
||||||
files = []
|
files = []
|
||||||
develop = true
|
develop = true
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
invoke = "2.2.0"
|
invoke = "2.2.1"
|
||||||
|
|
||||||
[package.source]
|
[package.source]
|
||||||
type = "directory"
|
type = "directory"
|
||||||
|
@ -131,13 +141,14 @@ url = "../packages/workspace_tools"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "invoke"
|
name = "invoke"
|
||||||
version = "2.2.0"
|
version = "2.2.1"
|
||||||
description = "Pythonic task execution"
|
description = "Pythonic task execution"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "invoke-2.2.0-py3-none-any.whl", hash = "sha256:6ea924cc53d4f78e3d98bc436b08069a03077e6f85ad1ddaa8a116d7dad15820"},
|
{file = "invoke-2.2.1-py3-none-any.whl", hash = "sha256:2413bc441b376e5cd3f55bb5d364f973ad8bdd7bf87e53c79de3c11bf3feecc8"},
|
||||||
{file = "invoke-2.2.0.tar.gz", hash = "sha256:ee6cbb101af1a859c7fe84f2a264c059020b0cb7fe3535f9424300ab568f6bd5"},
|
{file = "invoke-2.2.1.tar.gz", hash = "sha256:515bf49b4a48932b79b024590348da22f39c4942dff991ad1fb8b8baea1be707"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -146,6 +157,7 @@ version = "0.13.13"
|
||||||
description = "IPython-enabled pdb"
|
description = "IPython-enabled pdb"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "ipdb-0.13.13-py3-none-any.whl", hash = "sha256:45529994741c4ab6d2388bfa5d7b725c2cf7fe9deffabdb8a6113aa5ed449ed4"},
|
{file = "ipdb-0.13.13-py3-none-any.whl", hash = "sha256:45529994741c4ab6d2388bfa5d7b725c2cf7fe9deffabdb8a6113aa5ed449ed4"},
|
||||||
{file = "ipdb-0.13.13.tar.gz", hash = "sha256:e3ac6018ef05126d442af680aad863006ec19d02290561ac88b8b1c0b0cfc726"},
|
{file = "ipdb-0.13.13.tar.gz", hash = "sha256:e3ac6018ef05126d442af680aad863006ec19d02290561ac88b8b1c0b0cfc726"},
|
||||||
|
@ -157,13 +169,14 @@ ipython = {version = ">=7.31.1", markers = "python_version >= \"3.11\""}
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipython"
|
name = "ipython"
|
||||||
version = "9.3.0"
|
version = "9.6.0"
|
||||||
description = "IPython: Productive Interactive Computing"
|
description = "IPython: Productive Interactive Computing"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.11"
|
python-versions = ">=3.11"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "ipython-9.3.0-py3-none-any.whl", hash = "sha256:1a0b6dd9221a1f5dddf725b57ac0cb6fddc7b5f470576231ae9162b9b3455a04"},
|
{file = "ipython-9.6.0-py3-none-any.whl", hash = "sha256:5f77efafc886d2f023442479b8149e7d86547ad0a979e9da9f045d252f648196"},
|
||||||
{file = "ipython-9.3.0.tar.gz", hash = "sha256:79eb896f9f23f50ad16c3bc205f686f6e030ad246cc309c6279a242b14afe9d8"},
|
{file = "ipython-9.6.0.tar.gz", hash = "sha256:5603d6d5d356378be5043e69441a072b50a5b33b4503428c77b04cb8ce7bc731"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -181,10 +194,10 @@ traitlets = ">=5.13.0"
|
||||||
[package.extras]
|
[package.extras]
|
||||||
all = ["ipython[doc,matplotlib,test,test-extra]"]
|
all = ["ipython[doc,matplotlib,test,test-extra]"]
|
||||||
black = ["black"]
|
black = ["black"]
|
||||||
doc = ["docrepr", "exceptiongroup", "intersphinx_registry", "ipykernel", "ipython[test]", "matplotlib", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "sphinx_toml (==0.0.4)", "typing_extensions"]
|
doc = ["docrepr", "exceptiongroup", "intersphinx_registry", "ipykernel", "ipython[matplotlib,test]", "setuptools (>=61.2)", "sphinx (>=1.3)", "sphinx-rtd-theme", "sphinx_toml (==0.0.4)", "typing_extensions"]
|
||||||
matplotlib = ["matplotlib"]
|
matplotlib = ["matplotlib (>3.7)"]
|
||||||
test = ["packaging", "pytest", "pytest-asyncio (<0.22)", "testpath"]
|
test = ["packaging", "pytest", "pytest-asyncio", "testpath"]
|
||||||
test-extra = ["curio", "ipykernel", "ipython[test]", "jupyter_ai", "matplotlib (!=3.2.0)", "nbclient", "nbformat", "numpy (>=1.23)", "pandas", "trio"]
|
test-extra = ["curio", "ipykernel", "ipython[matplotlib]", "ipython[test]", "jupyter_ai", "nbclient", "nbformat", "numpy (>=1.25)", "pandas (>2.0)", "trio"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipython-pygments-lexers"
|
name = "ipython-pygments-lexers"
|
||||||
|
@ -192,6 +205,7 @@ version = "1.1.1"
|
||||||
description = "Defines a variety of Pygments lexers for highlighting IPython code."
|
description = "Defines a variety of Pygments lexers for highlighting IPython code."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c"},
|
{file = "ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c"},
|
||||||
{file = "ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81"},
|
{file = "ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81"},
|
||||||
|
@ -202,13 +216,14 @@ pygments = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "isort"
|
name = "isort"
|
||||||
version = "6.0.1"
|
version = "7.0.0"
|
||||||
description = "A Python utility / library to sort Python imports."
|
description = "A Python utility / library to sort Python imports."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9.0"
|
python-versions = ">=3.10.0"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "isort-6.0.1-py3-none-any.whl", hash = "sha256:2dc5d7f65c9678d94c88dfc29161a320eec67328bc97aad576874cb4be1e9615"},
|
{file = "isort-7.0.0-py3-none-any.whl", hash = "sha256:1bcabac8bc3c36c7fb7b98a76c8abb18e0f841a3ba81decac7691008592499c1"},
|
||||||
{file = "isort-6.0.1.tar.gz", hash = "sha256:1cb5df28dfbc742e490c5e41bad6da41b805b0a8be7bc93cd0fb2a8a890ac450"},
|
{file = "isort-7.0.0.tar.gz", hash = "sha256:5513527951aadb3ac4292a41a16cbc50dd1642432f5e8c20057d414bdafb4187"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
|
@ -221,6 +236,7 @@ version = "0.19.2"
|
||||||
description = "An autocompletion tool for Python that can be used for text editors."
|
description = "An autocompletion tool for Python that can be used for text editors."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9"},
|
{file = "jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9"},
|
||||||
{file = "jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0"},
|
{file = "jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0"},
|
||||||
|
@ -240,6 +256,7 @@ version = "0.1.7"
|
||||||
description = "Inline Matplotlib backend for Jupyter"
|
description = "Inline Matplotlib backend for Jupyter"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"},
|
{file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"},
|
||||||
{file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"},
|
{file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"},
|
||||||
|
@ -254,6 +271,7 @@ version = "0.7.0"
|
||||||
description = "McCabe checker, plugin for flake8"
|
description = "McCabe checker, plugin for flake8"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
|
{file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
|
||||||
{file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
|
{file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
|
||||||
|
@ -261,43 +279,50 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mypy"
|
name = "mypy"
|
||||||
version = "1.16.1"
|
version = "1.18.2"
|
||||||
description = "Optional static typing for Python"
|
description = "Optional static typing for Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "mypy-1.16.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b4f0fed1022a63c6fec38f28b7fc77fca47fd490445c69d0a66266c59dd0b88a"},
|
{file = "mypy-1.18.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c1eab0cf6294dafe397c261a75f96dc2c31bffe3b944faa24db5def4e2b0f77c"},
|
||||||
{file = "mypy-1.16.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86042bbf9f5a05ea000d3203cf87aa9d0ccf9a01f73f71c58979eb9249f46d72"},
|
{file = "mypy-1.18.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7a780ca61fc239e4865968ebc5240bb3bf610ef59ac398de9a7421b54e4a207e"},
|
||||||
{file = "mypy-1.16.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ea7469ee5902c95542bea7ee545f7006508c65c8c54b06dc2c92676ce526f3ea"},
|
{file = "mypy-1.18.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:448acd386266989ef11662ce3c8011fd2a7b632e0ec7d61a98edd8e27472225b"},
|
||||||
{file = "mypy-1.16.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:352025753ef6a83cb9e7f2427319bb7875d1fdda8439d1e23de12ab164179574"},
|
{file = "mypy-1.18.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f9e171c465ad3901dc652643ee4bffa8e9fef4d7d0eece23b428908c77a76a66"},
|
||||||
{file = "mypy-1.16.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ff9fa5b16e4c1364eb89a4d16bcda9987f05d39604e1e6c35378a2987c1aac2d"},
|
{file = "mypy-1.18.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:592ec214750bc00741af1f80cbf96b5013d81486b7bb24cb052382c19e40b428"},
|
||||||
{file = "mypy-1.16.1-cp310-cp310-win_amd64.whl", hash = "sha256:1256688e284632382f8f3b9e2123df7d279f603c561f099758e66dd6ed4e8bd6"},
|
{file = "mypy-1.18.2-cp310-cp310-win_amd64.whl", hash = "sha256:7fb95f97199ea11769ebe3638c29b550b5221e997c63b14ef93d2e971606ebed"},
|
||||||
{file = "mypy-1.16.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:472e4e4c100062488ec643f6162dd0d5208e33e2f34544e1fc931372e806c0cc"},
|
{file = "mypy-1.18.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:807d9315ab9d464125aa9fcf6d84fde6e1dc67da0b6f80e7405506b8ac72bc7f"},
|
||||||
{file = "mypy-1.16.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea16e2a7d2714277e349e24d19a782a663a34ed60864006e8585db08f8ad1782"},
|
{file = "mypy-1.18.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:776bb00de1778caf4db739c6e83919c1d85a448f71979b6a0edd774ea8399341"},
|
||||||
{file = "mypy-1.16.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08e850ea22adc4d8a4014651575567b0318ede51e8e9fe7a68f25391af699507"},
|
{file = "mypy-1.18.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1379451880512ffce14505493bd9fe469e0697543717298242574882cf8cdb8d"},
|
||||||
{file = "mypy-1.16.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22d76a63a42619bfb90122889b903519149879ddbf2ba4251834727944c8baca"},
|
{file = "mypy-1.18.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1331eb7fd110d60c24999893320967594ff84c38ac6d19e0a76c5fd809a84c86"},
|
||||||
{file = "mypy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2c7ce0662b6b9dc8f4ed86eb7a5d505ee3298c04b40ec13b30e572c0e5ae17c4"},
|
{file = "mypy-1.18.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ca30b50a51e7ba93b00422e486cbb124f1c56a535e20eff7b2d6ab72b3b2e37"},
|
||||||
{file = "mypy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:211287e98e05352a2e1d4e8759c5490925a7c784ddc84207f4714822f8cf99b6"},
|
{file = "mypy-1.18.2-cp311-cp311-win_amd64.whl", hash = "sha256:664dc726e67fa54e14536f6e1224bcfce1d9e5ac02426d2326e2bb4e081d1ce8"},
|
||||||
{file = "mypy-1.16.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:af4792433f09575d9eeca5c63d7d90ca4aeceda9d8355e136f80f8967639183d"},
|
{file = "mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:33eca32dd124b29400c31d7cf784e795b050ace0e1f91b8dc035672725617e34"},
|
||||||
{file = "mypy-1.16.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:66df38405fd8466ce3517eda1f6640611a0b8e70895e2a9462d1d4323c5eb4b9"},
|
{file = "mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a3c47adf30d65e89b2dcd2fa32f3aeb5e94ca970d2c15fcb25e297871c8e4764"},
|
||||||
{file = "mypy-1.16.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44e7acddb3c48bd2713994d098729494117803616e116032af192871aed80b79"},
|
{file = "mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d6c838e831a062f5f29d11c9057c6009f60cb294fea33a98422688181fe2893"},
|
||||||
{file = "mypy-1.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ab5eca37b50188163fa7c1b73c685ac66c4e9bdee4a85c9adac0e91d8895e15"},
|
{file = "mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01199871b6110a2ce984bde85acd481232d17413868c9807e95c1b0739a58914"},
|
||||||
{file = "mypy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb6229b2c9086247e21a83c309754b9058b438704ad2f6807f0d8227f6ebdd"},
|
{file = "mypy-1.18.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a2afc0fa0b0e91b4599ddfe0f91e2c26c2b5a5ab263737e998d6817874c5f7c8"},
|
||||||
{file = "mypy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:1f0435cf920e287ff68af3d10a118a73f212deb2ce087619eb4e648116d1fe9b"},
|
{file = "mypy-1.18.2-cp312-cp312-win_amd64.whl", hash = "sha256:d8068d0afe682c7c4897c0f7ce84ea77f6de953262b12d07038f4d296d547074"},
|
||||||
{file = "mypy-1.16.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ddc91eb318c8751c69ddb200a5937f1232ee8efb4e64e9f4bc475a33719de438"},
|
{file = "mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc"},
|
||||||
{file = "mypy-1.16.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:87ff2c13d58bdc4bbe7dc0dedfe622c0f04e2cb2a492269f3b418df2de05c536"},
|
{file = "mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e"},
|
||||||
{file = "mypy-1.16.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a7cfb0fe29fe5a9841b7c8ee6dffb52382c45acdf68f032145b75620acfbd6f"},
|
{file = "mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986"},
|
||||||
{file = "mypy-1.16.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:051e1677689c9d9578b9c7f4d206d763f9bbd95723cd1416fad50db49d52f359"},
|
{file = "mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a431a6f1ef14cf8c144c6b14793a23ec4eae3db28277c358136e79d7d062f62d"},
|
||||||
{file = "mypy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d5d2309511cc56c021b4b4e462907c2b12f669b2dbeb68300110ec27723971be"},
|
{file = "mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7ab28cc197f1dd77a67e1c6f35cd1f8e8b73ed2217e4fc005f9e6a504e46e7ba"},
|
||||||
{file = "mypy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:4f58ac32771341e38a853c5d0ec0dfe27e18e27da9cdb8bbc882d2249c71a3ee"},
|
{file = "mypy-1.18.2-cp313-cp313-win_amd64.whl", hash = "sha256:0e2785a84b34a72ba55fb5daf079a1003a34c05b22238da94fcae2bbe46f3544"},
|
||||||
{file = "mypy-1.16.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7fc688329af6a287567f45cc1cefb9db662defeb14625213a5b7da6e692e2069"},
|
{file = "mypy-1.18.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:62f0e1e988ad41c2a110edde6c398383a889d95b36b3e60bcf155f5164c4fdce"},
|
||||||
{file = "mypy-1.16.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e198ab3f55924c03ead626ff424cad1732d0d391478dfbf7bb97b34602395da"},
|
{file = "mypy-1.18.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8795a039bab805ff0c1dfdb8cd3344642c2b99b8e439d057aba30850b8d3423d"},
|
||||||
{file = "mypy-1.16.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09aa4f91ada245f0a45dbc47e548fd94e0dd5a8433e0114917dc3b526912a30c"},
|
{file = "mypy-1.18.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6ca1e64b24a700ab5ce10133f7ccd956a04715463d30498e64ea8715236f9c9c"},
|
||||||
{file = "mypy-1.16.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13c7cd5b1cb2909aa318a90fd1b7e31f17c50b242953e7dd58345b2a814f6383"},
|
{file = "mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb"},
|
||||||
{file = "mypy-1.16.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:58e07fb958bc5d752a280da0e890c538f1515b79a65757bbdc54252ba82e0b40"},
|
{file = "mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075"},
|
||||||
{file = "mypy-1.16.1-cp39-cp39-win_amd64.whl", hash = "sha256:f895078594d918f93337a505f8add9bd654d1a24962b4c6ed9390e12531eb31b"},
|
{file = "mypy-1.18.2-cp314-cp314-win_amd64.whl", hash = "sha256:749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf"},
|
||||||
{file = "mypy-1.16.1-py3-none-any.whl", hash = "sha256:5fc2ac4027d0ef28d6ba69a0343737a23c4d1b83672bf38d1fe237bdc0643b37"},
|
{file = "mypy-1.18.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:25a9c8fb67b00599f839cf472713f54249a62efd53a54b565eb61956a7e3296b"},
|
||||||
{file = "mypy-1.16.1.tar.gz", hash = "sha256:6bd00a0a2094841c5e47e7374bb42b83d64c527a502e3334e1173a0c24437bab"},
|
{file = "mypy-1.18.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2b9c7e284ee20e7598d6f42e13ca40b4928e6957ed6813d1ab6348aa3f47133"},
|
||||||
|
{file = "mypy-1.18.2-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6985ed057513e344e43a26cc1cd815c7a94602fb6a3130a34798625bc2f07b6"},
|
||||||
|
{file = "mypy-1.18.2-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22f27105f1525ec024b5c630c0b9f36d5c1cc4d447d61fe51ff4bd60633f47ac"},
|
||||||
|
{file = "mypy-1.18.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:030c52d0ea8144e721e49b1f68391e39553d7451f0c3f8a7565b59e19fcb608b"},
|
||||||
|
{file = "mypy-1.18.2-cp39-cp39-win_amd64.whl", hash = "sha256:aa5e07ac1a60a253445797e42b8b2963c9675563a94f11291ab40718b016a7a0"},
|
||||||
|
{file = "mypy-1.18.2-py3-none-any.whl", hash = "sha256:22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e"},
|
||||||
|
{file = "mypy-1.18.2.tar.gz", hash = "sha256:06a398102a5f203d7477b2923dda3634c36727fa5c237d8f859ef90c42a9924b"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -318,6 +343,7 @@ version = "1.1.0"
|
||||||
description = "Type system extensions for programs checked with the mypy type checker."
|
description = "Type system extensions for programs checked with the mypy type checker."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"},
|
{file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"},
|
||||||
{file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"},
|
{file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"},
|
||||||
|
@ -329,6 +355,7 @@ version = "0.8.5"
|
||||||
description = "A Python Parser"
|
description = "A Python Parser"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "parso-0.8.5-py2.py3-none-any.whl", hash = "sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887"},
|
{file = "parso-0.8.5-py2.py3-none-any.whl", hash = "sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887"},
|
||||||
{file = "parso-0.8.5.tar.gz", hash = "sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a"},
|
{file = "parso-0.8.5.tar.gz", hash = "sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a"},
|
||||||
|
@ -344,6 +371,7 @@ version = "0.12.1"
|
||||||
description = "Utility library for gitignore style pattern matching of file paths."
|
description = "Utility library for gitignore style pattern matching of file paths."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"},
|
{file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"},
|
||||||
{file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"},
|
{file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"},
|
||||||
|
@ -355,6 +383,8 @@ version = "4.9.0"
|
||||||
description = "Pexpect allows easy control of interactive console applications."
|
description = "Pexpect allows easy control of interactive console applications."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
groups = ["dev"]
|
||||||
|
markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""
|
||||||
files = [
|
files = [
|
||||||
{file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"},
|
{file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"},
|
||||||
{file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"},
|
{file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"},
|
||||||
|
@ -369,6 +399,7 @@ version = "3.0.52"
|
||||||
description = "Library for building powerful interactive command lines in Python"
|
description = "Library for building powerful interactive command lines in Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955"},
|
{file = "prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955"},
|
||||||
{file = "prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855"},
|
{file = "prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855"},
|
||||||
|
@ -383,6 +414,8 @@ version = "0.7.0"
|
||||||
description = "Run a subprocess in a pseudo terminal"
|
description = "Run a subprocess in a pseudo terminal"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
groups = ["dev"]
|
||||||
|
markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""
|
||||||
files = [
|
files = [
|
||||||
{file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"},
|
{file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"},
|
||||||
{file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"},
|
{file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"},
|
||||||
|
@ -394,6 +427,7 @@ version = "0.2.3"
|
||||||
description = "Safely evaluate AST nodes without side effects"
|
description = "Safely evaluate AST nodes without side effects"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"},
|
{file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"},
|
||||||
{file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"},
|
{file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"},
|
||||||
|
@ -408,6 +442,7 @@ version = "2.14.0"
|
||||||
description = "Python style guide checker"
|
description = "Python style guide checker"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "pycodestyle-2.14.0-py2.py3-none-any.whl", hash = "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d"},
|
{file = "pycodestyle-2.14.0-py2.py3-none-any.whl", hash = "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d"},
|
||||||
{file = "pycodestyle-2.14.0.tar.gz", hash = "sha256:c4b5b517d278089ff9d0abdec919cd97262a3367449ea1c8b49b91529167b783"},
|
{file = "pycodestyle-2.14.0.tar.gz", hash = "sha256:c4b5b517d278089ff9d0abdec919cd97262a3367449ea1c8b49b91529167b783"},
|
||||||
|
@ -419,6 +454,7 @@ version = "3.4.0"
|
||||||
description = "passive checker of Python programs"
|
description = "passive checker of Python programs"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "pyflakes-3.4.0-py2.py3-none-any.whl", hash = "sha256:f742a7dbd0d9cb9ea41e9a24a918996e8170c799fa528688d40dd582c8265f4f"},
|
{file = "pyflakes-3.4.0-py2.py3-none-any.whl", hash = "sha256:f742a7dbd0d9cb9ea41e9a24a918996e8170c799fa528688d40dd582c8265f4f"},
|
||||||
{file = "pyflakes-3.4.0.tar.gz", hash = "sha256:b24f96fafb7d2ab0ec5075b7350b3d2d2218eab42003821c06344973d3ea2f58"},
|
{file = "pyflakes-3.4.0.tar.gz", hash = "sha256:b24f96fafb7d2ab0ec5075b7350b3d2d2218eab42003821c06344973d3ea2f58"},
|
||||||
|
@ -430,6 +466,7 @@ version = "2.19.2"
|
||||||
description = "Pygments is a syntax highlighting package written in Python."
|
description = "Pygments is a syntax highlighting package written in Python."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"},
|
{file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"},
|
||||||
{file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"},
|
{file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"},
|
||||||
|
@ -444,6 +481,7 @@ version = "0.6.3"
|
||||||
description = "Extract data from python stack frames and tracebacks for informative displays"
|
description = "Extract data from python stack frames and tracebacks for informative displays"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"},
|
{file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"},
|
||||||
{file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"},
|
{file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"},
|
||||||
|
@ -463,6 +501,7 @@ version = "5.14.3"
|
||||||
description = "Traitlets Python configuration system"
|
description = "Traitlets Python configuration system"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"},
|
{file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"},
|
||||||
{file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"},
|
{file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"},
|
||||||
|
@ -478,6 +517,7 @@ version = "4.15.0"
|
||||||
description = "Backported and Experimental Type Hints for Python 3.9+"
|
description = "Backported and Experimental Type Hints for Python 3.9+"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"},
|
{file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"},
|
||||||
{file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"},
|
{file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"},
|
||||||
|
@ -489,6 +529,7 @@ version = "2025.2"
|
||||||
description = "Provider of IANA time zone data"
|
description = "Provider of IANA time zone data"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2"
|
python-versions = ">=2"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"},
|
{file = "tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"},
|
||||||
{file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"},
|
{file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"},
|
||||||
|
@ -496,16 +537,17 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wcwidth"
|
name = "wcwidth"
|
||||||
version = "0.2.13"
|
version = "0.2.14"
|
||||||
description = "Measures the displayed width of unicode strings in a terminal"
|
description = "Measures the displayed width of unicode strings in a terminal"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = ">=3.6"
|
||||||
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"},
|
{file = "wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1"},
|
||||||
{file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"},
|
{file = "wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.1"
|
||||||
python-versions = "^3.12"
|
python-versions = "^3.12"
|
||||||
content-hash = "1c74b6d5928a0b1bde41962f4233af2eba2242324c3155b21093b2f46baf5cd0"
|
content-hash = "b03ef0369277d183d033049206a4cfd5f450473179995a4a79165fbb84d81fa0"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "hotpocket-apple"
|
name = "hotpocket-apple"
|
||||||
version = "25.10.4"
|
version = "25.10.21"
|
||||||
description = "HotPocket Apple Integrations"
|
description = "HotPocket Apple Integrations"
|
||||||
authors = ["Tomek Wójcik <contact@bthlabs.pl>"]
|
authors = ["Tomek Wójcik <contact@bthlabs.pl>"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
@ -15,11 +15,10 @@ factory-boy = "3.3.3"
|
||||||
flake8 = "7.3.0"
|
flake8 = "7.3.0"
|
||||||
flake8-commas = "4.0.0"
|
flake8-commas = "4.0.0"
|
||||||
hotpocket-workspace-tools = {path = "../packages/workspace_tools", develop = true}
|
hotpocket-workspace-tools = {path = "../packages/workspace_tools", develop = true}
|
||||||
invoke = "2.2.0"
|
|
||||||
ipdb = "0.13.13"
|
ipdb = "0.13.13"
|
||||||
ipython = "9.3.0"
|
ipython = "9.6.0"
|
||||||
isort = "6.0.1"
|
isort = "7.0.0"
|
||||||
mypy = "1.16.1"
|
mypy = "1.18.2"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core"]
|
requires = ["poetry-core"]
|
||||||
|
|
|
@ -2,22 +2,17 @@ ARG APP_USER_UID=1000
|
||||||
ARG APP_USER_GID=1000
|
ARG APP_USER_GID=1000
|
||||||
ARG IMAGE_ID=development.00000000
|
ARG IMAGE_ID=development.00000000
|
||||||
|
|
||||||
FROM docker-hosted.nexus.bthlabs.pl/hotpocket/base:build-node-20250819-01 AS development
|
FROM docker-hosted.nexus.bthlabs.pl/hotpocket/base:build-node-20251014-01 AS development
|
||||||
|
|
||||||
ARG APP_USER_UID
|
ARG APP_USER_UID
|
||||||
ARG APP_USER_GID
|
ARG APP_USER_GID
|
||||||
ARG IMAGE_ID
|
ARG IMAGE_ID
|
||||||
|
|
||||||
USER root
|
|
||||||
|
|
||||||
COPY --chown=$APP_USER_UID:$APP_USER_GID backend/ops/bin/*.sh /srv/bin/
|
COPY --chown=$APP_USER_UID:$APP_USER_GID backend/ops/bin/*.sh /srv/bin/
|
||||||
RUN chown -R ${APP_USER_UID}:${APP_USER_GID} /srv
|
|
||||||
|
|
||||||
USER app
|
|
||||||
|
|
||||||
VOLUME ["/srv/node_modules", "/srv/venv"]
|
VOLUME ["/srv/node_modules", "/srv/venv"]
|
||||||
|
|
||||||
FROM docker-hosted.nexus.bthlabs.pl/hotpocket/base:build-python-20250819-01 AS deployment-build
|
FROM docker-hosted.nexus.bthlabs.pl/hotpocket/base:build-python-20251014-01 AS deployment-build
|
||||||
|
|
||||||
ARG APP_USER_UID
|
ARG APP_USER_UID
|
||||||
ARG APP_USER_GID
|
ARG APP_USER_GID
|
||||||
|
@ -36,7 +31,7 @@ RUN poetry install --only main,deployment && \
|
||||||
rm -f hotpocket_backend/settings/deployment/build.py && \
|
rm -f hotpocket_backend/settings/deployment/build.py && \
|
||||||
rm -rf node_modules/
|
rm -rf node_modules/
|
||||||
|
|
||||||
FROM docker-hosted.nexus.bthlabs.pl/hotpocket/base:base-20250819-01 AS deployment-base
|
FROM docker-hosted.nexus.bthlabs.pl/hotpocket/base:base-20251014-01 AS deployment-base
|
||||||
|
|
||||||
ARG APP_USER_UID
|
ARG APP_USER_UID
|
||||||
ARG APP_USER_GID
|
ARG APP_USER_GID
|
||||||
|
@ -50,7 +45,6 @@ COPY --from=deployment-build /srv/packages /srv/packages
|
||||||
COPY --from=deployment-build /srv/venv /srv/venv
|
COPY --from=deployment-build /srv/venv /srv/venv
|
||||||
COPY --chown=$APP_USER_UID:$APP_USER_GID backend/ops/bin/*.sh /srv/bin/
|
COPY --chown=$APP_USER_UID:$APP_USER_GID backend/ops/bin/*.sh /srv/bin/
|
||||||
COPY --chown=$APP_USER_UID:$APP_USER_GID backend/ops/deployment/gunicorn.conf.py backend/ops/deployment/gunicorn.logging.conf /srv/lib/
|
COPY --chown=$APP_USER_UID:$APP_USER_GID backend/ops/deployment/gunicorn.conf.py backend/ops/deployment/gunicorn.logging.conf /srv/lib/
|
||||||
RUN chown -R $APP_USER_UID:$APP_USER_GID /srv
|
|
||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
|
@ -109,5 +103,4 @@ COPY --chown=$APP_USER_UID:$APP_USER_GID packages/ /srv/packages/
|
||||||
COPY --chown=$APP_USER_UID:$APP_USER_GID tls/ /srv/tls/
|
COPY --chown=$APP_USER_UID:$APP_USER_GID tls/ /srv/tls/
|
||||||
|
|
||||||
RUN ln -s /srv/app/ops/docker/settings /srv/app/hotpocket_backend/settings/docker && \
|
RUN ln -s /srv/app/ops/docker/settings /srv/app/hotpocket_backend/settings/docker && \
|
||||||
ln -s /srv/app/ops/docker/secrets /srv/app/hotpocket_backend/secrets/docker && \
|
ln -s /srv/app/ops/docker/secrets /srv/app/hotpocket_backend/secrets/docker
|
||||||
chown -R $APP_USER_UID:$APP_USER_GID /srv
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
version = '25.10.4'
|
version = '25.10.21'
|
||||||
|
|
|
@ -68,4 +68,10 @@ class Account(AbstractUser):
|
||||||
else:
|
else:
|
||||||
result['auto_load_embeds'] = auto_load_embeds
|
result['auto_load_embeds'] = auto_load_embeds
|
||||||
|
|
||||||
|
light_mode = result.get('light_mode', None)
|
||||||
|
if isinstance(light_mode, str) is True:
|
||||||
|
result['light_mode'] = (light_mode == 'True')
|
||||||
|
else:
|
||||||
|
result['light_mode'] = light_mode
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -6,6 +6,7 @@ import hmac
|
||||||
import logging
|
import logging
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
import uuid6
|
import uuid6
|
||||||
|
|
||||||
|
@ -15,6 +16,10 @@ from hotpocket_soa.dto.accounts import (
|
||||||
AccessTokenMetaUpdateIn,
|
AccessTokenMetaUpdateIn,
|
||||||
AccessTokensQuery,
|
AccessTokensQuery,
|
||||||
)
|
)
|
||||||
|
from hotpocket_soa.exceptions.backend import (
|
||||||
|
Invalid as InvalidError,
|
||||||
|
NotFound as NotFoundError,
|
||||||
|
)
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -23,7 +28,10 @@ class AccessTokensService:
|
||||||
class AccessTokensServiceError(Exception):
|
class AccessTokensServiceError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class AccessTokenNotFound(AccessTokensServiceError):
|
class Invalid(InvalidError, AccessTokensServiceError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class NotFound(NotFoundError, AccessTokensServiceError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def create(self,
|
def create(self,
|
||||||
|
@ -32,6 +40,7 @@ class AccessTokensService:
|
||||||
origin: str,
|
origin: str,
|
||||||
meta: dict,
|
meta: dict,
|
||||||
) -> AccessToken:
|
) -> AccessToken:
|
||||||
|
try:
|
||||||
pk = uuid6.uuid7()
|
pk = uuid6.uuid7()
|
||||||
key = hmac.new(
|
key = hmac.new(
|
||||||
settings.SECRET_KEY.encode('ascii'),
|
settings.SECRET_KEY.encode('ascii'),
|
||||||
|
@ -46,6 +55,8 @@ class AccessTokensService:
|
||||||
origin=origin,
|
origin=origin,
|
||||||
meta=meta,
|
meta=meta,
|
||||||
)
|
)
|
||||||
|
except ValidationError as exception:
|
||||||
|
raise self.Invalid.from_django_validation_error(exception)
|
||||||
|
|
||||||
def get(self, *, pk: uuid.UUID) -> AccessToken:
|
def get(self, *, pk: uuid.UUID) -> AccessToken:
|
||||||
try:
|
try:
|
||||||
|
@ -53,7 +64,7 @@ class AccessTokensService:
|
||||||
|
|
||||||
return query_set.get(pk=pk)
|
return query_set.get(pk=pk)
|
||||||
except AccessToken.DoesNotExist as exception:
|
except AccessToken.DoesNotExist as exception:
|
||||||
raise self.AccessTokenNotFound(
|
raise self.NotFound(
|
||||||
f'Access Token not found: pk=`{pk}`',
|
f'Access Token not found: pk=`{pk}`',
|
||||||
) from exception
|
) from exception
|
||||||
|
|
||||||
|
@ -63,7 +74,7 @@ class AccessTokensService:
|
||||||
|
|
||||||
return query_set.get(key=key)
|
return query_set.get(key=key)
|
||||||
except AccessToken.DoesNotExist as exception:
|
except AccessToken.DoesNotExist as exception:
|
||||||
raise self.AccessTokenNotFound(
|
raise self.NotFound(
|
||||||
f'Access Token not found: key=`{key}`',
|
f'Access Token not found: key=`{key}`',
|
||||||
) from exception
|
) from exception
|
||||||
|
|
||||||
|
@ -98,7 +109,7 @@ class AccessTokensService:
|
||||||
pk: uuid.UUID,
|
pk: uuid.UUID,
|
||||||
update: AccessTokenMetaUpdateIn,
|
update: AccessTokenMetaUpdateIn,
|
||||||
) -> AccessToken:
|
) -> AccessToken:
|
||||||
access_token = AccessToken.active_objects.get(pk=pk)
|
access_token = self.get(pk=pk)
|
||||||
|
|
||||||
next_meta = {
|
next_meta = {
|
||||||
**(access_token.meta or {}),
|
**(access_token.meta or {}),
|
||||||
|
|
|
@ -5,6 +5,7 @@ import logging
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from hotpocket_backend.apps.accounts.models import Account
|
from hotpocket_backend.apps.accounts.models import Account
|
||||||
|
from hotpocket_soa.exceptions.backend import NotFound as NotFoundError
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ class AccountsService:
|
||||||
class AccountsServiceError(Exception):
|
class AccountsServiceError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class AccountNotFound(AccountsServiceError):
|
class NotFound(NotFoundError, AccountsServiceError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get(self, *, pk: uuid.UUID) -> Account:
|
def get(self, *, pk: uuid.UUID) -> Account:
|
||||||
|
@ -22,6 +23,6 @@ class AccountsService:
|
||||||
|
|
||||||
return query_set.get(pk=pk)
|
return query_set.get(pk=pk)
|
||||||
except Account.DoesNotExist as exception:
|
except Account.DoesNotExist as exception:
|
||||||
raise self.AccountNotFound(
|
raise self.NotFound(
|
||||||
f'Account not found: pk=`{pk}`',
|
f'Account not found: pk=`{pk}`',
|
||||||
) from exception
|
) from exception
|
||||||
|
|
|
@ -5,11 +5,17 @@ import datetime
|
||||||
import logging
|
import logging
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
import uuid6
|
import uuid6
|
||||||
|
|
||||||
from hotpocket_backend.apps.accounts.models import AuthKey
|
from hotpocket_backend.apps.accounts.models import AuthKey
|
||||||
from hotpocket_backend.apps.core.conf import settings
|
from hotpocket_backend.apps.core.conf import settings
|
||||||
|
from hotpocket_soa.exceptions.backend import (
|
||||||
|
InternalError,
|
||||||
|
Invalid as InvalidError,
|
||||||
|
NotFound as NotFoundError,
|
||||||
|
)
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -18,22 +24,25 @@ class AuthKeysService:
|
||||||
class AuthKeysServiceError(Exception):
|
class AuthKeysServiceError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class AuthKeyNotFound(AuthKeysServiceError):
|
class Invalid(InvalidError, AuthKeysServiceError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class AuthKeyExpired(AuthKeysServiceError):
|
class NotFound(NotFoundError, AuthKeysServiceError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class AuthKeyAccessDenied(AuthKeysServiceError):
|
class Expired(InternalError, AuthKeysServiceError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def create(self, *, account_uuid: uuid.UUID) -> AuthKey:
|
def create(self, *, account_uuid: uuid.UUID) -> AuthKey:
|
||||||
|
try:
|
||||||
key = str(uuid6.uuid7())
|
key = str(uuid6.uuid7())
|
||||||
|
|
||||||
return AuthKey.objects.create(
|
return AuthKey.objects.create(
|
||||||
account_uuid=account_uuid,
|
account_uuid=account_uuid,
|
||||||
key=key,
|
key=key,
|
||||||
)
|
)
|
||||||
|
except ValidationError as exception:
|
||||||
|
raise self.Invalid.from_django_validation_error(exception)
|
||||||
|
|
||||||
def get(self, *, pk: uuid.UUID) -> AuthKey:
|
def get(self, *, pk: uuid.UUID) -> AuthKey:
|
||||||
try:
|
try:
|
||||||
|
@ -41,7 +50,7 @@ class AuthKeysService:
|
||||||
|
|
||||||
return query_set.get(pk=pk)
|
return query_set.get(pk=pk)
|
||||||
except AuthKey.DoesNotExist as exception:
|
except AuthKey.DoesNotExist as exception:
|
||||||
raise self.AuthKeyNotFound(
|
raise self.NotFound(
|
||||||
f'Auth Key not found: pk=`{pk}`',
|
f'Auth Key not found: pk=`{pk}`',
|
||||||
) from exception
|
) from exception
|
||||||
|
|
||||||
|
@ -56,17 +65,17 @@ class AuthKeysService:
|
||||||
|
|
||||||
if ttl > 0:
|
if ttl > 0:
|
||||||
if result.created_at < now() - datetime.timedelta(seconds=ttl):
|
if result.created_at < now() - datetime.timedelta(seconds=ttl):
|
||||||
raise self.AuthKeyExpired(
|
raise self.Expired(
|
||||||
f'Auth Key expired: pk=`{key}`',
|
f'Auth Key expired: pk=`{key}`',
|
||||||
)
|
)
|
||||||
|
|
||||||
if result.consumed_at is not None:
|
if result.consumed_at is not None:
|
||||||
raise self.AuthKeyExpired(
|
raise self.Expired(
|
||||||
f'Auth Key already consumed: pk=`{key}`',
|
f'Auth Key already consumed: pk=`{key}`',
|
||||||
)
|
)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
except AuthKey.DoesNotExist as exception:
|
except AuthKey.DoesNotExist as exception:
|
||||||
raise self.AuthKeyNotFound(
|
raise self.NotFound(
|
||||||
f'Auth Key not found: key=`{key}`',
|
f'Auth Key not found: key=`{key}`',
|
||||||
) from exception
|
) from exception
|
||||||
|
|
|
@ -1,16 +1,39 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import functools
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
|
from bthlabs_jsonrpc_core.exceptions import BaseJSONRPCError
|
||||||
from bthlabs_jsonrpc_django import (
|
from bthlabs_jsonrpc_django import (
|
||||||
DjangoExecutor,
|
DjangoExecutor,
|
||||||
DjangoJSONRPCSerializer,
|
DjangoJSONRPCSerializer,
|
||||||
JSONRPCView as BaseJSONRPCView,
|
JSONRPCView as BaseJSONRPCView,
|
||||||
)
|
)
|
||||||
from django.core.exceptions import ValidationError
|
|
||||||
import uuid6
|
import uuid6
|
||||||
|
|
||||||
|
from hotpocket_soa.exceptions.frontend import SOAError
|
||||||
|
|
||||||
|
|
||||||
|
class SOAJSONRPCError(BaseJSONRPCError):
|
||||||
|
ERROR_CODE = -32000
|
||||||
|
ERROR_MESSAGE = 'SOA Error'
|
||||||
|
|
||||||
|
def to_rpc(self) -> dict:
|
||||||
|
exception = typing.cast(SOAError, self.data)
|
||||||
|
|
||||||
|
code = (
|
||||||
|
exception.code
|
||||||
|
if exception.code is not None
|
||||||
|
else self.ERROR_CODE
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'code': code,
|
||||||
|
'message': exception.message or self.ERROR_MESSAGE,
|
||||||
|
'data': exception.data,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class JSONRPCSerializer(DjangoJSONRPCSerializer):
|
class JSONRPCSerializer(DjangoJSONRPCSerializer):
|
||||||
STRING_COERCIBLE_TYPES: typing.Any = (
|
STRING_COERCIBLE_TYPES: typing.Any = (
|
||||||
|
@ -18,30 +41,6 @@ class JSONRPCSerializer(DjangoJSONRPCSerializer):
|
||||||
uuid6.UUID,
|
uuid6.UUID,
|
||||||
)
|
)
|
||||||
|
|
||||||
def serialize_value(self, value: typing.Any) -> typing.Any:
|
|
||||||
if isinstance(value, ValidationError):
|
|
||||||
result: typing.Any = None
|
|
||||||
|
|
||||||
if hasattr(value, 'error_dict') is True:
|
|
||||||
result = {}
|
|
||||||
for field, errors in value.error_dict.items():
|
|
||||||
result[field] = [
|
|
||||||
error.code
|
|
||||||
for error
|
|
||||||
in errors
|
|
||||||
]
|
|
||||||
elif hasattr(value, 'error_list') is True:
|
|
||||||
result = [
|
|
||||||
error.code
|
|
||||||
for error in value.error_list
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
result = value.code
|
|
||||||
|
|
||||||
return self.serialize_value(result)
|
|
||||||
|
|
||||||
return super().serialize_value(value)
|
|
||||||
|
|
||||||
|
|
||||||
class Executor(DjangoExecutor):
|
class Executor(DjangoExecutor):
|
||||||
serializer = JSONRPCSerializer
|
serializer = JSONRPCSerializer
|
||||||
|
@ -49,3 +48,14 @@ class Executor(DjangoExecutor):
|
||||||
|
|
||||||
class JSONRPCView(BaseJSONRPCView):
|
class JSONRPCView(BaseJSONRPCView):
|
||||||
executor = Executor
|
executor = Executor
|
||||||
|
|
||||||
|
|
||||||
|
def wrap_soa_errors(func: typing.Callable) -> typing.Callable:
|
||||||
|
@functools.wraps(func)
|
||||||
|
def decorator(*args, **kwargs):
|
||||||
|
try:
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
except SOAError as exception:
|
||||||
|
raise SOAJSONRPCError(exception)
|
||||||
|
|
||||||
|
return decorator
|
||||||
|
|
|
@ -5,6 +5,7 @@ import datetime
|
||||||
import logging
|
import logging
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
|
|
||||||
|
@ -15,6 +16,10 @@ from hotpocket_soa.dto.associations import (
|
||||||
AssociationsQuery,
|
AssociationsQuery,
|
||||||
AssociationUpdateIn,
|
AssociationUpdateIn,
|
||||||
)
|
)
|
||||||
|
from hotpocket_soa.exceptions.backend import (
|
||||||
|
Invalid as InvalidError,
|
||||||
|
NotFound as NotFoundError,
|
||||||
|
)
|
||||||
|
|
||||||
from .saves import SavesService
|
from .saves import SavesService
|
||||||
|
|
||||||
|
@ -25,7 +30,10 @@ class AssociationsService:
|
||||||
class AssociationsServiceError(Exception):
|
class AssociationsServiceError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class AssociationNotFound(AssociationsServiceError):
|
class Invalid(InvalidError, AssociationsServiceError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class NotFound(NotFoundError, AssociationsServiceError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -46,6 +54,7 @@ class AssociationsService:
|
||||||
pk: uuid.UUID | None = None,
|
pk: uuid.UUID | None = None,
|
||||||
created_at: datetime.datetime | None = None,
|
created_at: datetime.datetime | None = None,
|
||||||
) -> Association:
|
) -> Association:
|
||||||
|
try:
|
||||||
save = SavesService().get(pk=save_uuid)
|
save = SavesService().get(pk=save_uuid)
|
||||||
|
|
||||||
defaults = dict(
|
defaults = dict(
|
||||||
|
@ -70,6 +79,8 @@ class AssociationsService:
|
||||||
result.save()
|
result.save()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
except ValidationError as exception:
|
||||||
|
raise self.Invalid.from_django_validation_error(exception)
|
||||||
|
|
||||||
def get(self,
|
def get(self,
|
||||||
*,
|
*,
|
||||||
|
@ -87,7 +98,7 @@ class AssociationsService:
|
||||||
|
|
||||||
return query_set.get(pk=pk)
|
return query_set.get(pk=pk)
|
||||||
except Association.DoesNotExist as exception:
|
except Association.DoesNotExist as exception:
|
||||||
raise self.AssociationNotFound(
|
raise self.NotFound(
|
||||||
f'Association not found: pk=`{pk}`',
|
f'Association not found: pk=`{pk}`',
|
||||||
) from exception
|
) from exception
|
||||||
|
|
||||||
|
@ -112,6 +123,7 @@ class AssociationsService:
|
||||||
pk: uuid.UUID,
|
pk: uuid.UUID,
|
||||||
update: AssociationUpdateIn,
|
update: AssociationUpdateIn,
|
||||||
) -> Association:
|
) -> Association:
|
||||||
|
try:
|
||||||
association = self.get(pk=pk)
|
association = self.get(pk=pk)
|
||||||
association.target_title = update.target_title
|
association.target_title = update.target_title
|
||||||
association.target_description = update.target_description
|
association.target_description = update.target_description
|
||||||
|
@ -127,6 +139,8 @@ class AssociationsService:
|
||||||
association.save()
|
association.save()
|
||||||
|
|
||||||
return association
|
return association
|
||||||
|
except ValidationError as exception:
|
||||||
|
raise self.Invalid.from_django_validation_error(exception)
|
||||||
|
|
||||||
def archive(self, *, pk: uuid.UUID) -> bool:
|
def archive(self, *, pk: uuid.UUID) -> bool:
|
||||||
association = self.get(pk=pk)
|
association = self.get(pk=pk)
|
||||||
|
|
|
@ -5,19 +5,27 @@ import hashlib
|
||||||
import typing
|
import typing
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
from hotpocket_backend.apps.core.services import get_adapter
|
from hotpocket_backend.apps.core.services import get_adapter
|
||||||
from hotpocket_backend.apps.saves.models import Save
|
from hotpocket_backend.apps.saves.models import Save
|
||||||
from hotpocket_backend.apps.saves.types import PSaveAdapter
|
from hotpocket_backend.apps.saves.types import PSaveAdapter
|
||||||
from hotpocket_soa.dto.saves import ImportedSaveIn, SaveIn, SavesQuery
|
from hotpocket_soa.dto.saves import ImportedSaveIn, SaveIn, SavesQuery
|
||||||
|
from hotpocket_soa.exceptions.backend import (
|
||||||
|
Invalid as InvalidError,
|
||||||
|
NotFound as NotFoundError,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class SavesService:
|
class SavesService:
|
||||||
class SavesServiceError(Exception):
|
class SavesServiceError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class SaveNotFound(SavesServiceError):
|
class Invalid(InvalidError, SavesServiceError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class NotFound(NotFoundError, SavesServiceError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -36,6 +44,7 @@ class SavesService:
|
||||||
account_uuid: uuid.UUID,
|
account_uuid: uuid.UUID,
|
||||||
save: SaveIn | ImportedSaveIn,
|
save: SaveIn | ImportedSaveIn,
|
||||||
) -> Save:
|
) -> Save:
|
||||||
|
try:
|
||||||
key = hashlib.sha256(save.url.encode('utf-8')).hexdigest()
|
key = hashlib.sha256(save.url.encode('utf-8')).hexdigest()
|
||||||
|
|
||||||
defaults = dict(
|
defaults = dict(
|
||||||
|
@ -59,12 +68,14 @@ class SavesService:
|
||||||
save_object.save()
|
save_object.save()
|
||||||
|
|
||||||
return save_object
|
return save_object
|
||||||
|
except ValidationError as exception:
|
||||||
|
raise self.Invalid.from_django_validation_error(exception)
|
||||||
|
|
||||||
def get(self, *, pk: uuid.UUID) -> Save:
|
def get(self, *, pk: uuid.UUID) -> Save:
|
||||||
try:
|
try:
|
||||||
return Save.active_objects.get(pk=pk)
|
return Save.active_objects.get(pk=pk)
|
||||||
except Save.DoesNotExist as exception:
|
except Save.DoesNotExist as exception:
|
||||||
raise self.SaveNotFound(
|
raise self.NotFound(
|
||||||
f'Save not found: pk=`{pk}`',
|
f'Save not found: pk=`{pk}`',
|
||||||
) from exception
|
) from exception
|
||||||
|
|
||||||
|
|
|
@ -46,3 +46,39 @@ def version(request: HttpRequest) -> dict:
|
||||||
return {
|
return {
|
||||||
'VERSION': backend_version,
|
'VERSION': backend_version,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def appearance_settings(request: HttpRequest) -> dict:
|
||||||
|
theme = 'hotpocket'
|
||||||
|
result = {
|
||||||
|
'theme': theme,
|
||||||
|
'light_mode': False,
|
||||||
|
'theme_css': 'ui/css/bootstrap-hotpocket.min.css',
|
||||||
|
}
|
||||||
|
|
||||||
|
if request.user.is_anonymous is False:
|
||||||
|
theme = request.user.settings.get('theme', 'hotpocket')
|
||||||
|
result.update({
|
||||||
|
'theme': theme,
|
||||||
|
'light_mode': request.user.settings['light_mode'],
|
||||||
|
})
|
||||||
|
|
||||||
|
match theme:
|
||||||
|
case 'bootstrap':
|
||||||
|
result['theme_css'] = 'ui/css/bootstrap.min.css'
|
||||||
|
|
||||||
|
case 'cosmo':
|
||||||
|
result['theme_css'] = 'ui/css/cosmo.min.css'
|
||||||
|
|
||||||
|
case 'solar':
|
||||||
|
result['theme_css'] = 'ui/css/solar.min.css'
|
||||||
|
|
||||||
|
case 'sandstone':
|
||||||
|
result['theme_css'] = 'ui/css/sandstone.min.css'
|
||||||
|
|
||||||
|
case 'sketchy':
|
||||||
|
result['theme_css'] = 'ui/css/sketchy.min.css'
|
||||||
|
|
||||||
|
return {
|
||||||
|
'APPEARANCE_SETTINGS': result,
|
||||||
|
}
|
||||||
|
|
|
@ -143,13 +143,20 @@ class SettingsForm(Form):
|
||||||
|
|
||||||
theme = forms.ChoiceField(
|
theme = forms.ChoiceField(
|
||||||
label=_('Theme'),
|
label=_('Theme'),
|
||||||
disabled=True,
|
disabled=False,
|
||||||
required=False,
|
required=False,
|
||||||
choices=[
|
choices=[
|
||||||
(None, _('Bootstrap')),
|
(None, _('BTHLabs')),
|
||||||
|
('bootstrap', _('Bootstrap')),
|
||||||
('cosmo', _('Cosmo')),
|
('cosmo', _('Cosmo')),
|
||||||
|
('solar', _('Solar')),
|
||||||
|
('sandstone', _('Sandstone')),
|
||||||
|
('sketchy', _('Sketchy')),
|
||||||
],
|
],
|
||||||
show_hidden_initial=True,
|
)
|
||||||
|
light_mode = forms.BooleanField(
|
||||||
|
label=_('Use light mode'),
|
||||||
|
required=False,
|
||||||
)
|
)
|
||||||
auto_load_embeds = forms.ChoiceField(
|
auto_load_embeds = forms.ChoiceField(
|
||||||
label=_('Auto load embedded content'),
|
label=_('Auto load embedded content'),
|
||||||
|
@ -168,6 +175,7 @@ class SettingsForm(Form):
|
||||||
def get_layout_fields(self) -> list[str]:
|
def get_layout_fields(self) -> list[str]:
|
||||||
return [
|
return [
|
||||||
'theme',
|
'theme',
|
||||||
|
'light_mode',
|
||||||
'auto_load_embeds',
|
'auto_load_embeds',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ from bthlabs_jsonrpc_core import register_method
|
||||||
from django import db
|
from django import db
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
|
|
||||||
|
from hotpocket_backend.apps.core.rpc import wrap_soa_errors
|
||||||
from hotpocket_soa.services import (
|
from hotpocket_soa.services import (
|
||||||
AccessTokensService,
|
AccessTokensService,
|
||||||
AccountsService,
|
AccountsService,
|
||||||
|
@ -17,6 +18,7 @@ LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@register_method('accounts.access_tokens.create', namespace='accounts')
|
@register_method('accounts.access_tokens.create', namespace='accounts')
|
||||||
|
@wrap_soa_errors
|
||||||
def create(request: HttpRequest,
|
def create(request: HttpRequest,
|
||||||
auth_key: str,
|
auth_key: str,
|
||||||
meta: dict,
|
meta: dict,
|
||||||
|
@ -27,7 +29,7 @@ def create(request: HttpRequest,
|
||||||
account_uuid=None,
|
account_uuid=None,
|
||||||
key=auth_key,
|
key=auth_key,
|
||||||
)
|
)
|
||||||
except AuthKeysService.AuthKeyNotFound as exception:
|
except AuthKeysService.NotFound as exception:
|
||||||
LOGGER.error(
|
LOGGER.error(
|
||||||
'Unable to issue access token: %s',
|
'Unable to issue access token: %s',
|
||||||
exception,
|
exception,
|
||||||
|
@ -37,7 +39,7 @@ def create(request: HttpRequest,
|
||||||
|
|
||||||
try:
|
try:
|
||||||
account = AccountsService().get(pk=auth_key_object.account_uuid)
|
account = AccountsService().get(pk=auth_key_object.account_uuid)
|
||||||
except AccountsService.AccountNotFound as exception:
|
except AccountsService.NotFound as exception:
|
||||||
LOGGER.error(
|
LOGGER.error(
|
||||||
'Unable to issue access token: %s',
|
'Unable to issue access token: %s',
|
||||||
exception,
|
exception,
|
||||||
|
|
|
@ -44,7 +44,7 @@ def check_access_token(request: HttpRequest,
|
||||||
access_token=access_token_object,
|
access_token=access_token_object,
|
||||||
update=meta_update,
|
update=meta_update,
|
||||||
)
|
)
|
||||||
except AccessTokensService.AccessTokenNotFound as exception:
|
except AccessTokensService.NotFound as exception:
|
||||||
LOGGER.error(
|
LOGGER.error(
|
||||||
'Access Token not found: account_uuid=`%s` key=`%s`',
|
'Access Token not found: account_uuid=`%s` key=`%s`',
|
||||||
request.user.pk,
|
request.user.pk,
|
||||||
|
@ -52,7 +52,7 @@ def check_access_token(request: HttpRequest,
|
||||||
exc_info=exception,
|
exc_info=exception,
|
||||||
)
|
)
|
||||||
result = False
|
result = False
|
||||||
except AccessTokensService.AccessTokenAccessDenied as exception:
|
except AccessTokensService.AccessDenied as exception:
|
||||||
LOGGER.error(
|
LOGGER.error(
|
||||||
'Access Token access denied: account_uuid=`%s` key=`%s`',
|
'Access Token access denied: account_uuid=`%s` key=`%s`',
|
||||||
request.user.pk,
|
request.user.pk,
|
||||||
|
|
|
@ -4,11 +4,13 @@ from __future__ import annotations
|
||||||
from bthlabs_jsonrpc_core import register_method
|
from bthlabs_jsonrpc_core import register_method
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
|
|
||||||
|
from hotpocket_backend.apps.core.rpc import wrap_soa_errors
|
||||||
from hotpocket_backend.apps.ui.services.workflows import CreateSaveWorkflow
|
from hotpocket_backend.apps.ui.services.workflows import CreateSaveWorkflow
|
||||||
from hotpocket_soa.dto.associations import AssociationOut
|
from hotpocket_soa.dto.associations import AssociationOut
|
||||||
|
|
||||||
|
|
||||||
@register_method(method='saves.create')
|
@register_method(method='saves.create')
|
||||||
|
@wrap_soa_errors
|
||||||
def create(request: HttpRequest, url: str) -> AssociationOut:
|
def create(request: HttpRequest, url: str) -> AssociationOut:
|
||||||
association = CreateSaveWorkflow().run_rpc(
|
association = CreateSaveWorkflow().run_rpc(
|
||||||
request=request,
|
request=request,
|
||||||
|
|
|
@ -27,7 +27,7 @@ class UIAccessTokensService:
|
||||||
account_uuid=account_uuid,
|
account_uuid=account_uuid,
|
||||||
pk=pk,
|
pk=pk,
|
||||||
)
|
)
|
||||||
except AccessTokensService.AccessTokenNotFound as exception:
|
except AccessTokensService.NotFound as exception:
|
||||||
LOGGER.error(
|
LOGGER.error(
|
||||||
'Access Token not found: account_uuid=`%s` pk=`%s`',
|
'Access Token not found: account_uuid=`%s` pk=`%s`',
|
||||||
account_uuid,
|
account_uuid,
|
||||||
|
@ -35,7 +35,7 @@ class UIAccessTokensService:
|
||||||
exc_info=exception,
|
exc_info=exception,
|
||||||
)
|
)
|
||||||
raise Http404()
|
raise Http404()
|
||||||
except AccessTokensService.AccessTokenAccessDenied as exception:
|
except AccessTokensService.AccessDenied as exception:
|
||||||
LOGGER.error(
|
LOGGER.error(
|
||||||
'Access Token access denied: account_uuid=`%s` pk=`%s`',
|
'Access Token access denied: account_uuid=`%s` pk=`%s`',
|
||||||
account_uuid,
|
account_uuid,
|
||||||
|
|
|
@ -34,7 +34,7 @@ class UIAssociationsService:
|
||||||
with_target=True,
|
with_target=True,
|
||||||
allow_archived=allow_archived,
|
allow_archived=allow_archived,
|
||||||
)
|
)
|
||||||
except AssociationsService.AssociationNotFound as exception:
|
except AssociationsService.NotFound as exception:
|
||||||
LOGGER.error(
|
LOGGER.error(
|
||||||
'Association not found: account_uuid=`%s` pk=`%s`',
|
'Association not found: account_uuid=`%s` pk=`%s`',
|
||||||
account_uuid,
|
account_uuid,
|
||||||
|
@ -42,7 +42,7 @@ class UIAssociationsService:
|
||||||
exc_info=exception,
|
exc_info=exception,
|
||||||
)
|
)
|
||||||
raise Http404()
|
raise Http404()
|
||||||
except AssociationsService.AssociationAccessDenied as exception:
|
except AssociationsService.AccessDenied as exception:
|
||||||
LOGGER.error(
|
LOGGER.error(
|
||||||
'Association access denied: account_uuid=`%s` pk=`%s`',
|
'Association access denied: account_uuid=`%s` pk=`%s`',
|
||||||
account_uuid,
|
account_uuid,
|
||||||
|
|
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import csv
|
import csv
|
||||||
import datetime
|
import datetime
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
@ -13,16 +14,28 @@ from django.utils.timezone import get_current_timezone
|
||||||
from hotpocket_backend.apps.ui.services.workflows import ImportSaveWorkflow
|
from hotpocket_backend.apps.ui.services.workflows import ImportSaveWorkflow
|
||||||
from hotpocket_backend.apps.ui.tasks import import_from_pocket
|
from hotpocket_backend.apps.ui.tasks import import_from_pocket
|
||||||
from hotpocket_common.uuid import uuid7_from_timestamp
|
from hotpocket_common.uuid import uuid7_from_timestamp
|
||||||
|
from hotpocket_soa.services import SavesService
|
||||||
|
|
||||||
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class UIImportsService:
|
class UIImportsService:
|
||||||
def import_from_pocket(self,
|
def import_from_pocket(self,
|
||||||
*,
|
*,
|
||||||
|
job: str,
|
||||||
account_uuid: uuid.UUID,
|
account_uuid: uuid.UUID,
|
||||||
csv_path: str,
|
csv_path: str,
|
||||||
) -> list[tuple[uuid.UUID, uuid.UUID]]:
|
) -> list[tuple[uuid.UUID, uuid.UUID]]:
|
||||||
result = []
|
LOGGER.info(
|
||||||
|
'Starting import job: job=`%s` account_uuid=`%s`',
|
||||||
|
job,
|
||||||
|
account_uuid,
|
||||||
|
extra={
|
||||||
|
'job': job,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
result = []
|
||||||
with db.transaction.atomic():
|
with db.transaction.atomic():
|
||||||
try:
|
try:
|
||||||
with open(csv_path, 'r', encoding='utf-8') as csv_file:
|
with open(csv_path, 'r', encoding='utf-8') as csv_file:
|
||||||
|
@ -34,13 +47,14 @@ class UIImportsService:
|
||||||
current_timezone = get_current_timezone()
|
current_timezone = get_current_timezone()
|
||||||
|
|
||||||
is_header = False
|
is_header = False
|
||||||
for row in csv_reader:
|
for row_number, row in enumerate(csv_reader, start=1):
|
||||||
if is_header is False:
|
if is_header is False:
|
||||||
is_header = True
|
is_header = True
|
||||||
continue
|
continue
|
||||||
|
|
||||||
timestamp = int(row['time_added'])
|
timestamp = int(row['time_added'])
|
||||||
|
|
||||||
|
try:
|
||||||
save, association = ImportSaveWorkflow().run(
|
save, association = ImportSaveWorkflow().run(
|
||||||
account_uuid=account_uuid,
|
account_uuid=account_uuid,
|
||||||
url=row['url'],
|
url=row['url'],
|
||||||
|
@ -50,6 +64,18 @@ class UIImportsService:
|
||||||
timestamp, tz=current_timezone,
|
timestamp, tz=current_timezone,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
except SavesService.Invalid as exception:
|
||||||
|
LOGGER.error(
|
||||||
|
'Import error: row_number=`%d` url=`%s` exception=`%s`',
|
||||||
|
row_number,
|
||||||
|
row['url'],
|
||||||
|
exception,
|
||||||
|
exc_info=exception,
|
||||||
|
extra={
|
||||||
|
'job': job,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
result.append((save.pk, association.pk))
|
result.append((save.pk, association.pk))
|
||||||
finally:
|
finally:
|
||||||
|
@ -64,6 +90,7 @@ class UIImportsService:
|
||||||
) -> AsyncResult:
|
) -> AsyncResult:
|
||||||
return import_from_pocket.apply_async(
|
return import_from_pocket.apply_async(
|
||||||
kwargs={
|
kwargs={
|
||||||
|
'job': str(uuid.uuid4()),
|
||||||
'account_uuid': account_uuid,
|
'account_uuid': account_uuid,
|
||||||
'csv_path': csv_path,
|
'csv_path': csv_path,
|
||||||
},
|
},
|
||||||
|
|
|
@ -19,7 +19,7 @@ class UISavesService:
|
||||||
def get_or_404(self, *, pk: uuid.UUID) -> SaveOut:
|
def get_or_404(self, *, pk: uuid.UUID) -> SaveOut:
|
||||||
try:
|
try:
|
||||||
return SavesService().get(pk=pk)
|
return SavesService().get(pk=pk)
|
||||||
except SavesService.SaveNotFound as exception:
|
except SavesService.NotFound as exception:
|
||||||
LOGGER.error(
|
LOGGER.error(
|
||||||
'Save not found: pk=`%s`', pk, exc_info=exception,
|
'Save not found: pk=`%s`', pk, exc_info=exception,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from bthlabs_jsonrpc_core import JSONRPCInternalError
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.core.exceptions import ValidationError
|
|
||||||
import django.db
|
import django.db
|
||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
|
@ -14,7 +12,6 @@ from hotpocket_backend.apps.accounts.types import PAccount
|
||||||
from hotpocket_soa.dto.associations import AssociationOut
|
from hotpocket_soa.dto.associations import AssociationOut
|
||||||
from hotpocket_soa.dto.celery import AsyncResultOut
|
from hotpocket_soa.dto.celery import AsyncResultOut
|
||||||
from hotpocket_soa.dto.saves import SaveIn, SaveOut
|
from hotpocket_soa.dto.saves import SaveIn, SaveOut
|
||||||
from hotpocket_soa.services import SavesService
|
|
||||||
|
|
||||||
from .base import SaveWorkflow
|
from .base import SaveWorkflow
|
||||||
|
|
||||||
|
@ -73,14 +70,8 @@ class CreateSaveWorkflow(SaveWorkflow):
|
||||||
account: PAccount,
|
account: PAccount,
|
||||||
url: str,
|
url: str,
|
||||||
) -> AssociationOut:
|
) -> AssociationOut:
|
||||||
try:
|
|
||||||
save, association, processing_result = self.create_associate_and_process(
|
save, association, processing_result = self.create_associate_and_process(
|
||||||
account, url,
|
account, url,
|
||||||
)
|
)
|
||||||
|
|
||||||
return association
|
return association
|
||||||
except SavesService.SavesServiceError as exception:
|
|
||||||
if isinstance(exception.__cause__, ValidationError) is True:
|
|
||||||
raise JSONRPCInternalError(data=exception.__cause__)
|
|
||||||
|
|
||||||
raise
|
|
||||||
|
|
6
services/backend/hotpocket_backend/apps/ui/static/ui/css/bootstrap-hotpocket.min.css
vendored
Normal file
12
services/backend/hotpocket_backend/apps/ui/static/ui/css/cosmo.min.css
vendored
Normal file
12
services/backend/hotpocket_backend/apps/ui/static/ui/css/sandstone.min.css
vendored
Normal file
12
services/backend/hotpocket_backend/apps/ui/static/ui/css/sketchy.min.css
vendored
Normal file
12
services/backend/hotpocket_backend/apps/ui/static/ui/css/solar.min.css
vendored
Normal file
Before Width: | Height: | Size: 874 B After Width: | Height: | Size: 777 B |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
|
@ -11,6 +11,7 @@ LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def import_from_pocket(*,
|
def import_from_pocket(*,
|
||||||
|
job: str,
|
||||||
account_uuid: uuid.UUID,
|
account_uuid: uuid.UUID,
|
||||||
csv_path: str,
|
csv_path: str,
|
||||||
) -> list[tuple[uuid.UUID, uuid.UUID]]:
|
) -> list[tuple[uuid.UUID, uuid.UUID]]:
|
||||||
|
@ -18,6 +19,7 @@ def import_from_pocket(*,
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return UIImportsService().import_from_pocket(
|
return UIImportsService().import_from_pocket(
|
||||||
|
job=job,
|
||||||
account_uuid=account_uuid,
|
account_uuid=account_uuid,
|
||||||
csv_path=csv_path,
|
csv_path=csv_path,
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,14 +10,18 @@
|
||||||
|_|
|
|_|
|
||||||
production
|
production
|
||||||
-->
|
-->
|
||||||
<html lang="en" data-bs-theme="dark">
|
<html lang="en" data-bs-theme="{% if APPEARANCE_SETTINGS.light_mode %}light{% else %}dark{% endif %}">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover,user-scalable=no">
|
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover,user-scalable=no">
|
||||||
<meta name="generator" content="pl.bthlabs.HotPocket.backend@{{ IMAGE_ID }}">
|
<meta name="generator" content="pl.bthlabs.HotPocket.backend@{{ IMAGE_ID }}">
|
||||||
<meta name="theme-color" content="#2b3035"/>
|
{% if APPEARANCE_SETTINGS.light_mode %}
|
||||||
|
<meta name="theme-color" content="#f8f9fa" />
|
||||||
|
{% else %}
|
||||||
|
<meta name="theme-color" content="#2b3035" />
|
||||||
|
{% endif %}
|
||||||
<title>{% block title %}{% translate 'Not Found' %}{% endblock %} | {{ SITE_TITLE }}</title>
|
<title>{% block title %}{% translate 'Not Found' %}{% endblock %} | {{ SITE_TITLE }}</title>
|
||||||
<link href="{% static 'ui/css/bootstrap.min.css' %}" rel="stylesheet">
|
<link href="{% static APPEARANCE_SETTINGS.theme_css %}" rel="stylesheet">
|
||||||
<link href="{% static 'ui/css/bootstrap-icons.min.css' %}" rel="stylesheet">
|
<link href="{% static 'ui/css/bootstrap-icons.min.css' %}" rel="stylesheet">
|
||||||
<link href="{% static 'ui/css/hotpocket-backend.css' %}" rel="stylesheet">
|
<link href="{% static 'ui/css/hotpocket-backend.css' %}" rel="stylesheet">
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
|
|
@ -9,6 +9,10 @@ from hotpocket_backend.apps.core.conf import settings
|
||||||
|
|
||||||
|
|
||||||
def manifest_json(request: HttpRequest) -> JsonResponse:
|
def manifest_json(request: HttpRequest) -> JsonResponse:
|
||||||
|
light_theme = False
|
||||||
|
if request.user.is_anonymous is False:
|
||||||
|
light_theme = request.user.settings.get('light_theme', None) or False
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
'name': settings.SITE_TITLE,
|
'name': settings.SITE_TITLE,
|
||||||
'short_name': settings.SITE_SHORT_TITLE,
|
'short_name': settings.SITE_SHORT_TITLE,
|
||||||
|
@ -16,8 +20,17 @@ def manifest_json(request: HttpRequest) -> JsonResponse:
|
||||||
reverse('ui.associations.browse'),
|
reverse('ui.associations.browse'),
|
||||||
),
|
),
|
||||||
'display': 'standalone',
|
'display': 'standalone',
|
||||||
'background_color': '#212529',
|
'background_color': (
|
||||||
'theme_color': '#2b3035',
|
'#212529'
|
||||||
|
if light_theme is False
|
||||||
|
else '#ffffff'
|
||||||
|
),
|
||||||
|
'theme_color': (
|
||||||
|
'#2b3035'
|
||||||
|
if light_theme is False
|
||||||
|
else
|
||||||
|
'#f8f9fa'
|
||||||
|
),
|
||||||
'icons': [
|
'icons': [
|
||||||
{
|
{
|
||||||
'src': request.build_absolute_uri(
|
'src': request.build_absolute_uri(
|
||||||
|
|
|
@ -4,7 +4,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from .base import * # noqa: F403
|
from .webapp import * # noqa: F403
|
||||||
|
|
||||||
DEBUG = (
|
DEBUG = (
|
||||||
os.environ.get('HOTPOCKET_BACKEND_DEBUG', 'false').lower() == 'true'
|
os.environ.get('HOTPOCKET_BACKEND_DEBUG', 'false').lower() == 'true'
|
||||||
|
@ -12,23 +12,8 @@ DEBUG = (
|
||||||
|
|
||||||
ALLOWED_HOSTS = os.environ.get('HOTPOCKET_BACKEND_ALLOWED_HOSTS', '*').split(',')
|
ALLOWED_HOSTS = os.environ.get('HOTPOCKET_BACKEND_ALLOWED_HOSTS', '*').split(',')
|
||||||
|
|
||||||
INSTALLED_APPS += [ # noqa: F405
|
|
||||||
'crispy_forms',
|
|
||||||
'crispy_bootstrap5',
|
|
||||||
'django_htmx',
|
|
||||||
]
|
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
'hotpocket_backend.apps.core.middleware.RequestIDMiddleware',
|
*MIDDLEWARE, # noqa: F405
|
||||||
'django.middleware.security.SecurityMiddleware',
|
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
|
||||||
'django.middleware.common.CommonMiddleware',
|
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
|
||||||
'social_django.middleware.SocialAuthExceptionMiddleware',
|
|
||||||
'django_htmx.middleware.HtmxMiddleware',
|
|
||||||
'whitenoise.middleware.WhiteNoiseMiddleware',
|
'whitenoise.middleware.WhiteNoiseMiddleware',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ TEMPLATES = [
|
||||||
'hotpocket_backend.apps.ui.context_processors.htmx',
|
'hotpocket_backend.apps.ui.context_processors.htmx',
|
||||||
'hotpocket_backend.apps.ui.context_processors.debug',
|
'hotpocket_backend.apps.ui.context_processors.debug',
|
||||||
'hotpocket_backend.apps.ui.context_processors.version',
|
'hotpocket_backend.apps.ui.context_processors.version',
|
||||||
|
'hotpocket_backend.apps.ui.context_processors.appearance_settings',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -13,7 +13,7 @@ cat <<EOF
|
||||||
|_|
|
|_|
|
||||||
production
|
production
|
||||||
|
|
||||||
HotPocket v25.10.4 [${HOTPOCKET_BACKEND_IMAGE_ID}] (https://hotpocket.app/)
|
HotPocket v25.10.21 [${HOTPOCKET_BACKEND_IMAGE_ID}] (https://hotpocket.app/)
|
||||||
Copyright 2025-present by BTHLabs. All rights reserved. (https://bthlabs.pl/)
|
Copyright 2025-present by BTHLabs. All rights reserved. (https://bthlabs.pl/)
|
||||||
Licensed under Apache-2.0
|
Licensed under Apache-2.0
|
||||||
EOF
|
EOF
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "hotpocket-backend",
|
"name": "hotpocket-backend",
|
||||||
"version": "25.10.4",
|
"version": "25.10.21",
|
||||||
"description": "HotPocket Backend",
|
"description": "HotPocket Backend",
|
||||||
"main": "hotpocket_backend/apps/frontend/src/index.js",
|
"main": "hotpocket_backend/apps/frontend/src/index.js",
|
||||||
"repository": "https://git.bthlabs.pl/tomekwojcik/hotpocket",
|
"repository": "https://git.bthlabs.pl/tomekwojcik/hotpocket",
|
||||||
|
|
1974
services/backend/poetry.lock
generated
|
@ -1,6 +1,6 @@
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "hotpocket-backend"
|
name = "hotpocket-backend"
|
||||||
version = "25.10.4"
|
version = "25.10.21"
|
||||||
description = "HotPocket Backend"
|
description = "HotPocket Backend"
|
||||||
authors = ["Tomek Wójcik <contact@bthlabs.pl>"]
|
authors = ["Tomek Wójcik <contact@bthlabs.pl>"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
@ -16,45 +16,45 @@ python = "^3.12"
|
||||||
bthlabs-jsonrpc-django = "1.2.0"
|
bthlabs-jsonrpc-django = "1.2.0"
|
||||||
celery = "5.5.3"
|
celery = "5.5.3"
|
||||||
crispy-bootstrap5 = "2025.6"
|
crispy-bootstrap5 = "2025.6"
|
||||||
django = "5.2.3"
|
django = "5.2.7"
|
||||||
django-cors-headers = "4.7.0"
|
django-cors-headers = "4.9.0"
|
||||||
django-crispy-forms = "2.4"
|
django-crispy-forms = "2.4"
|
||||||
django-htmx = "1.23.2"
|
django-htmx = "1.26.0"
|
||||||
hotpocket-common = {path = "../packages/common", develop = true}
|
hotpocket-common = {path = "../packages/common", develop = true}
|
||||||
hotpocket-soa = {path = "../packages/soa", develop = true}
|
hotpocket-soa = {path = "../packages/soa", develop = true}
|
||||||
keep-it-secret = {version = "1.2.0", extras = ["aws", "vault"]}
|
keep-it-secret = {version = "1.2.0", extras = ["aws", "vault"]}
|
||||||
psycopg = {version = "3.2.9", extras = ["binary"]}
|
psycopg = {version = "3.2.10", extras = ["binary"]}
|
||||||
pydantic = "2.11.7"
|
pydantic = "2.12.2"
|
||||||
pyquery = "2.0.1"
|
pyquery = "2.0.1"
|
||||||
requests = "2.32.4"
|
requests = "2.32.5"
|
||||||
social-auth-app-django = "5.5.1"
|
social-auth-app-django = "5.6.0"
|
||||||
social-auth-core = "4.7.0"
|
social-auth-core = "4.8.1"
|
||||||
sqlalchemy = "2.0.41"
|
sqlalchemy = "2.0.44"
|
||||||
uuid6 = "2025.0.0"
|
uuid6 = "2025.0.1"
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
django-extensions = "4.1"
|
django-extensions = "4.1"
|
||||||
factory-boy = "3.3.3"
|
factory-boy = "3.3.3"
|
||||||
flake8 = "7.3.0"
|
flake8 = "7.3.0"
|
||||||
flake8-commas = "4.0.0"
|
flake8-commas = "4.0.0"
|
||||||
freezegun = "1.5.2"
|
freezegun = "1.5.5"
|
||||||
hotpocket-backend-testing = {path = "testing", develop = true}
|
hotpocket-backend-testing = {path = "testing", develop = true}
|
||||||
hotpocket-testing = {path = "../packages/testing", develop = true}
|
hotpocket-testing = {path = "../packages/testing", develop = true}
|
||||||
hotpocket-workspace-tools = {path = "../packages/workspace_tools", develop = true}
|
hotpocket-workspace-tools = {path = "../packages/workspace_tools", develop = true}
|
||||||
invoke = "2.2.0"
|
invoke = "2.2.1"
|
||||||
ipdb = "0.13.13"
|
ipdb = "0.13.13"
|
||||||
ipython = "9.3.0"
|
ipython = "9.6.0"
|
||||||
isort = "6.0.1"
|
isort = "7.0.0"
|
||||||
mypy = "1.16.1"
|
mypy = "1.18.2"
|
||||||
pytest = "8.4.1"
|
pytest = "8.4.2"
|
||||||
pytest-django = "4.11.1"
|
pytest-django = "4.11.1"
|
||||||
pytest-env = "1.1.5"
|
pytest-env = "1.2.0"
|
||||||
pytest-mock = "3.14.1"
|
pytest-mock = "3.15.1"
|
||||||
|
|
||||||
[tool.poetry.group.deployment.dependencies]
|
[tool.poetry.group.deployment.dependencies]
|
||||||
gunicorn = {version = "23.0.0", extras = ["setproctitle"]}
|
gunicorn = {version = "23.0.0", extras = ["setproctitle"]}
|
||||||
gunicorn_worker_healthcheck = "1.0.0"
|
gunicorn_worker_healthcheck = "1.0.0"
|
||||||
whitenoise = "6.9.0"
|
whitenoise = "6.11.0"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core"]
|
requires = ["poetry-core"]
|
||||||
|
|