You've already forked hotpocket
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3b1aba9672 | |||
| 22061486a8 | |||
| 38785ccf92 | |||
| 1f78a4a079 | |||
| 20fa33abeb | |||
| 16a9c73624 | |||
| b358ef6686 | |||
| ac9c7a81c3 | |||
| e800d0c16c | |||
| d8bbe57b17 |
19
.gitea/actions/setup-ansible/action.yaml
Normal file
19
.gitea/actions/setup-ansible/action.yaml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
name: "Set up Ansible"
|
||||||
|
description: "Downloads and installs Ansible"
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: "Ansible version to install"
|
||||||
|
required: false
|
||||||
|
default: "10.2.0"
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: "Install Ansible"
|
||||||
|
shell: "bash"
|
||||||
|
env:
|
||||||
|
PIP_INDEX_URL: "https://nexus.bthlabs.pl/repository/pypi/simple/"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
python3 -m venv /opt/ansible
|
||||||
|
|
||||||
|
/opt/ansible/bin/pip install ansible==${{ inputs.version }}
|
||||||
83
.gitea/workflows/build-deployment-images.yaml
Normal file
83
.gitea/workflows/build-deployment-images.yaml
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
name: "Build deployment images"
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
target:
|
||||||
|
required: true
|
||||||
|
type: "string"
|
||||||
|
registry:
|
||||||
|
required: false
|
||||||
|
type: "string"
|
||||||
|
default: "docker-hosted.nexus.bthlabs.pl"
|
||||||
|
platform:
|
||||||
|
required: false
|
||||||
|
type: "string"
|
||||||
|
default: "linux/amd64,linux/arm64"
|
||||||
|
secrets:
|
||||||
|
VAULT_ROLE_ID:
|
||||||
|
required: true
|
||||||
|
VAULT_SECRET_ID:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
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/${{ inputs.registry }} username | DOCKER_USERNAME ;
|
||||||
|
gitea/data/${{ inputs.registry }} 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 Docker Registry"
|
||||||
|
uses: "docker/login-action@v3"
|
||||||
|
with:
|
||||||
|
registry: "${{ inputs.registry }}"
|
||||||
|
username: "${{ steps.import-secrets.outputs.DOCKER_USERNAME }}"
|
||||||
|
password: "${{ steps.import-secrets.outputs.DOCKER_PASSWORD }}"
|
||||||
|
- 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,target=max" \
|
||||||
|
--push \
|
||||||
|
--platform "${{ inputs.platform }}" \
|
||||||
|
--build-arg IMAGE_ID="${{ inputs.target }}.${SHORT_SHA}" \
|
||||||
|
--build-arg IMAGE_VERSION="${VERSION}" \
|
||||||
|
--build-arg IMAGE_REVISION="${SHORT_SHA}" \
|
||||||
|
-f services/backend/Dockerfile \
|
||||||
|
--target "${{ inputs.target }}" \
|
||||||
|
-t "${{ inputs.registry }}/hotpocket/backend:${{ inputs.target }}-${VERSION}-${BUILD}" \
|
||||||
|
services/
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: "Deploy to development"
|
name: "Development deployment"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -6,98 +6,28 @@ on:
|
|||||||
- "development"
|
- "development"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-deployment-images:
|
build-for-development:
|
||||||
name: "Build deployment images"
|
name: "Build"
|
||||||
runs-on: "ubuntu-latest"
|
uses: "./.gitea/workflows/build-deployment-images.yaml"
|
||||||
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:
|
with:
|
||||||
service: "backend"
|
target: "deployment"
|
||||||
- name: "Import Secrets"
|
platform: "linux/amd64"
|
||||||
id: "import-secrets"
|
registry: "nexus.bthlab.bthlabs.net:8002"
|
||||||
uses: "hashicorp/vault-action@v2"
|
secrets:
|
||||||
with:
|
VAULT_ROLE_ID: "${{ secrets.VAULT_ROLE_ID }}"
|
||||||
url: "https://vault.bthlabs.pl/"
|
VAULT_SECRET_ID: "${{ secrets.VAULT_SECRET_ID }}"
|
||||||
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:
|
deploy-to-deployment:
|
||||||
name: "Deploy"
|
name: "Deploy"
|
||||||
runs-on: "ubuntu-latest"
|
runs-on: "ubuntu-latest"
|
||||||
needs:
|
needs:
|
||||||
- "build-deployment-images"
|
- "build-for-development"
|
||||||
env:
|
env:
|
||||||
KUBERNETES_NAMESPACE: "hotpocket-development"
|
KUBERNETES_NAMESPACE: "hotpocket-development"
|
||||||
KUBERNETES_CLUSTER: "k8s.bthlab"
|
KUBERNETES_CLUSTER: "k8s.bthlab"
|
||||||
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"
|
- name: "Get build options"
|
||||||
id: "get-build-options"
|
id: "get-build-options"
|
||||||
uses: "./.gitea/actions/get-build-options"
|
uses: "./.gitea/actions/get-build-options"
|
||||||
@@ -122,7 +52,6 @@ jobs:
|
|||||||
gitea/data/k8s.bthlab config | KUBECONFIG_PAYLOAD
|
gitea/data/k8s.bthlab config | KUBECONFIG_PAYLOAD
|
||||||
- name: "Set up kubeconfig"
|
- name: "Set up kubeconfig"
|
||||||
env:
|
env:
|
||||||
COMPOSE_PROJECT: "${{ steps.get-run-info.outputs.compose-project }}"
|
|
||||||
KUBECONFIG_PAYLOAD: "${{ steps.import-secrets.outputs.KUBECONFIG_PAYLOAD }}"
|
KUBECONFIG_PAYLOAD: "${{ steps.import-secrets.outputs.KUBECONFIG_PAYLOAD }}"
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
@@ -134,30 +63,29 @@ jobs:
|
|||||||
/opt/k8s/bin/kubectl get node
|
/opt/k8s/bin/kubectl get node
|
||||||
- name: "Run `backend` Django migrations"
|
- name: "Run `backend` Django migrations"
|
||||||
env:
|
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 }}"
|
BACKEND_TAG: "deployment-${{ steps.get-backend-version.outputs.version }}-${{ steps.get-backend-version.outputs.build-number }}"
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
(
|
(
|
||||||
cd deployment/hotpocket.bthlab ;
|
cd deployment/hotpocket_bthlab ;
|
||||||
export KUBECONFIG="/opt/k8s/etc/kubeconfig" ;
|
export KUBECONFIG="/opt/k8s/etc/kubeconfig" ;
|
||||||
/opt/k8s/bin/kubectl config use-context ${KUBERNETES_CLUSTER} ;
|
/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} apply -f resources/backend/config-map-local-deps.yaml ;
|
||||||
|
/opt/k8s/bin/kubectl -n ${KUBERNETES_NAMESPACE} set image cronjobs/backend-job-migrations migrations=nexus.bthlab.bthlabs.net:8002/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} 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} 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
|
/opt/k8s/bin/kubectl -n ${KUBERNETES_NAMESPACE} wait --for=condition=complete --timeout=300s job/backend-job-migrations
|
||||||
)
|
)
|
||||||
- name: "Deploy"
|
- name: "Deploy"
|
||||||
env:
|
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 }}"
|
BACKEND_TAG: "deployment-${{ steps.get-backend-version.outputs.version }}-${{ steps.get-backend-version.outputs.build-number }}"
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
(
|
(
|
||||||
cd deployment/hotpocket.bthlab ;
|
cd deployment/hotpocket_bthlab ;
|
||||||
export KUBECONFIG="/opt/k8s/etc/kubeconfig" ;
|
export KUBECONFIG="/opt/k8s/etc/kubeconfig" ;
|
||||||
/opt/k8s/bin/kubectl config use-context ${KUBERNETES_CLUSTER} ;
|
/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 edit set image hotpocket-backend=nexus.bthlab.bthlabs.net:8002/hotpocket/backend:${BACKEND_TAG} ;
|
||||||
/opt/k8s/bin/kustomize build . | /opt/k8s/bin/kubectl apply -f -
|
/opt/k8s/bin/kustomize build . | /opt/k8s/bin/kubectl apply -f -
|
||||||
)
|
)
|
||||||
|
|||||||
76
.gitea/workflows/production.yaml
Normal file
76
.gitea/workflows/production.yaml
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
name: "Production deployment"
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: ["published"]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-for-production:
|
||||||
|
name: "Build"
|
||||||
|
uses: "./.gitea/workflows/build-deployment-images.yaml"
|
||||||
|
with:
|
||||||
|
target: "deployment"
|
||||||
|
platform: "linux/amd64"
|
||||||
|
secrets:
|
||||||
|
VAULT_ROLE_ID: "${{ secrets.VAULT_ROLE_ID }}"
|
||||||
|
VAULT_SECRET_ID: "${{ secrets.VAULT_SECRET_ID }}"
|
||||||
|
|
||||||
|
deploy-to-production:
|
||||||
|
name: "Deploy"
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
needs:
|
||||||
|
- "build-for-production"
|
||||||
|
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/hotpocket.app ansible_vault_payload | ANSIBLE_VAULT_PAYLOAD ;
|
||||||
|
gitea/data/hotpocket.app ansible_vault_password | ANSIBLE_VAULT_PASSWORD ;
|
||||||
|
gitea/data/hotpocket.app ansible_inventory_payload | ANSIBLE_INVENTORY_PAYLOAD ;
|
||||||
|
gitea/data/hotpocket.app ssh_key_payload | SSH_KEY_PAYLOAD
|
||||||
|
- name: "Setup Ansible"
|
||||||
|
uses: "./.gitea/actions/setup-ansible"
|
||||||
|
- name: "Prepare Ansible secrets"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
|
||||||
|
mkdir deployment/hotpocket_app/.ci
|
||||||
|
echo "${ANSIBLE_VAULT_PAYLOAD}" | base64 -d >"deployment/hotpocket_app/env_vars/production/vault.yaml"
|
||||||
|
echo "${ANSIBLE_VAULT_PASSWORD}" >"deployment/hotpocket_app/.ci/vault_password"
|
||||||
|
echo "${ANSIBLE_INVENTORY_PAYLOAD}" | base64 -d >"deployment/hotpocket_app/inventory_ci.yaml"
|
||||||
|
echo "${SSH_KEY_PAYLOAD}" | base64 -d >"deployment/hotpocket_app/.ci/ssh_key"
|
||||||
|
chmod 600 deployment/hotpocket_app/.ci/ssh_key
|
||||||
|
- name: "Engage!"
|
||||||
|
env:
|
||||||
|
VERSION: "${{ steps.get-backend-version.outputs.version }}"
|
||||||
|
BUILD: "${{ steps.get-backend-version.outputs.build-number }}"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
|
||||||
|
(
|
||||||
|
cd deployment/hotpocket_app ;
|
||||||
|
ANSIBLE_HOST_KEY_CHECKING="False" /opt/ansible/bin/ansible-playbook \
|
||||||
|
-i inventory_ci.yaml \
|
||||||
|
--vault-id hotpocket@.ci/vault_password \
|
||||||
|
-e @env_vars/production/vars.yaml \
|
||||||
|
-e @env_vars/production/vault.yaml \
|
||||||
|
-e hotpocket_app_image_tag="deployment-${VERSION}-${BUILD}" \
|
||||||
|
--limit "*.production.hotpocket.app" \
|
||||||
|
deploy.yaml
|
||||||
|
)
|
||||||
76
.gitea/workflows/staging.yaml
Normal file
76
.gitea/workflows/staging.yaml
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
name: "Staging deployment"
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: ["published"]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-for-staging:
|
||||||
|
name: "Build"
|
||||||
|
uses: "./.gitea/workflows/build-deployment-images.yaml"
|
||||||
|
with:
|
||||||
|
target: "aio"
|
||||||
|
platform: "linux/amd64"
|
||||||
|
secrets:
|
||||||
|
VAULT_ROLE_ID: "${{ secrets.VAULT_ROLE_ID }}"
|
||||||
|
VAULT_SECRET_ID: "${{ secrets.VAULT_SECRET_ID }}"
|
||||||
|
|
||||||
|
deploy-to-staging:
|
||||||
|
name: "Deploy"
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
needs:
|
||||||
|
- "build-for-staging"
|
||||||
|
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/staging.hotpocket.app ansible_vault_payload | ANSIBLE_VAULT_PAYLOAD ;
|
||||||
|
gitea/data/staging.hotpocket.app ansible_vault_password | ANSIBLE_VAULT_PASSWORD ;
|
||||||
|
gitea/data/staging.hotpocket.app ansible_inventory_payload | ANSIBLE_INVENTORY_PAYLOAD ;
|
||||||
|
gitea/data/staging.hotpocket.app ssh_key_payload | SSH_KEY_PAYLOAD
|
||||||
|
- name: "Setup Ansible"
|
||||||
|
uses: "./.gitea/actions/setup-ansible"
|
||||||
|
- name: "Prepare Ansible secrets"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
|
||||||
|
mkdir deployment/hotpocket_app/.ci
|
||||||
|
echo "${ANSIBLE_VAULT_PAYLOAD}" | base64 -d >"deployment/hotpocket_app/env_vars/staging/vault.yaml"
|
||||||
|
echo "${ANSIBLE_VAULT_PASSWORD}" >"deployment/hotpocket_app/.ci/vault_password"
|
||||||
|
echo "${ANSIBLE_INVENTORY_PAYLOAD}" | base64 -d >"deployment/hotpocket_app/inventory_ci.yaml"
|
||||||
|
echo "${SSH_KEY_PAYLOAD}" | base64 -d >"deployment/hotpocket_app/.ci/ssh_key"
|
||||||
|
chmod 600 deployment/hotpocket_app/.ci/ssh_key
|
||||||
|
- name: "Engage!"
|
||||||
|
env:
|
||||||
|
VERSION: "${{ steps.get-backend-version.outputs.version }}"
|
||||||
|
BUILD: "${{ steps.get-backend-version.outputs.build-number }}"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
|
||||||
|
(
|
||||||
|
cd deployment/hotpocket_app ;
|
||||||
|
ANSIBLE_HOST_KEY_CHECKING="False" /opt/ansible/bin/ansible-playbook \
|
||||||
|
-i inventory_ci.yaml \
|
||||||
|
--vault-id hotpocket@.ci/vault_password \
|
||||||
|
-e @env_vars/staging/vars.yaml \
|
||||||
|
-e @env_vars/staging/vault.yaml \
|
||||||
|
-e hotpocket_app_image_tag="aio-${VERSION}-${BUILD}" \
|
||||||
|
--limit "*.staging.hotpocket.app" \
|
||||||
|
deploy.yaml
|
||||||
|
)
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
.ci/
|
.ci/
|
||||||
.envrc*
|
.envrc*
|
||||||
.ipythonhome/
|
.ipythonhome/
|
||||||
|
services/vendor/
|
||||||
/docker-compose-ci-*.yaml
|
/docker-compose-ci-*.yaml
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ This repository contains the _HotPocket_ project.
|
|||||||
|
|
||||||
### Requirements:
|
### Requirements:
|
||||||
|
|
||||||
* Python 3.12,
|
* Python 3.13,
|
||||||
* Poetry 1.8.3,
|
* Poetry 2.2.1,
|
||||||
* `git-crypt`,
|
* `git-crypt`,
|
||||||
* Docker with Docker Compose and Buildx.
|
* Docker with Docker Compose and Buildx.
|
||||||
|
|
||||||
@@ -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.21-01
|
hotpocket/backend:aio-v25.11.19-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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
backend:
|
backend:
|
||||||
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:aio-v25.10.21-01"
|
image: "hotpocket/backend:aio-v25.11.19-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.21-01"
|
image: "hotpocket/backend:deployment-v25.11.19-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.21-01"
|
image: "hotpocket/backend:deployment-v25.11.19-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.21-01"
|
image: "hotpocket/backend:deployment-v25.11.19-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.21-01"
|
image: "hotpocket/backend:deployment-v25.11.19-01"
|
||||||
command:
|
command:
|
||||||
- "/srv/venv/bin/celery"
|
- "/srv/venv/bin/celery"
|
||||||
- "-A"
|
- "-A"
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
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
|
|
||||||
3
deployment/hotpocket_app/.gitignore
vendored
Normal file
3
deployment/hotpocket_app/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.ci/
|
||||||
|
inventory_ci.yaml
|
||||||
|
vault.yaml
|
||||||
5
deployment/hotpocket_app/deploy.yaml
Normal file
5
deployment/hotpocket_app/deploy.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
- name: "Deploy HotPocket"
|
||||||
|
hosts: "hotpocket_app"
|
||||||
|
roles:
|
||||||
|
- role: "hotpocket_app"
|
||||||
|
tags: ["hotpocket-app"]
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
export PIP_INDEX_URL="https://nexus.bthlabs.pl/repository/pypi/simple/"
|
||||||
|
/srv/venv/bin/pip install -r /srv/lib/backend/requirements.txt
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
(
|
||||||
|
cd /srv/app;
|
||||||
|
./manage.py collectstatic --no-input
|
||||||
|
)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
hotpocket-bthlabs>=25.10.28
|
||||||
60
deployment/hotpocket_app/env_vars/production/vars.yaml
Normal file
60
deployment/hotpocket_app/env_vars/production/vars.yaml
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
hotpocket_app:
|
||||||
|
deployment_directory: "/srv/hotpocket"
|
||||||
|
owner: "hotpocket"
|
||||||
|
group: "hotpocket"
|
||||||
|
mode: "fullstack"
|
||||||
|
loki:
|
||||||
|
url: "http://monitoring.vm.snakeweb.net.bthlabs.net:3100/loki/api/v1/push"
|
||||||
|
node: "home.vm.snakeweb.net"
|
||||||
|
docker:
|
||||||
|
extra_hosts:
|
||||||
|
- "home.vm:10.0.1.2"
|
||||||
|
backend:
|
||||||
|
image_tag: "{{ hotpocket_app_image_tag|default('deployment-v25.10.21-01') }}"
|
||||||
|
database:
|
||||||
|
name: "thisissecret"
|
||||||
|
user: "thisissecret"
|
||||||
|
host: "thisissecret"
|
||||||
|
rabbitmq:
|
||||||
|
vhost: "thisissecret"
|
||||||
|
user: "thisissecret"
|
||||||
|
host: "thisissecret"
|
||||||
|
model_auth_is_disabled: true
|
||||||
|
env: "production"
|
||||||
|
extra_env:
|
||||||
|
- "HOTPOCKET_BACKEND_SECRETS_PACKAGE=hotpocket_bthlabs.secrets"
|
||||||
|
- "VAULT_URL={{ hotpocket_app_secrets.backend.vault.url }}"
|
||||||
|
- "VAULT_ROLE_ID={{ hotpocket_app_secrets.backend.vault.role_id }}"
|
||||||
|
- "VAULT_SECRET_ID={{ hotpocket_app_secrets.backend.vault.secret_id }}"
|
||||||
|
oidc:
|
||||||
|
enabled: true
|
||||||
|
endpoint: "thisissecret"
|
||||||
|
display_name: "thisissecret"
|
||||||
|
webapp:
|
||||||
|
settings_module: "hotpocket_bthlabs.settings.webapp"
|
||||||
|
loki:
|
||||||
|
external_labels: "job=hotpocket,service=backend-webapp,environment=production"
|
||||||
|
allowed_hosts:
|
||||||
|
- "my.hotpocket.app"
|
||||||
|
admin:
|
||||||
|
settings_module: "hotpocket_bthlabs.settings.admin"
|
||||||
|
loki:
|
||||||
|
external_labels: "job=hotpocket,service=backend-admin,environment=production"
|
||||||
|
allowed_hosts:
|
||||||
|
- "admin.hotpocket.app"
|
||||||
|
celery_worker:
|
||||||
|
concurrency: 2
|
||||||
|
loki:
|
||||||
|
external_labels: "job=hotpocket,service=backend-celery-worker,environment=production"
|
||||||
|
celery_beat:
|
||||||
|
loki:
|
||||||
|
external_labels: "job=hotpocket,service=backend-celery-beat,environment=production"
|
||||||
|
customization:
|
||||||
|
- src: "{{ inventory_dir }}/env_vars/production/etc/backend/entrypoint.d/01-install-customized-deps.sh"
|
||||||
|
dest: "etc/backend/entrypoint.d/01-install-customized-deps.sh"
|
||||||
|
mode: "755"
|
||||||
|
- src: "{{ inventory_dir }}/env_vars/production/etc/backend/entrypoint.d/99-collectstatic.sh"
|
||||||
|
dest: "etc/backend/entrypoint.d/99-collectstatic.sh"
|
||||||
|
mode: "755"
|
||||||
|
- src: "{{ inventory_dir }}/env_vars/production/lib/backend/requirements.txt"
|
||||||
|
dest: "lib/backend/requirements.txt"
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
export PIP_INDEX_URL="https://nexus.bthlabs.pl/repository/pypi/simple/"
|
||||||
|
/srv/venv/bin/pip install -r /srv/lib/backend/requirements.txt
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
(
|
||||||
|
cd /srv/app;
|
||||||
|
./manage.py collectstatic --no-input
|
||||||
|
)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
hotpocket-bthlabs>=25.10.28
|
||||||
37
deployment/hotpocket_app/env_vars/staging/vars.yaml
Normal file
37
deployment/hotpocket_app/env_vars/staging/vars.yaml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
hotpocket_app:
|
||||||
|
deployment_directory: "/srv/hotpocket_staging"
|
||||||
|
owner: "hotpocket_staging"
|
||||||
|
group: "hotpocket_staging"
|
||||||
|
mode: "aio"
|
||||||
|
loki:
|
||||||
|
url: "http://monitoring.vm.snakeweb.net.bthlabs.net:3100/loki/api/v1/push"
|
||||||
|
node: "home.vm.snakeweb.net"
|
||||||
|
docker:
|
||||||
|
extra_hosts:
|
||||||
|
- "home.vm:10.0.1.2"
|
||||||
|
backend:
|
||||||
|
image_tag: "{{ hotpocket_app_image_tag|default('aio-v25.10.29-rc1-01') }}"
|
||||||
|
model_auth_is_disabled: false
|
||||||
|
env: "staging"
|
||||||
|
extra_env:
|
||||||
|
- "HOTPOCKET_BACKEND_SECRETS_PACKAGE=hotpocket_bthlabs.secrets"
|
||||||
|
- "VAULT_URL={{ hotpocket_app_secrets.backend.vault.url }}"
|
||||||
|
- "VAULT_ROLE_ID={{ hotpocket_app_secrets.backend.vault.role_id }}"
|
||||||
|
- "VAULT_SECRET_ID={{ hotpocket_app_secrets.backend.vault.secret_id }}"
|
||||||
|
oidc:
|
||||||
|
enabled: false
|
||||||
|
webapp:
|
||||||
|
settings_module: "hotpocket_bthlabs.settings.webapp"
|
||||||
|
loki:
|
||||||
|
external_labels: "job=hotpocket,service=backend-webapp,environment=staging"
|
||||||
|
allowed_hosts:
|
||||||
|
- "staging.hotpocket.app"
|
||||||
|
customization:
|
||||||
|
- src: "{{ inventory_dir }}/env_vars/staging/etc/backend/entrypoint.d/01-install-customized-deps.sh"
|
||||||
|
dest: "etc/backend/entrypoint.d/01-install-customized-deps.sh"
|
||||||
|
mode: "755"
|
||||||
|
- src: "{{ inventory_dir }}/env_vars/staging/etc/backend/entrypoint.d/99-collectstatic.sh"
|
||||||
|
dest: "etc/backend/entrypoint.d/99-collectstatic.sh"
|
||||||
|
mode: "755"
|
||||||
|
- src: "{{ inventory_dir }}/env_vars/staging/lib/backend/requirements.txt"
|
||||||
|
dest: "lib/backend/requirements.txt"
|
||||||
10
deployment/hotpocket_app/inventory.yaml
Normal file
10
deployment/hotpocket_app/inventory.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
hotpocket_app:
|
||||||
|
hosts:
|
||||||
|
web1.staging.hotpocket.app:
|
||||||
|
ansible_host: vm-125.homelab01.bthlab
|
||||||
|
ansible_port: 22
|
||||||
|
ansible_user: hotpocket_staging
|
||||||
|
web1.production.hotpocket.app:
|
||||||
|
ansible_host: vm-125.homelab01.bthlab
|
||||||
|
ansible_port: 22
|
||||||
|
ansible_user: hotpocket
|
||||||
73
deployment/hotpocket_app/roles/hotpocket_app/tasks/main.yaml
Normal file
73
deployment/hotpocket_app/roles/hotpocket_app/tasks/main.yaml
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
- name: "Create workspace directories"
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ hotpocket_app.deployment_directory }}/{{ item }}"
|
||||||
|
state: "directory"
|
||||||
|
loop:
|
||||||
|
- "etc"
|
||||||
|
- "etc/backend"
|
||||||
|
- "etc/backend/entrypoint.d"
|
||||||
|
- "lib"
|
||||||
|
- "lib/backend"
|
||||||
|
- "log"
|
||||||
|
- "run"
|
||||||
|
- "run/backend-admin"
|
||||||
|
- "run/backend-celery-beat"
|
||||||
|
- "run/backend-celery-worker"
|
||||||
|
- "run/backend-webapp"
|
||||||
|
- "run/uploads"
|
||||||
|
- name: "Install docker-compose.yml"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "templates/{{ hotpocket_app.mode }}/docker-compose.yaml.jinja2"
|
||||||
|
dest: "{{ hotpocket_app.deployment_directory }}/docker-compose.yaml"
|
||||||
|
owner: "{{ hotpocket_app.owner }}"
|
||||||
|
group: "{{ hotpocket_app.group }}"
|
||||||
|
- name: "Install env files"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "templates/{{ hotpocket_app.mode }}/{{ item }}.jinja2"
|
||||||
|
dest: "{{ hotpocket_app.deployment_directory }}/etc/{{ item }}"
|
||||||
|
owner: "{{ hotpocket_app.owner }}"
|
||||||
|
group: "{{ hotpocket_app.group }}"
|
||||||
|
loop: "{{ hotpocket_app_role.env_files[hotpocket_app.mode] }}"
|
||||||
|
- name: "Upload customization files"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ item.src }}"
|
||||||
|
dest: "{{ hotpocket_app.deployment_directory }}/{{ item.dest }}"
|
||||||
|
owner: "{{ hotpocket_app.owner }}"
|
||||||
|
group: "{{ hotpocket_app.group }}"
|
||||||
|
mode: "{{ item.mode|default('644') }}"
|
||||||
|
loop: "{{ hotpocket_app.customization }}"
|
||||||
|
when: "hotpocket_app.customization is defined"
|
||||||
|
- name: "Install hotpocket_app.service unit"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "templates/{{ hotpocket_app_role.services[hotpocket_app.mode].src }}.jinja2"
|
||||||
|
dest: "{{ hotpocket_app.deployment_directory }}/etc/{{ hotpocket_app_role.services[hotpocket_app.mode].dest }}"
|
||||||
|
owner: "{{ hotpocket_app.owner }}"
|
||||||
|
group: "{{ hotpocket_app.group }}"
|
||||||
|
- name: "Stop the stack"
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- "docker"
|
||||||
|
- "compose"
|
||||||
|
- "down"
|
||||||
|
chdir: "{{ hotpocket_app.deployment_directory }}"
|
||||||
|
- name: "Run backend migrations"
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- "docker"
|
||||||
|
- "compose"
|
||||||
|
- "run"
|
||||||
|
- "--rm"
|
||||||
|
- "backend-webapp"
|
||||||
|
- "./manage.py"
|
||||||
|
- "migrate"
|
||||||
|
chdir: "{{ hotpocket_app.deployment_directory }}"
|
||||||
|
when: "hotpocket_app.mode == 'fullstack' and is_manual_run is not defined"
|
||||||
|
- name: "Start the stack"
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- "docker"
|
||||||
|
- "compose"
|
||||||
|
- "up"
|
||||||
|
- "-d"
|
||||||
|
chdir: "{{ hotpocket_app.deployment_directory }}"
|
||||||
|
when: "is_manual_run is not defined"
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
DJANGO_SETTINGS_MODULE="{{ hotpocket_app.backend.webapp.settings_module|default('hotpocket_backend.settings.aio')}}"
|
||||||
|
HOTPOCKET_BACKEND_ENV="{{ hotpocket_app.backend.env|default('aio') }}"
|
||||||
|
HOTPOCKET_BACKEND_MODEL_AUTH_IS_DISABLED="{% if hotpocket_app.backend.model_auth_is_disabled %}true{% else %}false{% endif %}"
|
||||||
|
|
||||||
|
{% if hotpocket_app.backend.oidc.enabled %}HOTPOCKET_BACKEND_OIDC_PAYLOAD='{"endpoint":"{{ hotpocket_app.backend.oidc.endpoint }}","key":"{{ hotpocket_app_secrets.backend.oidc.key }}","secret":"{{ hotpocket_app_secrets.backend.oidc.secret }}","display_name":"{{ hotpocket_app.backend.oidc.display_name }}"}'{% else %}#noop{% endif %}
|
||||||
|
|
||||||
|
{% for extra_env in hotpocket_app.backend.extra_env|default([]) %}
|
||||||
|
{{ extra_env }}
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
HOTPOCKET_BACKEND_SECRET_KEY: "{{ hotpocket_app_secrets.backend.webapp.secret_key }}"
|
||||||
|
HOTPOCKET_BACKEND_ALLOWED_HOSTS="{{ hotpocket_app.backend.webapp.allowed_hosts|join(',') }}"
|
||||||
|
HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME: "{{ hotpocket_app_secrets.backend.webapp.initial_account.username }}"
|
||||||
|
HOTPOCKET_BACKEND_INITIAL_ACCOUNT_PASSWORD: "{{ hotpocket_app_secrets.backend.webapp.initial_account.password }}"
|
||||||
|
{% for extra_env in hotpocket_app.backend.webapp.extra_env|default([]) %}
|
||||||
|
{{ extra_env }}
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
services:
|
||||||
|
backend-webapp:
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:{{ hotpocket_app.backend.image_tag }}"
|
||||||
|
command:
|
||||||
|
- "/srv/venv/bin/gunicorn"
|
||||||
|
- "-c"
|
||||||
|
- "/srv/lib/gunicorn.conf.py"
|
||||||
|
- "-b"
|
||||||
|
- "unix:///srv/run/gunicorn.sock"
|
||||||
|
- "hotpocket_backend.wsgi:application"
|
||||||
|
logging:
|
||||||
|
driver: "loki"
|
||||||
|
options:
|
||||||
|
loki-url: "{{ hotpocket_app.loki.url }}"
|
||||||
|
loki-external-labels: "{{ hotpocket_app.backend.webapp.loki.external_labels }}"
|
||||||
|
labels: "node"
|
||||||
|
labels:
|
||||||
|
node: "{{ hotpocket_app.loki.node }}"
|
||||||
|
env_file:
|
||||||
|
- "etc/backend_base.env"
|
||||||
|
- "etc/backend_webapp.env"
|
||||||
|
extra_hosts: [{% for extra_host in hotpocket_app.docker.extra_hosts|default([]) %}"{{ extra_host }}"{% endfor %}]
|
||||||
|
restart: "unless-stopped"
|
||||||
|
volumes:
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/etc/backend:/srv/etc"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/lib/backend:/srv/lib/backend"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/backend-webapp:/srv/run"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/uploads:/srv/uploads"
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
DJANGO_SETTINGS_MODULE="{{ hotpocket_app.backend.admin.settings_module|default('hotpocket_backend.settings.deployment.admin')}}"
|
||||||
|
HOTPOCKET_BACKEND_GUNICORN_WORKERS=2
|
||||||
|
HOTPOCKET_BACKEND_APP="admin"
|
||||||
|
HOTPOCKET_BACKEND_SECRET_KEY="{{ hotpocket_app_secrets.backend.admin.secret_key }}"
|
||||||
|
HOTPOCKET_BACKEND_ALLOWED_HOSTS="{{ hotpocket_app.backend.admin.allowed_hosts|join(',') }}"
|
||||||
|
{% for extra_env in hotpocket_app.backend.admin.extra_env|default([]) %}
|
||||||
|
{{ extra_env }}
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
HOTPOCKET_BACKEND_ENV="{{ hotpocket_app.backend.env|default('deployment') }}"
|
||||||
|
HOTPOCKET_BACKEND_DATABASE_NAME="{{ hotpocket_app.backend.database.name }}"
|
||||||
|
HOTPOCKET_BACKEND_DATABASE_USER="{{ hotpocket_app.backend.database.user }}"
|
||||||
|
HOTPOCKET_BACKEND_DATABASE_PASSWORD="{{ hotpocket_app_secrets.backend.database.password }}"
|
||||||
|
HOTPOCKET_BACKEND_DATABASE_HOST="{{ hotpocket_app.backend.database.host }}"
|
||||||
|
HOTPOCKET_BACKEND_CELERY_BROKER_URL="amqp://{{ hotpocket_app.backend.rabbitmq.user }}:{{ hotpocket_app_secrets.backend.rabbitmq.password }}@{{ hotpocket_app.backend.rabbitmq.host }}/{{ hotpocket_app.backend.rabbitmq.vhost }}"
|
||||||
|
HOTPOCKET_BACKEND_CELERY_RESULT_BACKEND="db+postgresql+psycopg://{{ hotpocket_app.backend.database.user }}:{{ hotpocket_app_secrets.backend.database.password }}@{{ hotpocket_app.backend.database.host }}/{{ hotpocket_app.backend.database.name }}"
|
||||||
|
HOTPOCKET_BACKEND_MODEL_AUTH_IS_DISABLED="{% if hotpocket_app.backend.model_auth_is_disabled %}true{% else %}false{% endif %}"
|
||||||
|
|
||||||
|
{% if hotpocket_app.backend.oidc.enabled %}HOTPOCKET_BACKEND_OIDC_PAYLOAD='{"endpoint":"{{ hotpocket_app.backend.oidc.endpoint }}","key":"{{ hotpocket_app_secrets.backend.oidc.key }}","secret":"{{ hotpocket_app_secrets.backend.oidc.secret }}","display_name":"{{ hotpocket_app.backend.oidc.display_name }}"}'{% else %}#noop{% endif %}
|
||||||
|
|
||||||
|
{% for extra_env in hotpocket_app.backend.extra_env|default([]) %}
|
||||||
|
{{ extra_env }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
DJANGO_SETTINGS_MODULE="{{ hotpocket_app.backend.webapp.settings_module|default('hotpocket_backend.settings.deployment.webapp')}}"
|
||||||
|
HOTPOCKET_BACKEND_APP="webapp"
|
||||||
|
HOTPOCKET_BACKEND_SECRET_KEY="{{ hotpocket_app_secrets.backend.webapp.secret_key }}"
|
||||||
|
HOTPOCKET_BACKEND_ALLOWED_HOSTS="{{ hotpocket_app.backend.webapp.allowed_hosts|join(',') }}"
|
||||||
|
HOTPOCKET_BACKEND_SAVES_SAVE_ADAPTER="hotpocket_backend.apps.saves.adapters.postgres:PostgresSaveAdapter"
|
||||||
|
HOTPOCKET_BACKEND_SAVES_ASSOCIATION_ADAPTER="hotpocket_backend.apps.saves.adapters.postgres:PostgresAssociationAdapter"
|
||||||
|
{% for extra_env in hotpocket_app.backend.webapp.extra_env|default([]) %}
|
||||||
|
{{ extra_env }}
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
services:
|
||||||
|
backend-webapp:
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:{{ hotpocket_app.backend.image_tag }}"
|
||||||
|
command:
|
||||||
|
- "/srv/venv/bin/gunicorn"
|
||||||
|
- "-c"
|
||||||
|
- "/srv/lib/gunicorn.conf.py"
|
||||||
|
- "-b"
|
||||||
|
- "unix:///srv/run/gunicorn.sock"
|
||||||
|
- "hotpocket_backend.wsgi:application"
|
||||||
|
logging:
|
||||||
|
driver: "loki"
|
||||||
|
options:
|
||||||
|
loki-url: "{{ hotpocket_app.loki.url }}"
|
||||||
|
loki-external-labels: "{{ hotpocket_app.backend.webapp.loki.external_labels }}"
|
||||||
|
labels: "node"
|
||||||
|
labels:
|
||||||
|
node: "{{ hotpocket_app.loki.node }}"
|
||||||
|
env_file:
|
||||||
|
- "etc/backend_base.env"
|
||||||
|
- "etc/backend_webapp.env"
|
||||||
|
extra_hosts: [{% for extra_host in hotpocket_app.docker.extra_hosts %}"{{ extra_host }}"{% endfor %}]
|
||||||
|
restart: "unless-stopped"
|
||||||
|
volumes:
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/etc/backend:/srv/etc"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/lib/backend:/srv/lib/backend"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/backend-webapp:/srv/run"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/uploads:/srv/uploads"
|
||||||
|
|
||||||
|
backend-admin:
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:{{ hotpocket_app.backend.image_tag }}"
|
||||||
|
command:
|
||||||
|
- "/srv/venv/bin/gunicorn"
|
||||||
|
- "-c"
|
||||||
|
- "/srv/lib/gunicorn.conf.py"
|
||||||
|
- "-b"
|
||||||
|
- "unix:///srv/run/gunicorn.sock"
|
||||||
|
- "hotpocket_backend.wsgi:application"
|
||||||
|
logging:
|
||||||
|
driver: "loki"
|
||||||
|
options:
|
||||||
|
loki-url: "{{ hotpocket_app.loki.url }}"
|
||||||
|
loki-external-labels: "{{ hotpocket_app.backend.admin.loki.external_labels }}"
|
||||||
|
labels: "node"
|
||||||
|
labels:
|
||||||
|
node: "{{ hotpocket_app.loki.node }}"
|
||||||
|
env_file:
|
||||||
|
- "etc/backend_base.env"
|
||||||
|
- "etc/backend_admin.env"
|
||||||
|
extra_hosts: [{% for extra_host in hotpocket_app.docker.extra_hosts %}"{{ extra_host }}"{% endfor %}]
|
||||||
|
restart: "unless-stopped"
|
||||||
|
volumes:
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/etc/backend:/srv/etc"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/lib/backend:/srv/lib/backend"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/backend-admin:/srv/run"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/uploads:/srv/uploads"
|
||||||
|
|
||||||
|
backend-celery-worker:
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:{{ hotpocket_app.backend.image_tag }}"
|
||||||
|
command:
|
||||||
|
- "/srv/venv/bin/celery"
|
||||||
|
- "-A"
|
||||||
|
- "hotpocket_backend.celery:app"
|
||||||
|
- "worker"
|
||||||
|
- "-l"
|
||||||
|
- "INFO"
|
||||||
|
- "-Q"
|
||||||
|
- "celery,webapp"
|
||||||
|
- "-c"
|
||||||
|
- "{{ hotpocket_app.backend.celery_worker.concurrency }}"
|
||||||
|
logging:
|
||||||
|
driver: "loki"
|
||||||
|
options:
|
||||||
|
loki-url: "{{ hotpocket_app.loki.url }}"
|
||||||
|
loki-external-labels: "{{ hotpocket_app.backend.celery_worker.loki.external_labels }}"
|
||||||
|
labels: "node"
|
||||||
|
labels:
|
||||||
|
node: "{{ hotpocket_app.loki.node }}"
|
||||||
|
env_file:
|
||||||
|
- "etc/backend_base.env"
|
||||||
|
- "etc/backend_webapp.env"
|
||||||
|
extra_hosts: [{% for extra_host in hotpocket_app.docker.extra_hosts %}"{{ extra_host }}"{% endfor %}]
|
||||||
|
restart: "unless-stopped"
|
||||||
|
volumes:
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/etc/backend:/srv/etc"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/lib/backend:/srv/lib/backend"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/backend-celery-worker:/srv/run"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/uploads:/srv/uploads"
|
||||||
|
|
||||||
|
backend-celery-beat:
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:{{ hotpocket_app.backend.image_tag }}"
|
||||||
|
command:
|
||||||
|
- "/srv/venv/bin/celery"
|
||||||
|
- "-A"
|
||||||
|
- "hotpocket_backend.celery:app"
|
||||||
|
- "beat"
|
||||||
|
- "-l"
|
||||||
|
- "INFO"
|
||||||
|
- "-s"
|
||||||
|
- "/srv/run/celery-beat-schedule"
|
||||||
|
logging:
|
||||||
|
driver: "loki"
|
||||||
|
options:
|
||||||
|
loki-url: "{{ hotpocket_app.loki.url }}"
|
||||||
|
loki-external-labels: "{{ hotpocket_app.backend.celery_beat.loki.external_labels }}"
|
||||||
|
labels: "node"
|
||||||
|
labels:
|
||||||
|
node: "{{ hotpocket_app.loki.node }}"
|
||||||
|
env_file:
|
||||||
|
- "etc/backend_base.env"
|
||||||
|
- "etc/backend_webapp.env"
|
||||||
|
extra_hosts: [{% for extra_host in hotpocket_app.docker.extra_hosts %}"{{ extra_host }}"{% endfor %}]
|
||||||
|
restart: "unless-stopped"
|
||||||
|
volumes:
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/etc/backend:/srv/etc"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/lib/backend:/srv/lib/backend"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/backend-celery-beat:/srv/run"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/uploads:/srv/uploads"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=hotpocket_backend.webapp
|
||||||
|
Requires=docker.service
|
||||||
|
After=docker.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
RemainAfterExit=yes
|
||||||
|
WorkingDirectory={{ hotpocket_app.deployment_directory }}
|
||||||
|
ExecStart=/usr/bin/docker compose up -d
|
||||||
|
ExecStop=/usr/bin/docker compose down
|
||||||
|
TimeoutStartSec=0
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
16
deployment/hotpocket_app/roles/hotpocket_app/vars/main.yaml
Normal file
16
deployment/hotpocket_app/roles/hotpocket_app/vars/main.yaml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
hotpocket_app_role:
|
||||||
|
env_files:
|
||||||
|
fullstack:
|
||||||
|
- "backend_admin.env"
|
||||||
|
- "backend_base.env"
|
||||||
|
- "backend_webapp.env"
|
||||||
|
aio:
|
||||||
|
- "backend_base.env"
|
||||||
|
- "backend_webapp.env"
|
||||||
|
services:
|
||||||
|
fullstack:
|
||||||
|
src: "hotpocket_app.service"
|
||||||
|
dest: "hotpocket_app.service"
|
||||||
|
aio:
|
||||||
|
src: "hotpocket_app.service"
|
||||||
|
dest: "staging_hotpocket_app.service"
|
||||||
7
deployment/hotpocket_bthlab/configs/backend/admin
Normal file
7
deployment/hotpocket_bthlab/configs/backend/admin
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
DJANGO_SETTINGS_MODULE=hotpocket_bthlabs.settings.admin
|
||||||
|
HOTPOCKET_BACKEND_GUNICORN_WORKERS=2
|
||||||
|
HOTPOCKET_BACKEND_SECRETS_PACKAGE=hotpocket_bthlabs.secrets
|
||||||
|
HOTPOCKET_BACKEND_ENV=development
|
||||||
|
HOTPOCKET_BACKEND_APP=admin
|
||||||
|
HOTPOCKET_BACKEND_SECRET_KEY=thisissecret
|
||||||
|
HOTPOCKET_BACKEND_ALLOWED_HOSTS=admin.hotpocket.bthlab.bthlabs.net
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
DJANGO_SETTINGS_MODULE=hotpocket_backend.settings.deployment.webapp
|
DJANGO_SETTINGS_MODULE=hotpocket_bthlabs.settings.webapp
|
||||||
HOTPOCKET_BACKEND_GUNICORN_WORKERS=2
|
HOTPOCKET_BACKEND_GUNICORN_WORKERS=2
|
||||||
|
HOTPOCKET_BACKEND_SECRETS_PACKAGE=hotpocket_bthlabs.secrets
|
||||||
|
HOTPOCKET_BACKEND_ENV=development
|
||||||
HOTPOCKET_BACKEND_APP=webapp
|
HOTPOCKET_BACKEND_APP=webapp
|
||||||
HOTPOCKET_BACKEND_SECRET_KEY=thisissecret
|
HOTPOCKET_BACKEND_SECRET_KEY=thisissecret
|
||||||
HOTPOCKET_BACKEND_ALLOWED_HOSTS=thisissecret
|
HOTPOCKET_BACKEND_ALLOWED_HOSTS=app.hotpocket.bthlab.bthlabs.net
|
||||||
HOTPOCKET_BACKEND_SAVES_SAVE_ADAPTER=hotpocket_backend.apps.saves.adapters.postgres:PostgresSaveAdapter
|
HOTPOCKET_BACKEND_SAVES_SAVE_ADAPTER=hotpocket_backend.apps.saves.adapters.postgres:PostgresSaveAdapter
|
||||||
HOTPOCKET_BACKEND_SAVES_ASSOCIATION_ADAPTER=hotpocket_backend.apps.saves.adapters.postgres:PostgresAssociationAdapter
|
HOTPOCKET_BACKEND_SAVES_ASSOCIATION_ADAPTER=hotpocket_backend.apps.saves.adapters.postgres:PostgresAssociationAdapter
|
||||||
@@ -4,6 +4,7 @@ kind: Kustomization
|
|||||||
resources:
|
resources:
|
||||||
- resources/namespace.yaml
|
- resources/namespace.yaml
|
||||||
- resources/volumes.yaml
|
- resources/volumes.yaml
|
||||||
|
- resources/backend/config-map-local-deps.yaml
|
||||||
- resources/backend/job-migrations.yaml
|
- resources/backend/job-migrations.yaml
|
||||||
- resources/backend/webapp.yaml
|
- resources/backend/webapp.yaml
|
||||||
- resources/backend/webapp-service.yaml
|
- resources/backend/webapp-service.yaml
|
||||||
@@ -35,5 +36,5 @@ patches: []
|
|||||||
|
|
||||||
images:
|
images:
|
||||||
- name: hotpocket-backend
|
- name: hotpocket-backend
|
||||||
newName: docker-hosted.nexus.bthlabs.pl/hotpocket/backend
|
newName: nexus.bthlab.bthlabs.net:8002/hotpocket/backend
|
||||||
newTag: deployment-v25.10.4-01
|
newTag: deployment-8e09ae51-01
|
||||||
@@ -26,7 +26,7 @@ spec:
|
|||||||
containers:
|
containers:
|
||||||
- name: app
|
- name: app
|
||||||
image: hotpocket-backend:latest
|
image: hotpocket-backend:latest
|
||||||
command:
|
args:
|
||||||
- "/srv/venv/bin/gunicorn"
|
- "/srv/venv/bin/gunicorn"
|
||||||
- "-c"
|
- "-c"
|
||||||
- "/srv/lib/gunicorn.conf.py"
|
- "/srv/lib/gunicorn.conf.py"
|
||||||
@@ -37,36 +37,21 @@ spec:
|
|||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: backend-admin-config
|
name: backend-admin-config
|
||||||
env:
|
env:
|
||||||
- name: HOTPOCKET_BACKEND_SECRET_KEY
|
- name: VAULT_URL
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: backend-admin
|
name: backend-vault
|
||||||
key: secret_key
|
key: url
|
||||||
- name: HOTPOCKET_BACKEND_ALLOWED_HOSTS
|
- name: VAULT_ROLE_ID
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: backend-admin
|
name: backend-vault
|
||||||
key: allowed_hosts
|
key: role_id
|
||||||
- name: HOTPOCKET_BACKEND_DATABASE_USER
|
- name: VAULT_SECRET_ID
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: backend-postgres
|
name: backend-vault
|
||||||
key: username
|
key: secret_id
|
||||||
- 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:
|
ports:
|
||||||
- containerPort: 8000
|
- containerPort: 8000
|
||||||
name: http
|
name: http
|
||||||
@@ -91,6 +76,15 @@ spec:
|
|||||||
name: shm
|
name: shm
|
||||||
- mountPath: /srv/run
|
- mountPath: /srv/run
|
||||||
name: backend-admin-srv-run
|
name: backend-admin-srv-run
|
||||||
|
- name: backend-admin-local-deps
|
||||||
|
mountPath: "/srv/lib/requirements.txt"
|
||||||
|
subPath: "requirements.txt"
|
||||||
|
- name: backend-admin-local-deps
|
||||||
|
mountPath: "/srv/etc/entrypoint.d/01-install-extra-deps.sh"
|
||||||
|
subPath: "01-install-extra-deps.sh"
|
||||||
|
- name: backend-admin-local-deps
|
||||||
|
mountPath: "/srv/etc/entrypoint.d/99-collectstatic.sh"
|
||||||
|
subPath: "99-collectstatic.sh"
|
||||||
dnsPolicy: ClusterFirst
|
dnsPolicy: ClusterFirst
|
||||||
restartPolicy: Always
|
restartPolicy: Always
|
||||||
volumes:
|
volumes:
|
||||||
@@ -99,3 +93,7 @@ spec:
|
|||||||
medium: Memory
|
medium: Memory
|
||||||
- name: backend-admin-srv-run
|
- name: backend-admin-srv-run
|
||||||
emptyDir: {}
|
emptyDir: {}
|
||||||
|
- name: backend-admin-local-deps
|
||||||
|
configMap:
|
||||||
|
name: "backend-local-deps"
|
||||||
|
defaultMode: 0755
|
||||||
@@ -20,7 +20,7 @@ spec:
|
|||||||
containers:
|
containers:
|
||||||
- name: app
|
- name: app
|
||||||
image: hotpocket-backend:latest
|
image: hotpocket-backend:latest
|
||||||
command:
|
args:
|
||||||
- "/srv/venv/bin/celery"
|
- "/srv/venv/bin/celery"
|
||||||
- "-A"
|
- "-A"
|
||||||
- "hotpocket_backend.celery:app"
|
- "hotpocket_backend.celery:app"
|
||||||
@@ -35,36 +35,21 @@ spec:
|
|||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: backend-webapp-config
|
name: backend-webapp-config
|
||||||
env:
|
env:
|
||||||
- name: HOTPOCKET_BACKEND_SECRET_KEY
|
- name: VAULT_URL
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: backend-webapp
|
name: backend-vault
|
||||||
key: secret_key
|
key: url
|
||||||
- name: HOTPOCKET_BACKEND_ALLOWED_HOSTS
|
- name: VAULT_ROLE_ID
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: backend-webapp
|
name: backend-vault
|
||||||
key: allowed_hosts
|
key: role_id
|
||||||
- name: HOTPOCKET_BACKEND_DATABASE_USER
|
- name: VAULT_SECRET_ID
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: backend-postgres
|
name: backend-vault
|
||||||
key: username
|
key: secret_id
|
||||||
- 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:
|
volumeMounts:
|
||||||
- mountPath: /dev/shm
|
- mountPath: /dev/shm
|
||||||
name: shm
|
name: shm
|
||||||
@@ -72,6 +57,12 @@ spec:
|
|||||||
name: backend-celery-beat-srv-run
|
name: backend-celery-beat-srv-run
|
||||||
- mountPath: /srv/uploads
|
- mountPath: /srv/uploads
|
||||||
name: backend-celery-beat-srv-uploads
|
name: backend-celery-beat-srv-uploads
|
||||||
|
- name: backend-admin-local-deps
|
||||||
|
mountPath: "/srv/lib/requirements.txt"
|
||||||
|
subPath: "requirements.txt"
|
||||||
|
- name: backend-admin-local-deps
|
||||||
|
mountPath: "/srv/etc/entrypoint.d/01-install-extra-deps.sh"
|
||||||
|
subPath: "01-install-extra-deps.sh"
|
||||||
dnsPolicy: ClusterFirst
|
dnsPolicy: ClusterFirst
|
||||||
restartPolicy: Always
|
restartPolicy: Always
|
||||||
volumes:
|
volumes:
|
||||||
@@ -83,3 +74,7 @@ spec:
|
|||||||
claimName: backend-celery-beat-run
|
claimName: backend-celery-beat-run
|
||||||
- name: backend-celery-beat-srv-uploads
|
- name: backend-celery-beat-srv-uploads
|
||||||
emptyDir: {}
|
emptyDir: {}
|
||||||
|
- name: backend-admin-local-deps
|
||||||
|
configMap:
|
||||||
|
name: "backend-local-deps"
|
||||||
|
defaultMode: 0755
|
||||||
@@ -26,7 +26,7 @@ spec:
|
|||||||
containers:
|
containers:
|
||||||
- name: app
|
- name: app
|
||||||
image: hotpocket-backend:latest
|
image: hotpocket-backend:latest
|
||||||
command:
|
args:
|
||||||
- "/srv/venv/bin/celery"
|
- "/srv/venv/bin/celery"
|
||||||
- "-A"
|
- "-A"
|
||||||
- "hotpocket_backend.celery:app"
|
- "hotpocket_backend.celery:app"
|
||||||
@@ -43,36 +43,21 @@ spec:
|
|||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: backend-webapp-config
|
name: backend-webapp-config
|
||||||
env:
|
env:
|
||||||
- name: HOTPOCKET_BACKEND_SECRET_KEY
|
- name: VAULT_URL
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: backend-webapp
|
name: backend-vault
|
||||||
key: secret_key
|
key: url
|
||||||
- name: HOTPOCKET_BACKEND_ALLOWED_HOSTS
|
- name: VAULT_ROLE_ID
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: backend-webapp
|
name: backend-vault
|
||||||
key: allowed_hosts
|
key: role_id
|
||||||
- name: HOTPOCKET_BACKEND_DATABASE_USER
|
- name: VAULT_SECRET_ID
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: backend-postgres
|
name: backend-vault
|
||||||
key: username
|
key: secret_id
|
||||||
- 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:
|
volumeMounts:
|
||||||
- mountPath: /dev/shm
|
- mountPath: /dev/shm
|
||||||
name: shm
|
name: shm
|
||||||
@@ -80,6 +65,12 @@ spec:
|
|||||||
name: backend-celery-worker-srv-run
|
name: backend-celery-worker-srv-run
|
||||||
- mountPath: /srv/uploads
|
- mountPath: /srv/uploads
|
||||||
name: backend-celery-worker-srv-uploads
|
name: backend-celery-worker-srv-uploads
|
||||||
|
- name: backend-admin-local-deps
|
||||||
|
mountPath: "/srv/lib/requirements.txt"
|
||||||
|
subPath: "requirements.txt"
|
||||||
|
- name: backend-admin-local-deps
|
||||||
|
mountPath: "/srv/etc/entrypoint.d/01-install-extra-deps.sh"
|
||||||
|
subPath: "01-install-extra-deps.sh"
|
||||||
dnsPolicy: ClusterFirst
|
dnsPolicy: ClusterFirst
|
||||||
restartPolicy: Always
|
restartPolicy: Always
|
||||||
volumes:
|
volumes:
|
||||||
@@ -91,3 +82,7 @@ spec:
|
|||||||
- name: backend-celery-worker-srv-uploads
|
- name: backend-celery-worker-srv-uploads
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
claimName: backend-uploads
|
claimName: backend-uploads
|
||||||
|
- name: backend-admin-local-deps
|
||||||
|
configMap:
|
||||||
|
name: "backend-local-deps"
|
||||||
|
defaultMode: 0755
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: backend-local-deps
|
||||||
|
namespace: hotpocket-development
|
||||||
|
data:
|
||||||
|
01-install-extra-deps.sh: |
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
export PIP_INDEX_URL="https://nexus.bthlabs.pl/repository/pypi/simple/"
|
||||||
|
/srv/venv/bin/pip install -r /srv/lib/requirements.txt
|
||||||
|
99-collectstatic.sh: |
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
(
|
||||||
|
cd /srv/app;
|
||||||
|
./manage.py collectstatic --no-input
|
||||||
|
)
|
||||||
|
requirements.txt: |
|
||||||
|
hotpocket_bthlabs>=25.10.28
|
||||||
@@ -22,7 +22,7 @@ spec:
|
|||||||
containers:
|
containers:
|
||||||
- name: migrations
|
- name: migrations
|
||||||
image: hotpocket-backend:latest
|
image: hotpocket-backend:latest
|
||||||
command:
|
args:
|
||||||
- "./manage.py"
|
- "./manage.py"
|
||||||
- "migrate"
|
- "migrate"
|
||||||
envFrom:
|
envFrom:
|
||||||
@@ -31,36 +31,21 @@ spec:
|
|||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: backend-webapp-config
|
name: backend-webapp-config
|
||||||
env:
|
env:
|
||||||
- name: HOTPOCKET_BACKEND_SECRET_KEY
|
- name: VAULT_URL
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: backend-webapp
|
name: backend-vault
|
||||||
key: secret_key
|
key: url
|
||||||
- name: HOTPOCKET_BACKEND_ALLOWED_HOSTS
|
- name: VAULT_ROLE_ID
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: backend-webapp
|
name: backend-vault
|
||||||
key: allowed_hosts
|
key: role_id
|
||||||
- name: HOTPOCKET_BACKEND_DATABASE_USER
|
- name: VAULT_SECRET_ID
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: backend-postgres
|
name: backend-vault
|
||||||
key: username
|
key: secret_id
|
||||||
- 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:
|
volumeMounts:
|
||||||
- mountPath: /dev/shm
|
- mountPath: /dev/shm
|
||||||
name: shm
|
name: shm
|
||||||
@@ -68,6 +53,12 @@ spec:
|
|||||||
name: backend-webapp-srv-run
|
name: backend-webapp-srv-run
|
||||||
- mountPath: /srv/uploads
|
- mountPath: /srv/uploads
|
||||||
name: backend-webapp-srv-uploads
|
name: backend-webapp-srv-uploads
|
||||||
|
- name: backend-admin-local-deps
|
||||||
|
mountPath: "/srv/lib/requirements.txt"
|
||||||
|
subPath: "requirements.txt"
|
||||||
|
- name: backend-admin-local-deps
|
||||||
|
mountPath: "/srv/etc/entrypoint.d/01-install-extra-deps.sh"
|
||||||
|
subPath: "01-install-extra-deps.sh"
|
||||||
dnsPolicy: ClusterFirst
|
dnsPolicy: ClusterFirst
|
||||||
restartPolicy: Never
|
restartPolicy: Never
|
||||||
volumes:
|
volumes:
|
||||||
@@ -78,3 +69,7 @@ spec:
|
|||||||
emptyDir: {}
|
emptyDir: {}
|
||||||
- name: backend-webapp-srv-uploads
|
- name: backend-webapp-srv-uploads
|
||||||
emptyDir: {}
|
emptyDir: {}
|
||||||
|
- name: backend-admin-local-deps
|
||||||
|
configMap:
|
||||||
|
name: "backend-local-deps"
|
||||||
|
defaultMode: 0755
|
||||||
@@ -26,7 +26,7 @@ spec:
|
|||||||
containers:
|
containers:
|
||||||
- name: app
|
- name: app
|
||||||
image: hotpocket-backend:latest
|
image: hotpocket-backend:latest
|
||||||
command:
|
args:
|
||||||
- "/srv/venv/bin/gunicorn"
|
- "/srv/venv/bin/gunicorn"
|
||||||
- "-c"
|
- "-c"
|
||||||
- "/srv/lib/gunicorn.conf.py"
|
- "/srv/lib/gunicorn.conf.py"
|
||||||
@@ -37,36 +37,23 @@ spec:
|
|||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: backend-webapp-config
|
name: backend-webapp-config
|
||||||
env:
|
env:
|
||||||
- name: HOTPOCKET_BACKEND_SECRET_KEY
|
- name: VAULT_URL
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: backend-webapp
|
name: backend-vault
|
||||||
key: secret_key
|
key: url
|
||||||
- name: HOTPOCKET_BACKEND_ALLOWED_HOSTS
|
- name: VAULT_ROLE_ID
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: backend-webapp
|
name: backend-vault
|
||||||
key: allowed_hosts
|
key: role_id
|
||||||
- name: HOTPOCKET_BACKEND_DATABASE_USER
|
- name: VAULT_SECRET_ID
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: backend-postgres
|
name: backend-vault
|
||||||
key: username
|
key: secret_id
|
||||||
- name: HOTPOCKET_BACKEND_DATABASE_PASSWORD
|
- name: HOTPOCKET_BACKEND_CREATE_INITIAL_ACCOUNT
|
||||||
valueFrom:
|
value: "true"
|
||||||
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:
|
ports:
|
||||||
- containerPort: 8000
|
- containerPort: 8000
|
||||||
name: http
|
name: http
|
||||||
@@ -93,6 +80,15 @@ spec:
|
|||||||
name: backend-webapp-srv-run
|
name: backend-webapp-srv-run
|
||||||
- mountPath: /srv/uploads
|
- mountPath: /srv/uploads
|
||||||
name: backend-webapp-srv-uploads
|
name: backend-webapp-srv-uploads
|
||||||
|
- name: backend-admin-local-deps
|
||||||
|
mountPath: "/srv/lib/requirements.txt"
|
||||||
|
subPath: "requirements.txt"
|
||||||
|
- name: backend-admin-local-deps
|
||||||
|
mountPath: "/srv/etc/entrypoint.d/01-install-extra-deps.sh"
|
||||||
|
subPath: "01-install-extra-deps.sh"
|
||||||
|
- name: backend-admin-local-deps
|
||||||
|
mountPath: "/srv/etc/entrypoint.d/99-collectstatic.sh"
|
||||||
|
subPath: "99-collectstatic.sh"
|
||||||
dnsPolicy: ClusterFirst
|
dnsPolicy: ClusterFirst
|
||||||
restartPolicy: Always
|
restartPolicy: Always
|
||||||
volumes:
|
volumes:
|
||||||
@@ -104,3 +100,7 @@ spec:
|
|||||||
- name: backend-webapp-srv-uploads
|
- name: backend-webapp-srv-uploads
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
claimName: backend-uploads
|
claimName: backend-uploads
|
||||||
|
- name: backend-admin-local-deps
|
||||||
|
configMap:
|
||||||
|
name: "backend-local-deps"
|
||||||
|
defaultMode: 0755
|
||||||
6
poetry.lock
generated
6
poetry.lock
generated
@@ -5,7 +5,7 @@ name = "hotpocket-workspace-tools"
|
|||||||
version = "1.0.0.dev0"
|
version = "1.0.0.dev0"
|
||||||
description = "HotPocket Workspace Tools"
|
description = "HotPocket Workspace Tools"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "^3.12"
|
python-versions = "^3.13"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
files = []
|
files = []
|
||||||
develop = true
|
develop = true
|
||||||
@@ -31,5 +31,5 @@ files = [
|
|||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.1"
|
lock-version = "2.1"
|
||||||
python-versions = "^3.12"
|
python-versions = "^3.13"
|
||||||
content-hash = "a7028d4a0260c82012077d9cc4b324b0ef5ab8ed24aa283a51cf941ba09685a9"
|
content-hash = "175bf795c7148fe40af7e095d6f41918fa14cf4c71be87444a4d6c467fbd38d2"
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "hotpocket-workspace"
|
name = "hotpocket-workspace"
|
||||||
version = "25.10.21"
|
version = "25.11.19"
|
||||||
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"
|
||||||
package-mode = false
|
package-mode = false
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.12"
|
python = "^3.13"
|
||||||
hotpocket-workspace-tools = {path = "services/packages/workspace_tools", develop = true}
|
hotpocket-workspace-tools = {path = "services/packages/workspace_tools", develop = true}
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
|
|||||||
@@ -13,4 +13,5 @@ backend/hotpocket_backend/settings/metal/
|
|||||||
backend/hotpocket_backend/static/
|
backend/hotpocket_backend/static/
|
||||||
extension/node_modules/
|
extension/node_modules/
|
||||||
extension/dist/
|
extension/dist/
|
||||||
|
vendor/
|
||||||
.envrc*
|
.envrc*
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ 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-20251014-01 AS development
|
FROM docker-hosted.nexus.bthlabs.pl/hotpocket/base:build-node-20251114-01 AS development
|
||||||
|
|
||||||
ARG APP_USER_UID
|
ARG APP_USER_UID
|
||||||
ARG APP_USER_GID
|
ARG APP_USER_GID
|
||||||
|
|||||||
@@ -85,8 +85,8 @@
|
|||||||
4C70F3142E886A8F00320048 /* HPSharedItem.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HPSharedItem.m; sourceTree = "<group>"; };
|
4C70F3142E886A8F00320048 /* HPSharedItem.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HPSharedItem.m; sourceTree = "<group>"; };
|
||||||
4C70F3172E886ADD00320048 /* HPSharedItemsContainer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HPSharedItemsContainer.h; sourceTree = "<group>"; };
|
4C70F3172E886ADD00320048 /* HPSharedItemsContainer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HPSharedItemsContainer.h; sourceTree = "<group>"; };
|
||||||
4C70F3182E886ADD00320048 /* HPSharedItemsContainer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HPSharedItemsContainer.m; sourceTree = "<group>"; };
|
4C70F3182E886ADD00320048 /* HPSharedItemsContainer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HPSharedItemsContainer.m; sourceTree = "<group>"; };
|
||||||
4CABCAB02E56F0C900D8A354 /* HotPocket.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HotPocket.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
4CABCAB02E56F0C900D8A354 /* HotPocket Development.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "HotPocket Development.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
4CABCAC62E56F0C900D8A354 /* HotPocket.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HotPocket.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
4CABCAC62E56F0C900D8A354 /* HotPocket Development.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "HotPocket Development.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
4CABCAD52E56F0C900D8A354 /* HotPocket Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "HotPocket Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
4CABCAD52E56F0C900D8A354 /* HotPocket Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "HotPocket Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
4CABCADF2E56F0C900D8A354 /* HotPocket Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "HotPocket Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
4CABCADF2E56F0C900D8A354 /* HotPocket Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "HotPocket Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
4CBCEA4F2E81CB9500722009 /* Save to HotPocket.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Save to HotPocket.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
4CBCEA4F2E81CB9500722009 /* Save to HotPocket.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Save to HotPocket.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
@@ -107,6 +107,7 @@
|
|||||||
HPAPI.m,
|
HPAPI.m,
|
||||||
HPCredentialsHelper.m,
|
HPCredentialsHelper.m,
|
||||||
HPRPCClient.m,
|
HPRPCClient.m,
|
||||||
|
"NSBundle+HotPocketExtensions.m",
|
||||||
"NSURL+HotPocketExtensions.m",
|
"NSURL+HotPocketExtensions.m",
|
||||||
"Resources/icon-mac-384.png",
|
"Resources/icon-mac-384.png",
|
||||||
);
|
);
|
||||||
@@ -123,6 +124,7 @@
|
|||||||
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
||||||
membershipExceptions = (
|
membershipExceptions = (
|
||||||
MultilineLabel.m,
|
MultilineLabel.m,
|
||||||
|
UnameLabel.m,
|
||||||
);
|
);
|
||||||
target = 4C2F0C5D2E851BBD0033F5C2 /* iOS (Share Extension) */;
|
target = 4C2F0C5D2E851BBD0033F5C2 /* iOS (Share Extension) */;
|
||||||
};
|
};
|
||||||
@@ -134,6 +136,7 @@
|
|||||||
HPAuthFlow.m,
|
HPAuthFlow.m,
|
||||||
HPCredentialsHelper.m,
|
HPCredentialsHelper.m,
|
||||||
HPRPCClient.m,
|
HPRPCClient.m,
|
||||||
|
"NSBundle+HotPocketExtensions.m",
|
||||||
"NSURL+HotPocketExtensions.m",
|
"NSURL+HotPocketExtensions.m",
|
||||||
"Resources/icon-mac-384.png",
|
"Resources/icon-mac-384.png",
|
||||||
);
|
);
|
||||||
@@ -161,6 +164,7 @@
|
|||||||
HPAuthFlow.m,
|
HPAuthFlow.m,
|
||||||
HPCredentialsHelper.m,
|
HPCredentialsHelper.m,
|
||||||
HPRPCClient.m,
|
HPRPCClient.m,
|
||||||
|
"NSBundle+HotPocketExtensions.m",
|
||||||
"NSURL+HotPocketExtensions.m",
|
"NSURL+HotPocketExtensions.m",
|
||||||
"Resources/icon-mac-384.png",
|
"Resources/icon-mac-384.png",
|
||||||
);
|
);
|
||||||
@@ -215,6 +219,7 @@
|
|||||||
HPAPI.m,
|
HPAPI.m,
|
||||||
HPCredentialsHelper.m,
|
HPCredentialsHelper.m,
|
||||||
HPRPCClient.m,
|
HPRPCClient.m,
|
||||||
|
"NSBundle+HotPocketExtensions.m",
|
||||||
"NSURL+HotPocketExtensions.m",
|
"NSURL+HotPocketExtensions.m",
|
||||||
"Resources/icon-mac-384.png",
|
"Resources/icon-mac-384.png",
|
||||||
);
|
);
|
||||||
@@ -384,8 +389,8 @@
|
|||||||
4CABCAB12E56F0C900D8A354 /* Products */ = {
|
4CABCAB12E56F0C900D8A354 /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
4CABCAB02E56F0C900D8A354 /* HotPocket.app */,
|
4CABCAB02E56F0C900D8A354 /* HotPocket Development.app */,
|
||||||
4CABCAC62E56F0C900D8A354 /* HotPocket.app */,
|
4CABCAC62E56F0C900D8A354 /* HotPocket Development.app */,
|
||||||
4CABCAD52E56F0C900D8A354 /* HotPocket Extension.appex */,
|
4CABCAD52E56F0C900D8A354 /* HotPocket Extension.appex */,
|
||||||
4CABCADF2E56F0C900D8A354 /* HotPocket Extension.appex */,
|
4CABCADF2E56F0C900D8A354 /* HotPocket Extension.appex */,
|
||||||
4CBCEA4F2E81CB9500722009 /* Save to HotPocket.appex */,
|
4CBCEA4F2E81CB9500722009 /* Save to HotPocket.appex */,
|
||||||
@@ -441,7 +446,7 @@
|
|||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
);
|
);
|
||||||
productName = "HotPocket (iOS)";
|
productName = "HotPocket (iOS)";
|
||||||
productReference = 4CABCAB02E56F0C900D8A354 /* HotPocket.app */;
|
productReference = 4CABCAB02E56F0C900D8A354 /* HotPocket Development.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
};
|
};
|
||||||
4CABCAC52E56F0C900D8A354 /* HotPocket (macOS) */ = {
|
4CABCAC52E56F0C900D8A354 /* HotPocket (macOS) */ = {
|
||||||
@@ -466,7 +471,7 @@
|
|||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
);
|
);
|
||||||
productName = "HotPocket (macOS)";
|
productName = "HotPocket (macOS)";
|
||||||
productReference = 4CABCAC62E56F0C900D8A354 /* HotPocket.app */;
|
productReference = 4CABCAC62E56F0C900D8A354 /* HotPocket Development.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
};
|
};
|
||||||
4CABCAD42E56F0C900D8A354 /* HotPocket Extension (iOS) */ = {
|
4CABCAD42E56F0C900D8A354 /* HotPocket Extension (iOS) */ = {
|
||||||
@@ -713,7 +718,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 = 2025102101;
|
CURRENT_PROJECT_VERSION = 2025111901;
|
||||||
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 +731,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 25.11.19;
|
||||||
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 +751,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 = 2025102101;
|
CURRENT_PROJECT_VERSION = 2025111901;
|
||||||
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 +764,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 25.11.19;
|
||||||
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 +784,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 2025102101;
|
CURRENT_PROJECT_VERSION = 2025111901;
|
||||||
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 +797,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 25.11.19;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
@@ -814,7 +819,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 2025102101;
|
CURRENT_PROJECT_VERSION = 2025111901;
|
||||||
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 +832,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 25.11.19;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
@@ -853,7 +858,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 = 2025102101;
|
CURRENT_PROJECT_VERSION = 2025111901;
|
||||||
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 +878,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 25.11.19;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
@@ -881,7 +886,7 @@
|
|||||||
WebKit,
|
WebKit,
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = pl.bthlabs.HotPocket;
|
PRODUCT_BUNDLE_IDENTIFIER = pl.bthlabs.HotPocket;
|
||||||
PRODUCT_NAME = HotPocket;
|
PRODUCT_NAME = "HotPocket Development";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
SUPPORTS_MACCATALYST = NO;
|
SUPPORTS_MACCATALYST = NO;
|
||||||
@@ -899,7 +904,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 = 2025102101;
|
CURRENT_PROJECT_VERSION = 2025111901;
|
||||||
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 +924,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 25.11.19;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
@@ -945,7 +950,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 = 2025102101;
|
CURRENT_PROJECT_VERSION = 2025111901;
|
||||||
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 +965,7 @@
|
|||||||
"@executable_path/../../../../Frameworks",
|
"@executable_path/../../../../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 25.11.19;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
@@ -980,7 +985,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 = 2025102101;
|
CURRENT_PROJECT_VERSION = 2025111901;
|
||||||
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 +1000,7 @@
|
|||||||
"@executable_path/../../../../Frameworks",
|
"@executable_path/../../../../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 25.11.19;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
@@ -1017,7 +1022,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 = 2025102101;
|
CURRENT_PROJECT_VERSION = 2025111901;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -1033,7 +1038,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 25.11.19;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
@@ -1041,7 +1046,7 @@
|
|||||||
WebKit,
|
WebKit,
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = pl.bthlabs.HotPocket;
|
PRODUCT_BUNDLE_IDENTIFIER = pl.bthlabs.HotPocket;
|
||||||
PRODUCT_NAME = HotPocket;
|
PRODUCT_NAME = "HotPocket Development";
|
||||||
REGISTER_APP_GROUPS = YES;
|
REGISTER_APP_GROUPS = YES;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
@@ -1056,7 +1061,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 = 2025102101;
|
CURRENT_PROJECT_VERSION = 2025111901;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -1072,7 +1077,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 25.11.19;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
@@ -1206,7 +1211,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 = 2025102101;
|
CURRENT_PROJECT_VERSION = 2025111901;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -1220,7 +1225,7 @@
|
|||||||
"@executable_path/../../../../Frameworks",
|
"@executable_path/../../../../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 25.11.19;
|
||||||
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 +1241,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 = 2025102101;
|
CURRENT_PROJECT_VERSION = 2025111901;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -1250,7 +1255,7 @@
|
|||||||
"@executable_path/../../../../Frameworks",
|
"@executable_path/../../../../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 25.11.19;
|
||||||
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;
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 264 KiB |
18
services/apple/Shared (App)/NSBundle+HotPocketExtensions.h
Normal file
18
services/apple/Shared (App)/NSBundle+HotPocketExtensions.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// NSBundle+HotPocketExtensions.h
|
||||||
|
// HotPocket
|
||||||
|
//
|
||||||
|
// Created by Tomek Wójcik on 17/11/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface NSBundle (HotPocketExtensions)
|
||||||
|
|
||||||
|
+(NSString *)uname;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
17
services/apple/Shared (App)/NSBundle+HotPocketExtensions.m
Normal file
17
services/apple/Shared (App)/NSBundle+HotPocketExtensions.m
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// NSBundle+HotPocketExtensions.m
|
||||||
|
// HotPocket
|
||||||
|
//
|
||||||
|
// Created by Tomek Wójcik on 17/11/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "NSBundle+HotPocketExtensions.h"
|
||||||
|
|
||||||
|
@implementation NSBundle (HotPocketExtensions)
|
||||||
|
|
||||||
|
+(NSString *)uname {
|
||||||
|
NSBundle *mainBundle = [NSBundle mainBundle];
|
||||||
|
return [NSString stringWithFormat:@"HotPocket v%@ (%@)", [mainBundle.infoDictionary valueForKey:@"CFBundleShortVersionString"], [mainBundle.infoDictionary valueForKey:@"CFBundleVersion"]];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 68 KiB |
@@ -5,10 +5,10 @@
|
|||||||
// Created by Tomek Wójcik on 21/08/2025.
|
// Created by Tomek Wójcik on 21/08/2025.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import "SafariWebExtensionHandler.h"
|
|
||||||
|
|
||||||
#import <SafariServices/SafariServices.h>
|
#import <SafariServices/SafariServices.h>
|
||||||
|
|
||||||
|
#import "SafariWebExtensionHandler.h"
|
||||||
|
|
||||||
@implementation SafariWebExtensionHandler
|
@implementation SafariWebExtensionHandler
|
||||||
|
|
||||||
- (void)beginRequestWithExtensionContext:(NSExtensionContext *)context {
|
- (void)beginRequestWithExtensionContext:(NSExtensionContext *)context {
|
||||||
|
|||||||
@@ -9,11 +9,14 @@
|
|||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@class UnameLabel;
|
||||||
|
|
||||||
@interface AuthorizationViewController : UIViewController
|
@interface AuthorizationViewController : UIViewController
|
||||||
|
|
||||||
@property UIImageView *invalidURLWarningView;
|
@property UIImageView *invalidURLWarningView;
|
||||||
|
|
||||||
@property IBOutlet UITextField *instanceURLField;
|
@property IBOutlet UITextField *instanceURLField;
|
||||||
|
@property IBOutlet UnameLabel *unameLabel;
|
||||||
|
|
||||||
-(IBAction)doStartAuthorizationFlow:(id)sender;
|
-(IBAction)doStartAuthorizationFlow:(id)sender;
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,9 @@
|
|||||||
#import "HPAuthFlow.h"
|
#import "HPAuthFlow.h"
|
||||||
#import "HPCredentialsHelper.h"
|
#import "HPCredentialsHelper.h"
|
||||||
#import "MainViewController.h"
|
#import "MainViewController.h"
|
||||||
|
#import "NSBundle+HotPocketExtensions.h"
|
||||||
#import "NSURL+HotPocketExtensions.h"
|
#import "NSURL+HotPocketExtensions.h"
|
||||||
|
#import "UnameLabel.h"
|
||||||
|
|
||||||
@interface AuthorizationViewController (AuthorizationViewControllerPrivate)
|
@interface AuthorizationViewController (AuthorizationViewControllerPrivate)
|
||||||
|
|
||||||
@@ -31,6 +33,8 @@
|
|||||||
self.invalidURLWarningView.contentMode = UIViewContentModeScaleAspectFit;
|
self.invalidURLWarningView.contentMode = UIViewContentModeScaleAspectFit;
|
||||||
self.invalidURLWarningView.frame = CGRectMake(0, 0, 16, 16);
|
self.invalidURLWarningView.frame = CGRectMake(0, 0, 16, 16);
|
||||||
self.invalidURLWarningView.tintColor = [UIColor colorNamed:@"WarningColor"];
|
self.invalidURLWarningView.tintColor = [UIColor colorNamed:@"WarningColor"];
|
||||||
|
|
||||||
|
self.unameLabel.text = [NSBundle uname];
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)viewWillAppear:(BOOL)animated {
|
-(void)viewWillAppear:(BOOL)animated {
|
||||||
|
|||||||
@@ -77,6 +77,13 @@
|
|||||||
<action selector="doLogOut:" destination="BYZ-38-t0r" eventType="primaryActionTriggered" id="iq7-wK-GMu"/>
|
<action selector="doLogOut:" destination="BYZ-38-t0r" eventType="primaryActionTriggered" id="iq7-wK-GMu"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SD4-ZJ-wLU" userLabel="uname Label" customClass="UnameLabel">
|
||||||
|
<rect key="frame" x="20" y="855" width="374" height="21"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||||
<color key="backgroundColor" name="BackgroundColor"/>
|
<color key="backgroundColor" name="BackgroundColor"/>
|
||||||
@@ -86,6 +93,7 @@
|
|||||||
<connections>
|
<connections>
|
||||||
<outlet property="instanceURLButton" destination="OPO-AY-zgd" id="1Wr-H9-eZ6"/>
|
<outlet property="instanceURLButton" destination="OPO-AY-zgd" id="1Wr-H9-eZ6"/>
|
||||||
<outlet property="logoutButton" destination="wQZ-n6-b0o" id="vco-vP-zvy"/>
|
<outlet property="logoutButton" destination="wQZ-n6-b0o" id="vco-vP-zvy"/>
|
||||||
|
<outlet property="unameLabel" destination="SD4-ZJ-wLU" id="LLk-wO-epu"/>
|
||||||
</connections>
|
</connections>
|
||||||
</viewController>
|
</viewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||||
@@ -136,7 +144,7 @@
|
|||||||
<action selector="doStartAuthorizationFlow:" destination="1Il-xJ-X5Y" eventType="primaryActionTriggered" id="Rd9-1f-N6Z"/>
|
<action selector="doStartAuthorizationFlow:" destination="1Il-xJ-X5Y" eventType="primaryActionTriggered" id="Rd9-1f-N6Z"/>
|
||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Enter the URL to your HotPocket instance, e.g. https://my.hotpocket.app" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Tn1-fl-daL" customClass="MultilineLabel">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Enter the URL to your HotPocket instance, e.g. https://hotpocket.yourcompany.com/" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Tn1-fl-daL" customClass="MultilineLabel">
|
||||||
<rect key="frame" x="20" y="348" width="374" height="64"/>
|
<rect key="frame" x="20" y="348" width="374" height="64"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
@@ -152,6 +160,13 @@
|
|||||||
<action selector="doStartAuthorizationFlow:" destination="1Il-xJ-X5Y" eventType="primaryActionTriggered" id="U0V-Pp-M2x"/>
|
<action selector="doStartAuthorizationFlow:" destination="1Il-xJ-X5Y" eventType="primaryActionTriggered" id="U0V-Pp-M2x"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gId-nt-VtS" userLabel="uname Label" customClass="UnameLabel">
|
||||||
|
<rect key="frame" x="20" y="855" width="374" height="21"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
<viewLayoutGuide key="safeArea" id="dL2-4T-yXY"/>
|
<viewLayoutGuide key="safeArea" id="dL2-4T-yXY"/>
|
||||||
<color key="backgroundColor" name="BackgroundColor"/>
|
<color key="backgroundColor" name="BackgroundColor"/>
|
||||||
@@ -159,6 +174,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="instanceURLField" destination="v5s-Uh-qWU" id="hRQ-r8-3Dz"/>
|
<outlet property="instanceURLField" destination="v5s-Uh-qWU" id="hRQ-r8-3Dz"/>
|
||||||
|
<outlet property="unameLabel" destination="gId-nt-VtS" id="ust-gO-7YN"/>
|
||||||
</connections>
|
</connections>
|
||||||
</viewController>
|
</viewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="m6b-Bm-Ty7" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="m6b-Bm-Ty7" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||||
|
|||||||
@@ -9,10 +9,13 @@
|
|||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@class UnameLabel;
|
||||||
|
|
||||||
@interface MainViewController : UIViewController
|
@interface MainViewController : UIViewController
|
||||||
|
|
||||||
@property IBOutlet UIButton *instanceURLButton;
|
@property IBOutlet UIButton *instanceURLButton;
|
||||||
@property IBOutlet UIButton *logoutButton;
|
@property IBOutlet UIButton *logoutButton;
|
||||||
|
@property IBOutlet UnameLabel *unameLabel;
|
||||||
|
|
||||||
-(IBAction)doOpenInstanceURL:(id)sender;
|
-(IBAction)doOpenInstanceURL:(id)sender;
|
||||||
-(IBAction)doLogOut:(id)sender;
|
-(IBAction)doLogOut:(id)sender;
|
||||||
|
|||||||
@@ -7,9 +7,10 @@
|
|||||||
|
|
||||||
#import "MainViewController.h"
|
#import "MainViewController.h"
|
||||||
|
|
||||||
#import "HPCredentialsHelper.h"
|
|
||||||
|
|
||||||
#import "AuthorizationViewController.h"
|
#import "AuthorizationViewController.h"
|
||||||
|
#import "HPCredentialsHelper.h"
|
||||||
|
#import "NSBundle+HotPocketExtensions.h"
|
||||||
|
#import "UnameLabel.h"
|
||||||
|
|
||||||
@interface MainViewController (MainViewControllerPrivate)
|
@interface MainViewController (MainViewControllerPrivate)
|
||||||
|
|
||||||
@@ -27,6 +28,8 @@
|
|||||||
[self.instanceURLButton setTitle:@"" forState:UIControlStateNormal];
|
[self.instanceURLButton setTitle:@"" forState:UIControlStateNormal];
|
||||||
self.instanceURLButton.enabled = NO;
|
self.instanceURLButton.enabled = NO;
|
||||||
|
|
||||||
|
self.unameLabel.text = [NSBundle uname];
|
||||||
|
|
||||||
self.logoutButton.enabled = NO;
|
self.logoutButton.enabled = NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
16
services/apple/iOS (App)/UnameLabel.h
Normal file
16
services/apple/iOS (App)/UnameLabel.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// UnameLabel.h
|
||||||
|
// HotPocket
|
||||||
|
//
|
||||||
|
// Created by Tomek Wójcik on 17/11/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface UnameLabel : UILabel
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
16
services/apple/iOS (App)/UnameLabel.m
Normal file
16
services/apple/iOS (App)/UnameLabel.m
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// UnameLabel.m
|
||||||
|
// HotPocket
|
||||||
|
//
|
||||||
|
// Created by Tomek Wójcik on 17/11/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "UnameLabel.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@implementation UnameLabel
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
|
|
||||||
int main(int argc, char * argv[]) {
|
int main(int argc, char * argv[]) {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
@class HPAPI;
|
@class HPAPI;
|
||||||
|
@class UnameLabel;
|
||||||
|
|
||||||
@interface ShareViewController : UIViewController
|
@interface ShareViewController : UIViewController
|
||||||
|
|
||||||
@@ -19,7 +20,7 @@
|
|||||||
@property IBOutlet UIView *doneView;
|
@property IBOutlet UIView *doneView;
|
||||||
@property IBOutlet UIView *errorView;
|
@property IBOutlet UIView *errorView;
|
||||||
@property IBOutlet UIView *unprocessableEntityView;
|
@property IBOutlet UIView *unprocessableEntityView;
|
||||||
@property IBOutlet UILabel *unameLabel;
|
@property IBOutlet UnameLabel *unameLabel;
|
||||||
|
|
||||||
-(IBAction)doCancel:(id)sender;
|
-(IBAction)doCancel:(id)sender;
|
||||||
-(IBAction)doClose:(id)sender;
|
-(IBAction)doClose:(id)sender;
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
#import "HPAPI.h"
|
#import "HPAPI.h"
|
||||||
#import "HPCredentialsHelper.h"
|
#import "HPCredentialsHelper.h"
|
||||||
#import "HPShareExtensionHelper.h"
|
#import "HPShareExtensionHelper.h"
|
||||||
|
#import "NSBundle+HotPocketExtensions.h"
|
||||||
|
#import "UnameLabel.h"
|
||||||
|
|
||||||
@implementation ShareViewController (ShareViewControllerPrivate)
|
@implementation ShareViewController (ShareViewControllerPrivate)
|
||||||
|
|
||||||
@@ -68,8 +70,7 @@
|
|||||||
self.errorView.hidden = YES;
|
self.errorView.hidden = YES;
|
||||||
self.unprocessableEntityView.hidden = YES;
|
self.unprocessableEntityView.hidden = YES;
|
||||||
|
|
||||||
NSBundle *mainBundle = [NSBundle mainBundle];
|
self.unameLabel.text = [NSBundle uname];
|
||||||
self.unameLabel.text = [NSString stringWithFormat:@"HotPocket v%@ (%@)", [mainBundle.infoDictionary valueForKey:@"CFBundleShortVersionString"], [mainBundle.infoDictionary valueForKey:@"CFBundleVersion"]];
|
|
||||||
|
|
||||||
self.api = [[HPAPI alloc] init];
|
self.api = [[HPAPI alloc] init];
|
||||||
if (self.api.rpcClient.hasCredentials == YES) {
|
if (self.api.rpcClient.hasCredentials == YES) {
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
#import "AuthorizationViewController.h"
|
#import "AuthorizationViewController.h"
|
||||||
|
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
#import "HPAuthFlow.h"
|
|
||||||
#import "AuthorizationProgressViewController.h"
|
#import "AuthorizationProgressViewController.h"
|
||||||
|
#import "HPAuthFlow.h"
|
||||||
#import "ReplaceAnimator.h"
|
#import "ReplaceAnimator.h"
|
||||||
|
|
||||||
@interface AuthorizationViewController (AuthorizationViewControllerPrivate)
|
@interface AuthorizationViewController (AuthorizationViewControllerPrivate)
|
||||||
|
|||||||
@@ -131,7 +131,7 @@
|
|||||||
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DIc-8O-uoQ">
|
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DIc-8O-uoQ">
|
||||||
<rect key="frame" x="18" y="68" width="389" height="48"/>
|
<rect key="frame" x="18" y="68" width="389" height="48"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" selectable="YES" title="Enter the URL to your HotPocket instance, e.g. https://my.hotpocket.app" id="Y0q-a1-oBP">
|
<textFieldCell key="cell" selectable="YES" title="Enter the URL to your HotPocket instance, e.g. https://hotpocket.yourcompany.com/" id="Y0q-a1-oBP">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
#import "MainViewController.h"
|
#import "MainViewController.h"
|
||||||
|
|
||||||
#import "HPCredentialsHelper.h"
|
|
||||||
#import "AuthorizationViewController.h"
|
#import "AuthorizationViewController.h"
|
||||||
|
#import "HPCredentialsHelper.h"
|
||||||
#import "ReplaceAnimator.h"
|
#import "ReplaceAnimator.h"
|
||||||
|
|
||||||
@interface MainViewController (MainViewControllerPrivate)
|
@interface MainViewController (MainViewControllerPrivate)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" animates="YES" imageScaling="proportionallyDown" image="icon-mac-384" id="NT0-XU-t9f"/>
|
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" animates="YES" imageScaling="proportionallyDown" image="icon-mac-384" id="NT0-XU-t9f"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KZW-gY-pvX">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KZW-gY-pvX">
|
||||||
<rect key="frame" x="18" y="138" width="352" height="28"/>
|
<rect key="frame" x="18" y="138" width="352" height="28"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="HotPocket by BTHLabs" id="urI-Z1-yMm">
|
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="HotPocket by BTHLabs" id="urI-Z1-yMm">
|
||||||
@@ -50,7 +50,7 @@ Gw
|
|||||||
<action selector="cancel:" target="-2" id="yRt-GR-jQ6"/>
|
<action selector="cancel:" target="-2" id="yRt-GR-jQ6"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5X8-4n-wWm">
|
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5X8-4n-wWm">
|
||||||
<rect key="frame" x="-2" y="28" width="352" height="32"/>
|
<rect key="frame" x="-2" y="28" width="352" height="32"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" selectable="YES" alignment="center" title="HotPocket couldn't complete this operation." id="fmg-RT-3FA">
|
<textFieldCell key="cell" selectable="YES" alignment="center" title="HotPocket couldn't complete this operation." id="fmg-RT-3FA">
|
||||||
@@ -94,7 +94,7 @@ Gw
|
|||||||
<action selector="close:" target="-2" id="3aP-Lu-EzX"/>
|
<action selector="close:" target="-2" id="3aP-Lu-EzX"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Mfx-pW-oi2">
|
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Mfx-pW-oi2">
|
||||||
<rect key="frame" x="-2" y="28" width="352" height="32"/>
|
<rect key="frame" x="-2" y="28" width="352" height="32"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" selectable="YES" alignment="center" title="Your link has been saved!" id="JhJ-K4-UFb">
|
<textFieldCell key="cell" selectable="YES" alignment="center" title="Your link has been saved!" id="JhJ-K4-UFb">
|
||||||
@@ -118,7 +118,7 @@ Gw
|
|||||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" animates="YES" imageScaling="proportionallyUpOrDown" image="exclamationmark.circle.fill" catalog="system" id="3kO-Gq-csg"/>
|
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" animates="YES" imageScaling="proportionallyUpOrDown" image="exclamationmark.circle.fill" catalog="system" id="3kO-Gq-csg"/>
|
||||||
<color key="contentTintColor" name="WarningColor"/>
|
<color key="contentTintColor" name="WarningColor"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="YLC-Bx-qKZ">
|
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="YLC-Bx-qKZ">
|
||||||
<rect key="frame" x="-2" y="28" width="352" height="32"/>
|
<rect key="frame" x="-2" y="28" width="352" height="32"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" selectable="YES" alignment="center" title="Open the HotPocket application to set it up." id="eYb-eq-cbo">
|
<textFieldCell key="cell" selectable="YES" alignment="center" title="Open the HotPocket application to set it up." id="eYb-eq-cbo">
|
||||||
@@ -183,7 +183,7 @@ Gw
|
|||||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" animates="YES" imageScaling="proportionallyUpOrDown" image="exclamationmark.circle.fill" catalog="system" id="66K-cT-2Vw"/>
|
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" animates="YES" imageScaling="proportionallyUpOrDown" image="exclamationmark.circle.fill" catalog="system" id="66K-cT-2Vw"/>
|
||||||
<color key="contentTintColor" name="WarningColor"/>
|
<color key="contentTintColor" name="WarningColor"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="LS4-qN-h75">
|
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="LS4-qN-h75">
|
||||||
<rect key="frame" x="-2" y="28" width="352" height="32"/>
|
<rect key="frame" x="-2" y="28" width="352" height="32"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" selectable="YES" alignment="center" title="This item couldn't be shared :(." id="b0i-Lf-21f">
|
<textFieldCell key="cell" selectable="YES" alignment="center" title="This item couldn't be shared :(." id="b0i-Lf-21f">
|
||||||
@@ -211,7 +211,7 @@ Gw
|
|||||||
<binding destination="-2" name="hidden" keyPath="self.unprocessableEntityViewHidden" id="lqC-lO-ll8"/>
|
<binding destination="-2" name="hidden" keyPath="self.unprocessableEntityViewHidden" id="lqC-lO-ll8"/>
|
||||||
</connections>
|
</connections>
|
||||||
</customView>
|
</customView>
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1yJ-sU-Spr" userLabel="uname Label">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1yJ-sU-Spr" userLabel="uname Label">
|
||||||
<rect key="frame" x="6" y="4" width="376" height="14"/>
|
<rect key="frame" x="6" y="4" width="376" height="14"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" alignment="center" id="nQ0-Es-oIB">
|
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" alignment="center" id="nQ0-Es-oIB">
|
||||||
@@ -233,7 +233,7 @@ Gw
|
|||||||
<image name="icon-mac-384" width="384" height="384"/>
|
<image name="icon-mac-384" width="384" height="384"/>
|
||||||
<image name="multiply.circle.fill" catalog="system" width="15" height="15"/>
|
<image name="multiply.circle.fill" catalog="system" width="15" height="15"/>
|
||||||
<namedColor name="DangerColor">
|
<namedColor name="DangerColor">
|
||||||
<color red="0.93300002813339233" green="0.3919999897480011" blue="0.46299999952316284" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color red="0.93333333333333335" green="0.39215686274509803" blue="0.46274509803921571" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</namedColor>
|
</namedColor>
|
||||||
<namedColor name="SuccessColor">
|
<namedColor name="SuccessColor">
|
||||||
<color red="0.054901960784313725" green="0.65490196078431373" blue="0.40392156862745099" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color red="0.054901960784313725" green="0.65490196078431373" blue="0.40392156862745099" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#import "HPAPI.h"
|
#import "HPAPI.h"
|
||||||
#import "HPShareExtensionHelper.h"
|
#import "HPShareExtensionHelper.h"
|
||||||
|
#import "NSBundle+HotPocketExtensions.h"
|
||||||
|
|
||||||
@implementation ShareViewController (ShareViewControllerPrivate)
|
@implementation ShareViewController (ShareViewControllerPrivate)
|
||||||
|
|
||||||
@@ -69,8 +70,7 @@
|
|||||||
self.errorViewHidden = YES;
|
self.errorViewHidden = YES;
|
||||||
self.unprocessableEntityViewHidden = YES;
|
self.unprocessableEntityViewHidden = YES;
|
||||||
|
|
||||||
NSBundle *mainBundle = [NSBundle mainBundle];
|
self.uname = [NSBundle uname];
|
||||||
self.uname = [NSString stringWithFormat:@"HotPocket v%@ (%@)", [mainBundle.infoDictionary valueForKey:@"CFBundleShortVersionString"], [mainBundle.infoDictionary valueForKey:@"CFBundleVersion"]];
|
|
||||||
|
|
||||||
self.api = [[HPAPI alloc] init];
|
self.api = [[HPAPI alloc] init];
|
||||||
if (self.api.rpcClient.hasCredentials == YES) {
|
if (self.api.rpcClient.hasCredentials == YES) {
|
||||||
|
|||||||
80
services/apple/poetry.lock
generated
80
services/apple/poetry.lock
generated
@@ -56,40 +56,6 @@ files = [
|
|||||||
[package.extras]
|
[package.extras]
|
||||||
tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich ; python_version >= \"3.11\""]
|
tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich ; python_version >= \"3.11\""]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "factory-boy"
|
|
||||||
version = "3.3.3"
|
|
||||||
description = "A versatile test fixtures replacement based on thoughtbot's factory_bot for Ruby."
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.8"
|
|
||||||
groups = ["dev"]
|
|
||||||
files = [
|
|
||||||
{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"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
Faker = ">=0.7.0"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
dev = ["Django", "Pillow", "SQLAlchemy", "coverage", "flake8", "isort", "mongoengine", "mongomock", "mypy", "tox", "wheel (>=0.32.0)", "zest.releaser[recommended]"]
|
|
||||||
doc = ["Sphinx", "sphinx-rtd-theme", "sphinxcontrib-spelling"]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "faker"
|
|
||||||
version = "37.11.0"
|
|
||||||
description = "Faker is a Python package that generates fake data for you."
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.9"
|
|
||||||
groups = ["dev"]
|
|
||||||
files = [
|
|
||||||
{file = "faker-37.11.0-py3-none-any.whl", hash = "sha256:1508d2da94dfd1e0087b36f386126d84f8583b3de19ac18e392a2831a6676c57"},
|
|
||||||
{file = "faker-37.11.0.tar.gz", hash = "sha256:22969803849ba0618be8eee2dd01d0d9e2cd3b75e6ff1a291fa9abcdb34da5e6"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
tzdata = "*"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flake8"
|
name = "flake8"
|
||||||
version = "7.3.0"
|
version = "7.3.0"
|
||||||
@@ -127,7 +93,7 @@ name = "hotpocket-workspace-tools"
|
|||||||
version = "1.0.0.dev0"
|
version = "1.0.0.dev0"
|
||||||
description = "HotPocket Workspace Tools"
|
description = "HotPocket Workspace Tools"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "^3.12"
|
python-versions = "^3.13"
|
||||||
groups = ["dev"]
|
groups = ["dev"]
|
||||||
files = []
|
files = []
|
||||||
develop = true
|
develop = true
|
||||||
@@ -169,35 +135,35 @@ ipython = {version = ">=7.31.1", markers = "python_version >= \"3.11\""}
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipython"
|
name = "ipython"
|
||||||
version = "9.6.0"
|
version = "9.7.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"]
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "ipython-9.6.0-py3-none-any.whl", hash = "sha256:5f77efafc886d2f023442479b8149e7d86547ad0a979e9da9f045d252f648196"},
|
{file = "ipython-9.7.0-py3-none-any.whl", hash = "sha256:bce8ac85eb9521adc94e1845b4c03d88365fd6ac2f4908ec4ed1eb1b0a065f9f"},
|
||||||
{file = "ipython-9.6.0.tar.gz", hash = "sha256:5603d6d5d356378be5043e69441a072b50a5b33b4503428c77b04cb8ce7bc731"},
|
{file = "ipython-9.7.0.tar.gz", hash = "sha256:5f6de88c905a566c6a9d6c400a8fed54a638e1f7543d17aae2551133216b1e4e"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
colorama = {version = "*", markers = "sys_platform == \"win32\""}
|
colorama = {version = ">=0.4.4", markers = "sys_platform == \"win32\""}
|
||||||
decorator = "*"
|
decorator = ">=4.3.2"
|
||||||
ipython-pygments-lexers = "*"
|
ipython-pygments-lexers = ">=1.0.0"
|
||||||
jedi = ">=0.16"
|
jedi = ">=0.18.1"
|
||||||
matplotlib-inline = "*"
|
matplotlib-inline = ">=0.1.5"
|
||||||
pexpect = {version = ">4.3", markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""}
|
pexpect = {version = ">4.3", markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""}
|
||||||
prompt_toolkit = ">=3.0.41,<3.1.0"
|
prompt_toolkit = ">=3.0.41,<3.1.0"
|
||||||
pygments = ">=2.4.0"
|
pygments = ">=2.11.0"
|
||||||
stack_data = "*"
|
stack_data = ">=0.6.0"
|
||||||
traitlets = ">=5.13.0"
|
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[matplotlib,test]", "setuptools (>=61.2)", "sphinx (>=1.3)", "sphinx-rtd-theme", "sphinx_toml (==0.0.4)", "typing_extensions"]
|
doc = ["docrepr", "exceptiongroup", "intersphinx_registry", "ipykernel", "ipython[matplotlib,test]", "setuptools (>=70.0)", "sphinx (>=8.0)", "sphinx-rtd-theme (>=0.1.8)", "sphinx_toml (==0.0.4)", "typing_extensions"]
|
||||||
matplotlib = ["matplotlib (>3.7)"]
|
matplotlib = ["matplotlib (>3.9)"]
|
||||||
test = ["packaging", "pytest", "pytest-asyncio", "testpath"]
|
test = ["packaging (>=20.1.0)", "pytest (>=7.0.0)", "pytest-asyncio (>=1.0.0)", "setuptools (>=61.2)", "testpath (>=0.2)"]
|
||||||
test-extra = ["curio", "ipykernel", "ipython[matplotlib]", "ipython[test]", "jupyter_ai", "nbclient", "nbformat", "numpy (>=1.25)", "pandas (>2.0)", "trio"]
|
test-extra = ["curio", "ipykernel (>6.30)", "ipython[matplotlib]", "ipython[test]", "jupyter_ai", "nbclient", "nbformat", "numpy (>=1.27)", "pandas (>2.1)", "trio (>=0.1.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipython-pygments-lexers"
|
name = "ipython-pygments-lexers"
|
||||||
@@ -523,18 +489,6 @@ files = [
|
|||||||
{file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"},
|
{file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tzdata"
|
|
||||||
version = "2025.2"
|
|
||||||
description = "Provider of IANA time zone data"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2"
|
|
||||||
groups = ["dev"]
|
|
||||||
files = [
|
|
||||||
{file = "tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"},
|
|
||||||
{file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wcwidth"
|
name = "wcwidth"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
@@ -549,5 +503,5 @@ files = [
|
|||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.1"
|
lock-version = "2.1"
|
||||||
python-versions = "^3.12"
|
python-versions = "^3.13"
|
||||||
content-hash = "b03ef0369277d183d033049206a4cfd5f450473179995a4a79165fbb84d81fa0"
|
content-hash = "b38eaf0455b1239589b6f8d89e40bee3410324fcf073d4513912166429713dfe"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "hotpocket-apple"
|
name = "hotpocket-apple"
|
||||||
version = "25.10.21"
|
version = "25.11.19"
|
||||||
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"
|
||||||
@@ -8,15 +8,14 @@ readme = "README.md"
|
|||||||
package-mode = false
|
package-mode = false
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.12"
|
python = "^3.13"
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
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}
|
||||||
ipdb = "0.13.13"
|
ipdb = "0.13.13"
|
||||||
ipython = "9.6.0"
|
ipython = "9.7.0"
|
||||||
isort = "7.0.0"
|
isort = "7.0.0"
|
||||||
mypy = "1.18.2"
|
mypy = "1.18.2"
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ def flake8(ctx: Context):
|
|||||||
|
|
||||||
|
|
||||||
@task
|
@task
|
||||||
def isort(ctx, check=False, diff=False):
|
def isort(ctx: Context, check=False, diff=False):
|
||||||
command_parts = [
|
command_parts = [
|
||||||
'isort',
|
'isort',
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
ARG APP_USER_UID=1000
|
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
|
||||||
|
ARG IMAGE_VERSION=v00.00.00
|
||||||
|
ARG IMAGE_REVISION=00000000
|
||||||
|
|
||||||
FROM docker-hosted.nexus.bthlabs.pl/hotpocket/base:build-node-20251014-01 AS development
|
FROM docker-hosted.nexus.bthlabs.pl/hotpocket/base:build-node-20251114-01 AS development
|
||||||
|
|
||||||
ARG APP_USER_UID
|
ARG APP_USER_UID
|
||||||
ARG APP_USER_GID
|
ARG APP_USER_GID
|
||||||
@@ -12,7 +14,7 @@ COPY --chown=$APP_USER_UID:$APP_USER_GID backend/ops/bin/*.sh /srv/bin/
|
|||||||
|
|
||||||
VOLUME ["/srv/node_modules", "/srv/venv"]
|
VOLUME ["/srv/node_modules", "/srv/venv"]
|
||||||
|
|
||||||
FROM docker-hosted.nexus.bthlabs.pl/hotpocket/base:build-python-20251014-01 AS deployment-build
|
FROM docker-hosted.nexus.bthlabs.pl/hotpocket/base:build-python-20251114-01 AS deployment-build
|
||||||
|
|
||||||
ARG APP_USER_UID
|
ARG APP_USER_UID
|
||||||
ARG APP_USER_GID
|
ARG APP_USER_GID
|
||||||
@@ -31,7 +33,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-20251014-01 AS deployment-base
|
FROM docker-hosted.nexus.bthlabs.pl/hotpocket/base:base-20251114-01 AS deployment-base
|
||||||
|
|
||||||
ARG APP_USER_UID
|
ARG APP_USER_UID
|
||||||
ARG APP_USER_GID
|
ARG APP_USER_GID
|
||||||
@@ -45,11 +47,12 @@ 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/
|
||||||
|
COPY --chown=root:root backend/ops/etc/sudoers_app /etc/sudoers.d/app
|
||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y libpq5 dumb-init && \
|
apt-get install -y libpq5 dumb-init sudo && \
|
||||||
apt-get clean autoclean && \
|
apt-get clean autoclean && \
|
||||||
apt-get autoremove --yes && \
|
apt-get autoremove --yes && \
|
||||||
rm -rf /var/lib/apt /var/lib/dpkg && \
|
rm -rf /var/lib/apt /var/lib/dpkg && \
|
||||||
@@ -62,11 +65,27 @@ CMD ["/srv/venv/bin/gunicorn", "-c", "/srv/lib/gunicorn.conf.py", "hotpocket_bac
|
|||||||
|
|
||||||
FROM deployment-base AS deployment
|
FROM deployment-base AS deployment
|
||||||
|
|
||||||
|
ARG IMAGE_VERSION
|
||||||
|
ARG IMAGE_REVISION
|
||||||
|
|
||||||
|
LABEL org.opencontainers.image.authors="Tomek Wójcik <contact@bthlabs.pl>"
|
||||||
|
LABEL org.opencontainers.image.url="https://git.bthlabs.pl/tomekwojcik/hotpocket"
|
||||||
|
LABEL org.opencontainers.image.documentation="https://git.bthlabs.pl/tomekwojcik/hotpocket"
|
||||||
|
LABEL org.opencontainers.image.source="https://git.bthlabs.pl/tomekwojcik/hotpocket.git"
|
||||||
|
LABEL org.opencontainers.image.version="${IMAGE_VERSION}"
|
||||||
|
LABEL org.opencontainers.image.revision="${IMAGE_REVISION}"
|
||||||
|
LABEL org.opencontainers.image.vendor="BTHLabs <contact@bthlabs.pl>"
|
||||||
|
LABEL org.opencontainers.image.title="HotPocket by BTHLabs"
|
||||||
|
LABEL org.opencontainers.image.description="Minimal self-hosted bookmarking app :)"
|
||||||
|
LABEL org.opencontainers.image.licenses="Apache-2.0"
|
||||||
|
|
||||||
ARG APP_USER_UID
|
ARG APP_USER_UID
|
||||||
ARG APP_USER_GID
|
ARG APP_USER_GID
|
||||||
ARG IMAGE_ID
|
ARG IMAGE_ID
|
||||||
|
|
||||||
ENV DJANGO_SETTINGS_MODULE=hotpocket_backend.settings.deployment.webapp
|
ENV DJANGO_SETTINGS_MODULE=hotpocket_backend.settings.deployment.webapp
|
||||||
|
ENV HOTPOCKET_BACKEND_APP_USER_UID=${APP_USER_UID}
|
||||||
|
ENV HOTPOCKET_BACKEND_APP_USER_GID=${APP_USER_GID}
|
||||||
ENV HOTPOCKET_BACKEND_ENV=deployment
|
ENV HOTPOCKET_BACKEND_ENV=deployment
|
||||||
ENV HOTPOCKET_BACKEND_APP=webapp
|
ENV HOTPOCKET_BACKEND_APP=webapp
|
||||||
|
|
||||||
@@ -74,11 +93,27 @@ VOLUME ["/srv/run", "/srv/uploads"]
|
|||||||
|
|
||||||
FROM deployment-base AS aio
|
FROM deployment-base AS aio
|
||||||
|
|
||||||
|
ARG IMAGE_VERSION
|
||||||
|
ARG IMAGE_REVISION
|
||||||
|
|
||||||
|
LABEL org.opencontainers.image.authors="Tomek Wójcik <contact@bthlabs.pl>"
|
||||||
|
LABEL org.opencontainers.image.url="https://git.bthlabs.pl/tomekwojcik/hotpocket"
|
||||||
|
LABEL org.opencontainers.image.documentation="https://git.bthlabs.pl/tomekwojcik/hotpocket"
|
||||||
|
LABEL org.opencontainers.image.source="https://git.bthlabs.pl/tomekwojcik/hotpocket.git"
|
||||||
|
LABEL org.opencontainers.image.version="${IMAGE_VERSION}"
|
||||||
|
LABEL org.opencontainers.image.revision="${IMAGE_REVISION}"
|
||||||
|
LABEL org.opencontainers.image.vendor="BTHLabs <contact@bthlabs.pl>"
|
||||||
|
LABEL org.opencontainers.image.title="BTHLabs Docker Bastion"
|
||||||
|
LABEL org.opencontainers.image.description="Minimal self-hosted bookmarking app :)"
|
||||||
|
LABEL org.opencontainers.image.licenses="Apache-2.0"
|
||||||
|
|
||||||
ARG APP_USER_UID
|
ARG APP_USER_UID
|
||||||
ARG APP_USER_GID
|
ARG APP_USER_GID
|
||||||
ARG IMAGE_ID
|
ARG IMAGE_ID
|
||||||
|
|
||||||
ENV DJANGO_SETTINGS_MODULE=hotpocket_backend.settings.aio
|
ENV DJANGO_SETTINGS_MODULE=hotpocket_backend.settings.aio
|
||||||
|
ENV HOTPOCKET_BACKEND_APP_USER_UID=${APP_USER_UID}
|
||||||
|
ENV HOTPOCKET_BACKEND_APP_USER_GID=${APP_USER_GID}
|
||||||
ENV HOTPOCKET_BACKEND_ENV=aio
|
ENV HOTPOCKET_BACKEND_ENV=aio
|
||||||
ENV HOTPOCKET_BACKEND_APP=webapp
|
ENV HOTPOCKET_BACKEND_APP=webapp
|
||||||
ENV HOTPOCKET_BACKEND_DEBUG=false
|
ENV HOTPOCKET_BACKEND_DEBUG=false
|
||||||
@@ -92,6 +127,7 @@ ENV HOTPOCKET_BACKEND_CELERY_IGNORE_RESULT=true
|
|||||||
ENV HOTPOCKET_BACKEND_CELERY_ALWAYS_EAGER=true
|
ENV HOTPOCKET_BACKEND_CELERY_ALWAYS_EAGER=true
|
||||||
ENV HOTPOCKET_BACKEND_GUNICORN_WORKERS=2
|
ENV HOTPOCKET_BACKEND_GUNICORN_WORKERS=2
|
||||||
ENV HOTPOCKET_BACKEND_RUN_MIGRATIONS=true
|
ENV HOTPOCKET_BACKEND_RUN_MIGRATIONS=true
|
||||||
|
ENV HOTPOCKET_BACKEND_CREATE_INITIAL_ACCOUNT=true
|
||||||
ENV HOTPOCKET_BACKEND_UPLOADS_PATH=/srv/run/uploads
|
ENV HOTPOCKET_BACKEND_UPLOADS_PATH=/srv/run/uploads
|
||||||
|
|
||||||
VOLUME ["/srv/run"]
|
VOLUME ["/srv/run"]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
version = '25.10.21'
|
version = '25.11.19'
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from django.core.management import BaseCommand
|
|||||||
import django.db
|
import django.db
|
||||||
|
|
||||||
from hotpocket_backend.apps.accounts.models import Account
|
from hotpocket_backend.apps.accounts.models import Account
|
||||||
|
from hotpocket_backend.apps.core.conf import settings
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -17,12 +18,12 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
def add_arguments(self, parser: ArgumentParser):
|
def add_arguments(self, parser: ArgumentParser):
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'username',
|
'-u', '--username', default=None,
|
||||||
help='Username for the Account',
|
help='Override username for the Account',
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'password',
|
'-p', '--password', default=None,
|
||||||
help='Password for the Account',
|
help='Override Password for the Account',
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-d', '--dry-run', action='store_true', default=False,
|
'-d', '--dry-run', action='store_true', default=False,
|
||||||
@@ -31,10 +32,22 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
LOGGER.debug('args=`%s` options=`%s`', args, options)
|
LOGGER.debug('args=`%s` options=`%s`', args, options)
|
||||||
username = options.get('username')
|
|
||||||
password = options.get('password')
|
|
||||||
dry_run = options.get('dry_run', False)
|
dry_run = options.get('dry_run', False)
|
||||||
|
|
||||||
|
username = options.get('username') or settings.SECRETS.INITIAL_ACCOUNT.username
|
||||||
|
if not username:
|
||||||
|
LOGGER.info('Not creating initial Account: empty `username`')
|
||||||
|
return
|
||||||
|
|
||||||
|
password = options.get('password') or settings.SECRETS.INITIAL_ACCOUNT.password
|
||||||
|
assert password, 'Unable to proceed: empty `password`'
|
||||||
|
|
||||||
|
LOGGER.debug(
|
||||||
|
'Creating initial Account: username=`%s` password=`%s`',
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
)
|
||||||
|
|
||||||
with django.db.transaction.atomic():
|
with django.db.transaction.atomic():
|
||||||
current_account = Account.objects.filter(username=username).first()
|
current_account = Account.objects.filter(username=username).first()
|
||||||
if current_account is not None:
|
if current_account is not None:
|
||||||
|
|||||||
@@ -79,3 +79,17 @@ class AuthKeysService:
|
|||||||
raise self.NotFound(
|
raise self.NotFound(
|
||||||
f'Auth Key not found: key=`{key}`',
|
f'Auth Key not found: key=`{key}`',
|
||||||
) from exception
|
) from exception
|
||||||
|
|
||||||
|
def clean_expired_auth_keys(self) -> int:
|
||||||
|
current_timestamp = now()
|
||||||
|
cutoff_timestamp = current_timestamp - datetime.timedelta(
|
||||||
|
seconds=(settings.AUTH_KEY_TTL + 5),
|
||||||
|
)
|
||||||
|
|
||||||
|
deleted, _ = AuthKey.active_objects.\
|
||||||
|
filter(
|
||||||
|
created_at__lte=cutoff_timestamp,
|
||||||
|
).\
|
||||||
|
delete()
|
||||||
|
|
||||||
|
return deleted
|
||||||
|
|||||||
20
services/backend/hotpocket_backend/apps/accounts/tasks.py
Normal file
20
services/backend/hotpocket_backend/apps/accounts/tasks.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from celery import shared_task
|
||||||
|
from django import db
|
||||||
|
|
||||||
|
from hotpocket_backend.apps.accounts.services import AuthKeysService
|
||||||
|
|
||||||
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@shared_task
|
||||||
|
def clean_expired_auth_keys():
|
||||||
|
with db.transaction.atomic():
|
||||||
|
deleted_count = AuthKeysService().clean_expired_auth_keys()
|
||||||
|
LOGGER.debug(
|
||||||
|
'Deleted expired AuthKey objects: deleted_count=`%d`', deleted_count,
|
||||||
|
)
|
||||||
@@ -1,12 +1,25 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from hotpocket_backend.apps.core.conf import settings
|
||||||
|
|
||||||
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class CoreConfig(AppConfig):
|
class CoreConfig(AppConfig):
|
||||||
default_auto_field = 'django.db.models.BigAutoField'
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
label = 'core'
|
label = 'core'
|
||||||
name = 'hotpocket_backend.apps.core'
|
name = 'hotpocket_backend.apps.core'
|
||||||
verbose_name = _('Core')
|
verbose_name = _('Core')
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
LOGGER.info(
|
||||||
|
'HotPocket Backend ready: env=`%s` app=`%s`',
|
||||||
|
settings.ENV.name,
|
||||||
|
settings.APP.name,
|
||||||
|
)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import typing
|
|||||||
|
|
||||||
from hotpocket_backend.secrets.admin import AdminSecrets
|
from hotpocket_backend.secrets.admin import AdminSecrets
|
||||||
from hotpocket_backend.secrets.webapp import WebAppSecrets
|
from hotpocket_backend.secrets.webapp import WebAppSecrets
|
||||||
from hotpocket_common.constants import App, Env
|
from hotpocket_common.constants import App, Environment
|
||||||
|
|
||||||
|
|
||||||
class PSettings(typing.Protocol):
|
class PSettings(typing.Protocol):
|
||||||
@@ -16,7 +16,7 @@ class PSettings(typing.Protocol):
|
|||||||
SECRET_KEY: str
|
SECRET_KEY: str
|
||||||
|
|
||||||
APP: App
|
APP: App
|
||||||
ENV: Env
|
ENV: Environment
|
||||||
|
|
||||||
SECRETS: AdminSecrets | WebAppSecrets
|
SECRETS: AdminSecrets | WebAppSecrets
|
||||||
|
|
||||||
@@ -32,3 +32,9 @@ class PSettings(typing.Protocol):
|
|||||||
UPLOADS_PATH: pathlib.Path
|
UPLOADS_PATH: pathlib.Path
|
||||||
|
|
||||||
AUTH_KEY_TTL: int
|
AUTH_KEY_TTL: int
|
||||||
|
|
||||||
|
UI_BASE_HEAD_INCLUDES: list
|
||||||
|
UI_BASE_SCRIPT_INCLUDES: list
|
||||||
|
|
||||||
|
UI_PAGE_HEAD_INCLUDES: list
|
||||||
|
UI_PAGE_SCRIPT_INCLUDES: list
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# Generated by Django 5.2.8 on 2025-11-18 14:13
|
||||||
|
|
||||||
|
import django.core.validators
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('saves', '0008_alter_save_url'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='save',
|
||||||
|
name='description',
|
||||||
|
field=models.CharField(blank=True, db_index=True, default=None, null=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='save',
|
||||||
|
name='title',
|
||||||
|
field=models.CharField(blank=True, db_index=True, default=None, null=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='save',
|
||||||
|
name='url',
|
||||||
|
field=models.CharField(db_index=True, default=None, validators=[django.core.validators.URLValidator(schemes=['http', 'https'])]),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -20,7 +20,7 @@ class Save(Model):
|
|||||||
blank=False, null=False, default=None, db_index=True,
|
blank=False, null=False, default=None, db_index=True,
|
||||||
)
|
)
|
||||||
url = models.CharField(
|
url = models.CharField(
|
||||||
blank=False, null=False, default=None,
|
blank=False, null=False, default=None, db_index=True,
|
||||||
validators=[
|
validators=[
|
||||||
validators.URLValidator(schemes=['http', 'https']),
|
validators.URLValidator(schemes=['http', 'https']),
|
||||||
],
|
],
|
||||||
@@ -29,10 +29,10 @@ class Save(Model):
|
|||||||
blank=True, null=True, default=None, editable=False,
|
blank=True, null=True, default=None, editable=False,
|
||||||
)
|
)
|
||||||
title = models.CharField(
|
title = models.CharField(
|
||||||
blank=True, null=True, default=None,
|
blank=True, null=True, default=None, db_index=True,
|
||||||
)
|
)
|
||||||
description = models.CharField(
|
description = models.CharField(
|
||||||
blank=True, null=True, default=None,
|
blank=True, null=True, default=None, db_index=True,
|
||||||
)
|
)
|
||||||
last_processed_at = models.DateTimeField(
|
last_processed_at = models.DateTimeField(
|
||||||
auto_now=False,
|
auto_now=False,
|
||||||
|
|||||||
@@ -82,3 +82,21 @@ def appearance_settings(request: HttpRequest) -> dict:
|
|||||||
return {
|
return {
|
||||||
'APPEARANCE_SETTINGS': result,
|
'APPEARANCE_SETTINGS': result,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def base_includes(request: HttpRequest) -> dict:
|
||||||
|
return {
|
||||||
|
'BASE_INCLUDES': {
|
||||||
|
'head': settings.UI_BASE_HEAD_INCLUDES,
|
||||||
|
'script': settings.UI_BASE_SCRIPT_INCLUDES,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def page_includes(request: HttpRequest) -> dict:
|
||||||
|
return {
|
||||||
|
'PAGE_INCLUDES': {
|
||||||
|
'head': settings.UI_PAGE_HEAD_INCLUDES,
|
||||||
|
'script': settings.UI_PAGE_SCRIPT_INCLUDES,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|||||||
@@ -122,3 +122,7 @@ body.ui-mode-standalone #offcanvas-controls .offcanvas-body {
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ui-login-logo {
|
||||||
|
width: 128px;
|
||||||
|
}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
@@ -1,6 +1,6 @@
|
|||||||
{% extends "ui/base.html" %}
|
{% extends "ui/base.html" %}
|
||||||
|
|
||||||
{% load crispy_forms_tags i18n ui %}
|
{% load crispy_forms_tags i18n static ui %}
|
||||||
|
|
||||||
{% block title %}{% translate 'Log in' %}{% endblock %}
|
{% block title %}{% translate 'Log in' %}{% endblock %}
|
||||||
|
|
||||||
@@ -10,6 +10,11 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col col-12 col-md-6 offset-md-3">
|
<div class="col col-12 col-md-6 offset-md-3">
|
||||||
|
<img
|
||||||
|
alt="HotPocket Icon"
|
||||||
|
class="d-block ms-auto me-auto ui-login-logo"
|
||||||
|
src="{% static 'ui/img/icon-mac-384.png' %}"
|
||||||
|
>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header text-center">
|
<div class="card-header text-center">
|
||||||
<p class="fs-3 mb-0">{{ SITE_TITLE }}</p>
|
<p class="fs-3 mb-0">{{ SITE_TITLE }}</p>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer d-flex align-items-center">
|
<div class="card-footer d-flex align-items-center">
|
||||||
<a href="{{ association.target.url }}" target="_blank" rel="noopener noreferer"><small>{{ association.target.url|render_url_domain }}</small></a>
|
<a href="{{ association.target.url }}" target="_blank" rel="noopener noreferrer"><small>{{ association.target.url|render_url_domain }}</small></a>
|
||||||
<div class="ms-auto flex-shrink-0 d-flex align-items-center">
|
<div class="ms-auto flex-shrink-0 d-flex align-items-center">
|
||||||
{% if not association.archived_at %}
|
{% if not association.archived_at %}
|
||||||
<div class="spinner-border spinner-border-sm ui-htmx-indicator" role="status">
|
<div class="spinner-border spinner-border-sm ui-htmx-indicator" role="status">
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
{% blocktranslate with created_at=association.created_at %}Saved on {{ created_at }}{% endblocktranslate %}
|
{% blocktranslate with created_at=association.created_at %}Saved on {{ created_at }}{% endblocktranslate %}
|
||||||
</span>
|
</span>
|
||||||
<br>
|
<br>
|
||||||
<a href="{{ association.target.url }}" target="_blank" rel="noopener noreferer">
|
<a href="{{ association.target.url }}" target="_blank" rel="noopener noreferrer">
|
||||||
{% translate 'View original' %} <i class="bi bi-box-arrow-up-right"></i>
|
{% translate 'View original' %} <i class="bi bi-box-arrow-up-right"></i>
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
<a
|
<a
|
||||||
class="btn btn-secondary btn-sm ui-noscript-show"
|
class="btn btn-secondary btn-sm ui-noscript-show"
|
||||||
href="{{ share_url }}"
|
href="{{ share_url }}"
|
||||||
rel="noopener noreferer"
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<i class="bi bi-link-45deg"></i> {% translate 'Share link' %}
|
<i class="bi bi-link-45deg"></i> {% translate 'Share link' %}
|
||||||
|
|||||||
@@ -31,11 +31,17 @@
|
|||||||
<link rel="icon" type="image/png" sizes="32x32" href="{% static 'ui/img/icon-32.png' %}">
|
<link rel="icon" type="image/png" sizes="32x32" href="{% static 'ui/img/icon-32.png' %}">
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="{% static 'ui/img/icon-16.png' %}">
|
<link rel="icon" type="image/png" sizes="16x16" href="{% static 'ui/img/icon-16.png' %}">
|
||||||
<link rel="manifest" href="{% url 'ui.meta.manifest_json' %}">
|
<link rel="manifest" href="{% url 'ui.meta.manifest_json' %}">
|
||||||
|
{% for head_include in BASE_INCLUDES.head %}
|
||||||
|
{% include head_include %}
|
||||||
|
{% endfor %}
|
||||||
{% block page_head %}{% endblock %}
|
{% block page_head %}{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body class="{% block body_class %}{% endblock %}" hx-headers='{"x-csrftoken": "{{ csrf_token }}"}'>
|
<body class="{% block body_class %}{% endblock %}" hx-headers='{"x-csrftoken": "{{ csrf_token }}"}'>
|
||||||
{% block body %}
|
{% block body %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block scripts %}{% endblock %}
|
{% block scripts %}{% endblock %}
|
||||||
|
{% for script_include in BASE_INCLUDES.script %}
|
||||||
|
{% include script_include %}
|
||||||
|
{% endfor %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -2,6 +2,12 @@
|
|||||||
|
|
||||||
{% load i18n static ui %}
|
{% load i18n static ui %}
|
||||||
|
|
||||||
|
{% block page_head %}
|
||||||
|
{% for head_include in PAGE_INCLUDES.head %}
|
||||||
|
{% include head_include %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<nav id="navbar" class="navbar navbar-expand-sm bg-body-tertiary fixed-top">
|
<nav id="navbar" class="navbar navbar-expand-sm bg-body-tertiary fixed-top">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@@ -153,7 +159,11 @@
|
|||||||
<script src="{% static 'ui/js/hotpocket-backend.ui.BrowseAccountAppsView.js' %}" type="text/javascript"></script>
|
<script src="{% static 'ui/js/hotpocket-backend.ui.BrowseAccountAppsView.js' %}" type="text/javascript"></script>
|
||||||
<script src="{% static 'ui/js/hotpocket-backend.ui.InlineCreateSaveForm.js' %}" type="text/javascript"></script>
|
<script src="{% static 'ui/js/hotpocket-backend.ui.InlineCreateSaveForm.js' %}" type="text/javascript"></script>
|
||||||
<script src="{% static 'ui/js/hotpocket-backend.ui.PasteboardLink.js' %}" type="text/javascript"></script>
|
<script src="{% static 'ui/js/hotpocket-backend.ui.PasteboardLink.js' %}" type="text/javascript"></script>
|
||||||
{% block page_scripts %}{% endblock %}
|
{% for script_include in PAGE_INCLUDES.script %}
|
||||||
|
{% include script_include %}
|
||||||
|
{% endfor %}
|
||||||
|
{% block page_scripts %}
|
||||||
|
{% endblock %}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
(() => {
|
(() => {
|
||||||
window.HotPocket.run({
|
window.HotPocket.run({
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<p class="mb-0 mt-2 text-center text-muted ui-uname">
|
<p class="mb-0 mt-2 text-center text-muted ui-uname">
|
||||||
<span>
|
<span>
|
||||||
<a href="https://hotpocket.app/" target="_blank" rel="noopener noreferer">{{ SITE_TITLE }}</a> v{{ VERSION }}
|
<a href="https://hotpocket.app/" target="_blank" rel="noopener noreferrer">{{ SITE_TITLE }}</a> v{{ VERSION }}
|
||||||
(<code>{{ IMAGE_ID }}</code>)
|
(<code>{{ IMAGE_ID }}</code>)
|
||||||
</span>
|
</span>
|
||||||
<br>
|
<br>
|
||||||
|
|||||||
@@ -78,9 +78,13 @@ urlpatterns = [
|
|||||||
name='ui.integrations.ios.shortcut',
|
name='ui.integrations.ios.shortcut',
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
|
# Turns out PWAs can register a share target in Windows 11 when
|
||||||
|
# installed through Edge. Neat, too. I wish I knew this when I defined
|
||||||
|
# this URL path. Now it's gonna stay forever like this due to backwards
|
||||||
|
# compat ;).
|
||||||
'integrations/android/share-sheet/',
|
'integrations/android/share-sheet/',
|
||||||
integrations.android.share_sheet,
|
integrations.pwa.share_sheet,
|
||||||
name='ui.integrations.android.share_sheet',
|
name='ui.integrations.pwa.share_sheet',
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
'integrations/extension/authenticate/',
|
'integrations/extension/authenticate/',
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
from . import android # noqa: F401
|
|
||||||
from . import extension # noqa: F401
|
from . import extension # noqa: F401
|
||||||
from . import ios # noqa: F401
|
from . import ios # noqa: F401
|
||||||
|
from . import pwa # noqa: F401
|
||||||
|
|||||||
@@ -21,10 +21,14 @@ def share_sheet(request: HttpRequest) -> HttpResponse:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
assert request.user.is_anonymous is False, 'Login required'
|
assert request.user.is_anonymous is False, 'Login required'
|
||||||
assert 'text' in request.POST, 'Bad request: Missing `text`'
|
|
||||||
|
|
||||||
|
url: str = ''
|
||||||
|
if 'url' in request.POST:
|
||||||
|
url = request.POST['url'].strip()
|
||||||
|
elif 'text' in request.POST:
|
||||||
url = request.POST['text'].split('\n')[0].strip()
|
url = request.POST['text'].split('\n')[0].strip()
|
||||||
assert url != '', 'Bad request: Empty `text`'
|
|
||||||
|
assert url != '', 'Bad request: Empty `url`'
|
||||||
|
|
||||||
return CreateSaveWorkflow().run(
|
return CreateSaveWorkflow().run(
|
||||||
request=request,
|
request=request,
|
||||||
@@ -50,7 +50,7 @@ def manifest_json(request: HttpRequest) -> JsonResponse:
|
|||||||
'scope': '/',
|
'scope': '/',
|
||||||
'share_target': {
|
'share_target': {
|
||||||
'action': request.build_absolute_uri(
|
'action': request.build_absolute_uri(
|
||||||
reverse('ui.integrations.android.share_sheet'),
|
reverse('ui.integrations.pwa.share_sheet'),
|
||||||
),
|
),
|
||||||
'method': 'POST',
|
'method': 'POST',
|
||||||
'enctype': 'multipart/form-data',
|
'enctype': 'multipart/form-data',
|
||||||
|
|||||||
@@ -3,7 +3,13 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from keep_it_secret import AbstractField, LiteralField, Secrets, SecretsField
|
from keep_it_secret import (
|
||||||
|
AbstractField,
|
||||||
|
EnvField,
|
||||||
|
LiteralField,
|
||||||
|
Secrets,
|
||||||
|
SecretsField,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DatabaseSecrets(Secrets):
|
class DatabaseSecrets(Secrets):
|
||||||
@@ -84,6 +90,19 @@ class CelerySecrets(Secrets):
|
|||||||
result_backend: str = AbstractField.new()
|
result_backend: str = AbstractField.new()
|
||||||
|
|
||||||
|
|
||||||
|
class InitialAccountSecrets(Secrets):
|
||||||
|
username: str = EnvField.new(
|
||||||
|
'HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME',
|
||||||
|
default=None,
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
password: str = EnvField.new(
|
||||||
|
'HOTPOCKET_BACKEND_INITIAL_ACCOUNT_PASSWORD',
|
||||||
|
default=None,
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class BaseSecrets(Secrets):
|
class BaseSecrets(Secrets):
|
||||||
SECRET_KEY: str = AbstractField.new()
|
SECRET_KEY: str = AbstractField.new()
|
||||||
|
|
||||||
@@ -91,3 +110,4 @@ class BaseSecrets(Secrets):
|
|||||||
CELERY: CelerySecrets = SecretsField.new(CelerySecrets)
|
CELERY: CelerySecrets = SecretsField.new(CelerySecrets)
|
||||||
|
|
||||||
OIDC: OIDCSecrets = SecretsField.new(OIDCSecrets)
|
OIDC: OIDCSecrets = SecretsField.new(OIDCSecrets)
|
||||||
|
INITIAL_ACCOUNT: InitialAccountSecrets = SecretsField.new(InitialAccountSecrets)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user