Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1af8a4be9a | |||
| 92473a2f52 | |||
| dc5f8ddb51 | |||
| d90504eed9 | |||
| 9565a71bc8 | |||
| dbb01a5225 | |||
| 0611ceb3ec | |||
| 3c71464663 | |||
| c842657766 | |||
| e2b2455bea | |||
| 1b775a130b | |||
| bcef0d2d09 | |||
| 9f121a0ceb | |||
| d16f0cd957 | |||
| 98e5e1891a | |||
| 06343e6ed3 | |||
| 82a3b612ec | |||
| 1e549d3fc2 | |||
| 55126f4af6 | |||
| cca49f2292 | |||
| 23f8296659 | |||
| 9abed01e53 | |||
| 3b1aba9672 | |||
| 22061486a8 | |||
| 38785ccf92 | |||
| 1f78a4a079 | |||
| 20fa33abeb | |||
| 16a9c73624 | |||
| b358ef6686 | |||
| ac9c7a81c3 | |||
| e800d0c16c | |||
| d8bbe57b17 |
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
@@ -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
@@ -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
@@ -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,4 +1,5 @@
|
|||||||
.ci/
|
.ci/
|
||||||
.envrc*
|
.envrc*
|
||||||
.ipythonhome/
|
.ipythonhome/
|
||||||
|
services/vendor/
|
||||||
/docker-compose-ci-*.yaml
|
/docker-compose-ci-*.yaml
|
||||||
|
|||||||
35
README.md
@@ -1,13 +1,30 @@
|
|||||||
# HotPocket by BTHLabs
|
# HotPocket by BTHLabs
|
||||||
|
|
||||||
This repository contains the _HotPocket_ project.
|
Minimal self-hosted bookmarking app :).
|
||||||
|
|
||||||
|
## The what, the why and the ugly
|
||||||
|
|
||||||
|
HotPocket is a minimal self-hosted bookmarking app. It combines a Web
|
||||||
|
application, companion apps, browser extensions to give you a way to quickly
|
||||||
|
save links for later.
|
||||||
|
|
||||||
|
HotPocket came to be to fill in the blank left by Pocket, after Mozilla shut it
|
||||||
|
down. I looked at the existing alternatives and found them either too
|
||||||
|
feature-rich, too involved to self-host or otherwise not to my liking. So I
|
||||||
|
decided to sit down and build something for myself.
|
||||||
|
|
||||||
|
With the what and why out of the way, let's talk about the ugly... At its core
|
||||||
|
HotPocket is a personal project. I built it by myself and for myself. It may
|
||||||
|
or may not fit your needs. If it does, happy saving!
|
||||||
|
|
||||||
|
If you're feeling up for an adventure, continue reading below :).
|
||||||
|
|
||||||
## Development setup
|
## Development setup
|
||||||
|
|
||||||
### 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 +83,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-v26.8.20-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
|
||||||
@@ -128,6 +145,7 @@ that can be used to configure the services.
|
|||||||
| `HOTPOCKET_BACKEND_RUN_MIGRATIONS` | `false` or `true` | Set to `true` to run database muigrations when the container starts. |
|
| `HOTPOCKET_BACKEND_RUN_MIGRATIONS` | `false` or `true` | Set to `true` to run database muigrations when the container starts. |
|
||||||
| `HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME` | N/A | Username for the initial account. |
|
| `HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME` | N/A | Username for the initial account. |
|
||||||
| `HOTPOCKET_BACKEND_INITIAL_ACCOUNT_PASSWORD` | N/A | Password for the initial account. |
|
| `HOTPOCKET_BACKEND_INITIAL_ACCOUNT_PASSWORD` | N/A | Password for the initial account. |
|
||||||
|
| `HOTPOCKET_BACKEND_OPERATOR_EMAIL` | N/A | Instance operator's e-mail. Used to display extra language on login page. |
|
||||||
|
|
||||||
**Env and App settings**
|
**Env and App settings**
|
||||||
|
|
||||||
@@ -158,6 +176,15 @@ method's name in the UI and defaults to `OIDC`.
|
|||||||
|
|
||||||
**NOTE:** Currently, only Keycloak has been tested with this login method.
|
**NOTE:** Currently, only Keycloak has been tested with this login method.
|
||||||
|
|
||||||
|
### Volumes
|
||||||
|
|
||||||
|
Both images declare `/srv/run` to be a volume. It's intended to keep the
|
||||||
|
service's runtime data, including but not limited to PID files, UNIX sockets
|
||||||
|
etc. It's recommended to persist this volume.
|
||||||
|
|
||||||
|
Additionally, the `deployment` image declares `/srv/uploads` to be a volume.
|
||||||
|
It's recommeded to persist this volume.
|
||||||
|
|
||||||
## Author
|
## Author
|
||||||
|
|
||||||
_HotPocket_ is developed by [BTHLabs](https://www.bthlabs.pl/).
|
_HotPocket_ is developed by [BTHLabs](https://www.bthlabs.pl/).
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
backend:
|
backend:
|
||||||
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:aio-v25.10.21-01"
|
image: "bthlabs/hotpocket:aio-v26.8.20-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: "bthlabs/hotpocket:deployment-v26.8.20-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: "bthlabs/hotpocket:deployment-v26.8.20-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: "bthlabs/hotpocket:deployment-v26.8.20-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: "bthlabs/hotpocket:deployment-v26.8.20-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
@@ -0,0 +1,3 @@
|
|||||||
|
.ci/
|
||||||
|
inventory_ci.yaml
|
||||||
|
vault.yaml
|
||||||
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
@@ -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.16.1.100"
|
||||||
|
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 = "26.8.20"
|
||||||
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
services/apple/.gitignore
vendored
@@ -92,3 +92,5 @@ Shared (Extension)/Resources/content-bundle.js
|
|||||||
Shared (Extension)/Resources/manifest.json
|
Shared (Extension)/Resources/manifest.json
|
||||||
Shared (Extension)/Resources/preauth.html
|
Shared (Extension)/Resources/preauth.html
|
||||||
Shared (Extension)/Resources/preauth.js
|
Shared (Extension)/Resources/preauth.js
|
||||||
|
Shared (Extension)/Resources/options.html
|
||||||
|
Shared (Extension)/Resources/options.js
|
||||||
|
|||||||
@@ -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-20260818-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; };
|
||||||
@@ -104,10 +104,13 @@
|
|||||||
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
||||||
membershipExceptions = (
|
membershipExceptions = (
|
||||||
Assets.xcassets,
|
Assets.xcassets,
|
||||||
|
"HotPocket 27.icon",
|
||||||
HPAPI.m,
|
HPAPI.m,
|
||||||
HPCredentialsHelper.m,
|
HPCredentialsHelper.m,
|
||||||
HPRPCClient.m,
|
HPRPCClient.m,
|
||||||
|
"NSBundle+HotPocketExtensions.m",
|
||||||
"NSURL+HotPocketExtensions.m",
|
"NSURL+HotPocketExtensions.m",
|
||||||
|
"Resources/icon-glass-512.png",
|
||||||
"Resources/icon-mac-384.png",
|
"Resources/icon-mac-384.png",
|
||||||
);
|
);
|
||||||
target = 4C2F0C5D2E851BBD0033F5C2 /* iOS (Share Extension) */;
|
target = 4C2F0C5D2E851BBD0033F5C2 /* iOS (Share Extension) */;
|
||||||
@@ -123,6 +126,7 @@
|
|||||||
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
||||||
membershipExceptions = (
|
membershipExceptions = (
|
||||||
MultilineLabel.m,
|
MultilineLabel.m,
|
||||||
|
UnameLabel.m,
|
||||||
);
|
);
|
||||||
target = 4C2F0C5D2E851BBD0033F5C2 /* iOS (Share Extension) */;
|
target = 4C2F0C5D2E851BBD0033F5C2 /* iOS (Share Extension) */;
|
||||||
};
|
};
|
||||||
@@ -130,11 +134,14 @@
|
|||||||
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
||||||
membershipExceptions = (
|
membershipExceptions = (
|
||||||
Assets.xcassets,
|
Assets.xcassets,
|
||||||
|
"HotPocket 27.icon",
|
||||||
HPAPI.m,
|
HPAPI.m,
|
||||||
HPAuthFlow.m,
|
HPAuthFlow.m,
|
||||||
HPCredentialsHelper.m,
|
HPCredentialsHelper.m,
|
||||||
HPRPCClient.m,
|
HPRPCClient.m,
|
||||||
|
"NSBundle+HotPocketExtensions.m",
|
||||||
"NSURL+HotPocketExtensions.m",
|
"NSURL+HotPocketExtensions.m",
|
||||||
|
"Resources/icon-glass-512.png",
|
||||||
"Resources/icon-mac-384.png",
|
"Resources/icon-mac-384.png",
|
||||||
);
|
);
|
||||||
target = 4CABCAAF2E56F0C900D8A354 /* HotPocket (iOS) */;
|
target = 4CABCAAF2E56F0C900D8A354 /* HotPocket (iOS) */;
|
||||||
@@ -157,11 +164,14 @@
|
|||||||
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
||||||
membershipExceptions = (
|
membershipExceptions = (
|
||||||
Assets.xcassets,
|
Assets.xcassets,
|
||||||
|
"HotPocket 27.icon",
|
||||||
HPAPI.m,
|
HPAPI.m,
|
||||||
HPAuthFlow.m,
|
HPAuthFlow.m,
|
||||||
HPCredentialsHelper.m,
|
HPCredentialsHelper.m,
|
||||||
HPRPCClient.m,
|
HPRPCClient.m,
|
||||||
|
"NSBundle+HotPocketExtensions.m",
|
||||||
"NSURL+HotPocketExtensions.m",
|
"NSURL+HotPocketExtensions.m",
|
||||||
|
"Resources/icon-glass-512.png",
|
||||||
"Resources/icon-mac-384.png",
|
"Resources/icon-mac-384.png",
|
||||||
);
|
);
|
||||||
target = 4CABCAC52E56F0C900D8A354 /* HotPocket (macOS) */;
|
target = 4CABCAC52E56F0C900D8A354 /* HotPocket (macOS) */;
|
||||||
@@ -181,6 +191,8 @@
|
|||||||
"Resources/content-bundle.js",
|
"Resources/content-bundle.js",
|
||||||
Resources/images,
|
Resources/images,
|
||||||
Resources/manifest.json,
|
Resources/manifest.json,
|
||||||
|
Resources/options.html,
|
||||||
|
Resources/options.js,
|
||||||
Resources/preauth.html,
|
Resources/preauth.html,
|
||||||
Resources/preauth.js,
|
Resources/preauth.js,
|
||||||
SafariWebExtensionHandler.m,
|
SafariWebExtensionHandler.m,
|
||||||
@@ -195,6 +207,8 @@
|
|||||||
"Resources/content-bundle.js",
|
"Resources/content-bundle.js",
|
||||||
Resources/images,
|
Resources/images,
|
||||||
Resources/manifest.json,
|
Resources/manifest.json,
|
||||||
|
Resources/options.html,
|
||||||
|
Resources/options.js,
|
||||||
Resources/preauth.html,
|
Resources/preauth.html,
|
||||||
Resources/preauth.js,
|
Resources/preauth.js,
|
||||||
SafariWebExtensionHandler.m,
|
SafariWebExtensionHandler.m,
|
||||||
@@ -212,10 +226,13 @@
|
|||||||
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
||||||
membershipExceptions = (
|
membershipExceptions = (
|
||||||
Assets.xcassets,
|
Assets.xcassets,
|
||||||
|
"HotPocket 27.icon",
|
||||||
HPAPI.m,
|
HPAPI.m,
|
||||||
HPCredentialsHelper.m,
|
HPCredentialsHelper.m,
|
||||||
HPRPCClient.m,
|
HPRPCClient.m,
|
||||||
|
"NSBundle+HotPocketExtensions.m",
|
||||||
"NSURL+HotPocketExtensions.m",
|
"NSURL+HotPocketExtensions.m",
|
||||||
|
"Resources/icon-glass-512.png",
|
||||||
"Resources/icon-mac-384.png",
|
"Resources/icon-mac-384.png",
|
||||||
);
|
);
|
||||||
target = 4CBCEA4E2E81CB9500722009 /* macOS (Share Extension) */;
|
target = 4CBCEA4E2E81CB9500722009 /* macOS (Share Extension) */;
|
||||||
@@ -384,8 +401,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 +458,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 +483,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 +730,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 = 2026082001;
|
||||||
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 +743,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 26.8.20;
|
||||||
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 +763,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 = 2026082001;
|
||||||
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 +776,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 26.8.20;
|
||||||
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;
|
||||||
@@ -778,8 +795,9 @@
|
|||||||
4CABCB062E56F0C900D8A354 /* Debug */ = {
|
4CABCB062E56F0C900D8A354 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = "HotPocket 27";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 2025102101;
|
CURRENT_PROJECT_VERSION = 2026082001;
|
||||||
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 +810,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 26.8.20;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
@@ -813,8 +831,9 @@
|
|||||||
4CABCB072E56F0C900D8A354 /* Release */ = {
|
4CABCB072E56F0C900D8A354 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = "HotPocket 27";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 2025102101;
|
CURRENT_PROJECT_VERSION = 2026082001;
|
||||||
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 +846,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 26.8.20;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
@@ -849,11 +868,11 @@
|
|||||||
4CABCB0B2E56F0C900D8A354 /* Debug */ = {
|
4CABCB0B2E56F0C900D8A354 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = "HotPocket 27";
|
||||||
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 = 2026082001;
|
||||||
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 +892,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 26.8.20;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
@@ -881,7 +900,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;
|
||||||
@@ -895,11 +914,11 @@
|
|||||||
4CABCB0C2E56F0C900D8A354 /* Release */ = {
|
4CABCB0C2E56F0C900D8A354 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = "HotPocket 27";
|
||||||
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 = 2026082001;
|
||||||
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 +938,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 26.8.20;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
@@ -945,7 +964,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 = 2026082001;
|
||||||
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 +979,7 @@
|
|||||||
"@executable_path/../../../../Frameworks",
|
"@executable_path/../../../../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 26.8.20;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
@@ -980,7 +999,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 = 2026082001;
|
||||||
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 +1014,7 @@
|
|||||||
"@executable_path/../../../../Frameworks",
|
"@executable_path/../../../../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 26.8.20;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
@@ -1012,12 +1031,12 @@
|
|||||||
4CABCB152E56F0C900D8A354 /* Debug */ = {
|
4CABCB152E56F0C900D8A354 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = "HotPocket 27";
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
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 = 2026082001;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -1033,7 +1052,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 26.8.20;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
@@ -1041,7 +1060,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;
|
||||||
@@ -1051,12 +1070,12 @@
|
|||||||
4CABCB162E56F0C900D8A354 /* Release */ = {
|
4CABCB162E56F0C900D8A354 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = "HotPocket 27";
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
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 = 2026082001;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -1072,7 +1091,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 26.8.20;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
SafariServices,
|
SafariServices,
|
||||||
@@ -1206,7 +1225,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 = 2026082001;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -1220,7 +1239,7 @@
|
|||||||
"@executable_path/../../../../Frameworks",
|
"@executable_path/../../../../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 26.8.20;
|
||||||
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 +1255,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 = 2026082001;
|
||||||
DEVELOPMENT_TEAM = 648728X64K;
|
DEVELOPMENT_TEAM = 648728X64K;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -1250,7 +1269,7 @@
|
|||||||
"@executable_path/../../../../Frameworks",
|
"@executable_path/../../../../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
MACOSX_DEPLOYMENT_TARGET = 15.0;
|
||||||
MARKETING_VERSION = 25.10.21;
|
MARKETING_VERSION = 26.8.20;
|
||||||
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;
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 264 KiB |
@@ -10,6 +10,7 @@
|
|||||||
#import "HPAPI.h"
|
#import "HPAPI.h"
|
||||||
#import "HPCredentialsHelper.h"
|
#import "HPCredentialsHelper.h"
|
||||||
#import "HPRPCClient.h"
|
#import "HPRPCClient.h"
|
||||||
|
#import "NSBundle+HotPocketExtensions.h"
|
||||||
#import "NSURL+HotPocketExtensions.h"
|
#import "NSURL+HotPocketExtensions.h"
|
||||||
|
|
||||||
@implementation HPAuthParams
|
@implementation HPAuthParams
|
||||||
@@ -77,18 +78,19 @@
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSDictionary *postAuthenticateURLParams = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"HPAuthFlowPostAuthenticateURLParts"];
|
NSString *expectedScheme = [NSBundle postAuthenticateURLScheme];
|
||||||
if (postAuthenticateURLParams == nil) {
|
NSString *expectedHost = [NSBundle postAuthenticateURLHost];
|
||||||
|
if (expectedScheme == nil || expectedHost == nil) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
|
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
|
||||||
|
|
||||||
if ([urlComponents.scheme isEqualToString:[postAuthenticateURLParams valueForKey:@"scheme"]] == NO) {
|
if ([urlComponents.scheme isEqualToString:expectedScheme] == NO) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([urlComponents.host isEqualToString:[postAuthenticateURLParams valueForKey:@"host"]] == NO) {
|
if ([urlComponents.host isEqualToString:expectedHost] == NO) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,6 +111,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
-(BOOL)handleAuthParams:(HPAuthParams *)authParams {
|
-(BOOL)handleAuthParams:(HPAuthParams *)authParams {
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"AuthFlowDidReceiveAuthParams" object:self];
|
||||||
|
|
||||||
HPRPCClient *rpcClient = [[HPRPCClient alloc] initWithBaseURL:self.baseURL accessToken:nil];
|
HPRPCClient *rpcClient = [[HPRPCClient alloc] initWithBaseURL:self.baseURL accessToken:nil];
|
||||||
|
|
||||||
NSArray *callParams = @[
|
NSArray *callParams = @[
|
||||||
@@ -120,7 +124,7 @@
|
|||||||
method:@"accounts.access_tokens.create"
|
method:@"accounts.access_tokens.create"
|
||||||
params:callParams endopoint:@"/accounts/rpc/"
|
params:callParams endopoint:@"/accounts/rpc/"
|
||||||
completionHandler:^(NSString *callId, HPRPCCallResult *result) {
|
completionHandler:^(NSString *callId, HPRPCCallResult *result) {
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||||
if (result.error != nil) {
|
if (result.error != nil) {
|
||||||
NSLog(@"-[HPAuthFlow handleAuthParams:] error=`%@`", result.error);
|
NSLog(@"-[HPAuthFlow handleAuthParams:] error=`%@`", result.error);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="1024px" height="1024px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 61 (89581) - https://sketch.com -->
|
||||||
|
<title>icon-ios-tinted</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs>
|
||||||
|
<filter x="-1.5%" y="-1.5%" width="103.0%" height="103.0%" filterUnits="objectBoundingBox" id="filter-1">
|
||||||
|
<feOffset dx="0" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||||
|
<feGaussianBlur stdDeviation="2" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||||
|
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode in="shadowMatrixOuter1"></feMergeNode>
|
||||||
|
<feMergeNode in="SourceGraphic"></feMergeNode>
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
<g id="icon-ios-tinted" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="HotPocket-Copy" transform="translate(112.000000, 136.000000)" fill="#1CBAED" fill-rule="nonzero">
|
||||||
|
<g id="Group" filter="url(#filter-1)">
|
||||||
|
<g id="pepper-hot-solid-svgrepo-com" transform="translate(174.000000, 78.000000)">
|
||||||
|
<path d="M452,37.5215494 L452,0 C414.620964,0 385.466785,10.4063766 365.41868,30.779396 C353.815765,42.5781598 347.57369,55.6960499 343.975301,66.9818378 C334.428601,60.3862436 323.339725,56.2823241 311.002439,56.2823241 C263.562643,56.2823241 245.644203,93.9504515 245.203576,119.599939 C245.203576,123.703858 245.056713,128.027635 244.762969,132.497971 C232.131937,169.799663 207.604227,145.102867 207.604227,93.8038736 C147.019342,158.0009 212.304145,181.671725 175.071972,218.826858 C167.140859,226.74156 148.194321,229.81949 136.371093,215.309213 C120.729162,196.768277 152.527064,166.282018 122.4182,143.490622 C127.925922,177.787663 101.415448,170.679075 92.4562182,163.350647 C80.7798529,153.8237 59.5567872,132.864388 94.8061776,75.0430988 C58.748984,91.4587767 37.0118599,124.803127 38.407153,150.086198 C42.1524054,216.408463 144.889696,274.009913 103.398212,312.704011 C82.4688909,332.270918 41.3446022,305.81528 57.2068278,262.650846 C37.4524867,272.690787 14.246638,296.581471 21.6636925,333.736603 C26.804238,359.45937 64.2567059,417.427237 0.807803229,450.258593 C0.807803229,450.258593 1.10154815,450.331873 1.61560646,450.478451 L0,487.780142 C1.24843001,487.853422 6.31552517,488 14.4669514,488 C67.341037,488 250.344122,479.865441 362.995289,372.210844 C422.038018,315.781942 452,241.03198 452,150.086198 C452,124.143573 440.176772,75.0430988 395.600975,75.0430988 C390.093253,75.0430988 384.952727,75.775951 380.105926,76.9484994 C382.235591,70.6460423 385.907393,63.4641926 392.222918,57.0151763 C405.000813,44.1171437 425.048899,37.5215494 452,37.5215494 Z M395.600975,112.564648 C413.372552,112.564648 414.40065,149.793061 414.40065,150.086198 C414.40065,230.332485 388.330784,295.921917 337.072305,345.022372 C253.869061,424.609106 122.785376,444.322571 51.6256743,449.012765 C68.9566246,445.055405 89.8125139,436.994144 112.651186,421.604436 C222.658649,361.43805 280.526398,219.559692 282.656063,125.096264 L282.802926,125.096264 L282.802926,119.966355 C282.876358,115.569299 284.638827,93.8038736 311.002439,93.8038736 C327.084978,93.8038736 339.201951,116.595288 339.201951,131.325423 L376.801301,131.325423 C376.801301,123.264162 378.784083,112.564648 395.600975,112.564648 Z" id="Shape"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.6 KiB |
@@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="1024px" height="1024px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 61 (89581) - https://sketch.com -->
|
||||||
|
<title>icon-ios-tinted</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs>
|
||||||
|
<filter x="-1.5%" y="-1.5%" width="103.0%" height="103.0%" filterUnits="objectBoundingBox" id="filter-1">
|
||||||
|
<feOffset dx="0" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||||
|
<feGaussianBlur stdDeviation="2" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||||
|
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode in="shadowMatrixOuter1"></feMergeNode>
|
||||||
|
<feMergeNode in="SourceGraphic"></feMergeNode>
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
<g id="icon-ios-tinted" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="HotPocket-Copy" transform="translate(112.000000, 136.000000)" fill="#0082DD" fill-rule="nonzero">
|
||||||
|
<g id="Group" filter="url(#filter-1)">
|
||||||
|
<g id="patch-fashion-svgrepo-com">
|
||||||
|
<path d="M786.667187,0 L13.3328125,0 C5.3328125,0 0,5.3328125 0,13.3328125 L0,573.332813 C0,578.665625 2.6671875,582.665625 6.6671875,585.332813 L393.334375,798.665625 C396,800 397.332812,800 400,800 C402.667187,800 404,800 406.667187,798.667187 L793.334375,585.334375 C797.334375,582.667188 800.001562,578.667188 800.001562,573.334375 L800.001562,13.3328125 C800.001562,5.3328125 794.667187,0 786.667187,0 Z M773.334375,565.332812 L400,770.667187 L26.6671875,565.332812 L26.6671875,26.6671875 L773.334375,26.6671875 L773.334375,565.332812 L773.334375,565.332812 Z" id="Shape"></path>
|
||||||
|
<path d="M86.6671875,537.332812 L138.667188,566.665625 C141.334375,567.998437 142.667188,567.998437 145.334375,567.998437 C150.667188,567.998437 154.667188,565.33125 157.334375,562.665625 C161.334375,555.998437 158.667187,547.998437 152.001562,543.998437 L106.66875,518.665625 L106.66875,466.665625 C106.66875,458.665625 101.335937,453.332812 93.3359375,453.332812 C85.3359375,453.332812 80.0031223,458.665625 80.0031223,466.665625 L80.0031223,526.665625 C80,530.667187 82.6671875,536 86.6671875,537.332812 Z" id="Path"></path>
|
||||||
|
<path d="M93.3328125,390.667187 C101.332813,390.667187 106.665625,384 106.665625,377.334375 L106.665625,242.667187 C106.665625,234.667187 101.332813,229.334375 93.3328125,229.334375 C85.3328125,229.334375 80,234.667188 80,242.667187 L80,377.334375 C80,385.332812 85.3328125,390.667187 93.3328125,390.667187 Z" id="Path"></path>
|
||||||
|
<path d="M93.3328125,166.667188 C101.332813,166.667188 106.665625,161.334375 106.665625,153.334375 L106.665625,106.667188 L153.332812,106.667188 C161.332813,106.667188 166.665625,101.334375 166.665625,93.334375 C166.665625,85.334375 161.332813,80.0015625 153.332812,80.0015625 L93.3328125,80.0015625 C85.3328125,80.0015625 80,85.334375 80,93.334375 L80,153.334375 C80,161.332813 85.3328125,166.667188 93.3328125,166.667188 Z" id="Path"></path>
|
||||||
|
<path d="M236,106.667188 L358.667188,106.667188 C366.667188,106.667188 372,101.334375 372,93.334375 C372,85.334375 366.667188,80.0015625 358.667188,80.0015625 L236,80.0015625 C228,80.0015625 222.667188,85.334375 222.667188,93.334375 C222.667188,101.334375 228,106.667188 236,106.667188 Z" id="Path"></path>
|
||||||
|
<path d="M441.332812,106.667187 L564,106.667187 C572,106.667187 577.332812,101.334375 577.332812,93.334375 C577.332812,85.334375 572,80 564,80 L441.332812,80 C433.332812,80 428,85.3328125 428,93.3328125 C428,101.332813 433.332812,106.667187 441.332812,106.667187 Z" id="Path"></path>
|
||||||
|
<path d="M646.667188,106.667187 L693.334375,106.667187 L693.334375,153.334375 C693.334375,161.334375 698.667188,166.667188 706.667188,166.667188 C714.667188,166.667188 720,161.334375 720,153.334375 L720,93.334375 C720,85.334375 714.667188,80.0015625 706.667188,80.0015625 L646.667188,80.0015625 C638.667188,80.0015625 633.334375,85.334375 633.334375,93.334375 C633.334375,101.334375 638.667188,106.667187 646.667188,106.667187 Z" id="Path"></path>
|
||||||
|
<path d="M706.667188,229.332812 C698.667188,229.332812 693.334375,234.665625 693.334375,242.665625 L693.334375,377.332812 C693.334375,385.332812 698.667188,390.665625 706.667188,390.665625 C714.667188,390.665625 720,383.998437 720,377.332812 L720,242.665625 C720,234.667188 714.667188,229.332812 706.667188,229.332812 Z" id="Path"></path>
|
||||||
|
<path d="M706.667187,453.332812 C698.667187,453.332812 693.334375,458.665625 693.334375,466.665625 L693.334375,517.332813 L648.001562,542.665625 C641.334375,546.665625 638.66875,554.665625 642.66875,561.332813 C645.335938,565.332813 649.335938,568 654.66875,568 C656.001562,568 658.66875,568 661.335938,568 L713.335937,538.667188 C717.335937,536 720.003125,532 720.003125,526.667188 L720.003125,466.667188 C720,458.667188 714.667187,453.332812 706.667187,453.332812 Z" id="Path"></path>
|
||||||
|
<path d="M498.667187,641.332812 C501.334375,645.332812 505.334375,648 510.667187,648 C512,648 514.667187,646.667187 517.334375,646.667187 L604.001562,598.667187 C610.66875,594.667187 613.334375,586.667187 609.334375,580 C605.334375,573.332812 597.334375,570.667187 590.667187,574.667187 L504,622.667187 C497.332812,626.667187 494.667187,634.667187 498.667187,641.332812 Z" id="Path"></path>
|
||||||
|
<path d="M336,658.667188 C332,665.334375 334.667188,673.334375 341.332813,677.334375 L393.332813,706.667188 C396,708 397.332813,708 400,708 C402.667188,708 404,708 406.667188,706.667188 L460,678.667188 C466.667188,674.667188 469.332813,666.667188 465.332813,660 C461.332813,653.332813 453.332813,650.667188 446.665625,654.667188 L400,680 L354.667188,653.332813 C348,649.332813 340,652 336,658.667188 Z" id="Path"></path>
|
||||||
|
<path d="M196,598.667187 L282.667187,646.667187 C285.334375,648 286.667187,648 289.334375,648 C294.667187,648 298.667187,645.332813 301.334375,641.332813 C305.334375,634.665625 302.667187,626.665625 296.001562,622.665625 L209.334375,574.665625 C202.667187,570.665625 194.667187,573.332812 190.667187,579.998437 C186.667187,586.664062 189.332812,594.667187 196,598.667187 Z" id="Path"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 6.4 KiB |
98
services/apple/Shared (App)/HotPocket 27.icon/icon.json
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
{
|
||||||
|
"fill-specializations" : [
|
||||||
|
{
|
||||||
|
"value" : {
|
||||||
|
"linear-gradient" : [
|
||||||
|
"display-p3:0.30588,0.37647,0.40784,1.00000",
|
||||||
|
"srgb:0.19608,0.27451,0.31373,1.00000"
|
||||||
|
],
|
||||||
|
"orientation" : {
|
||||||
|
"start" : {
|
||||||
|
"x" : 0.5,
|
||||||
|
"y" : 0
|
||||||
|
},
|
||||||
|
"stop" : {
|
||||||
|
"x" : 0.5,
|
||||||
|
"y" : 0.7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearance" : "dark",
|
||||||
|
"value" : {
|
||||||
|
"linear-gradient" : [
|
||||||
|
"display-p3:0.18824,0.18824,0.18824,1.00000",
|
||||||
|
"srgb:0.07451,0.07451,0.07451,1.00000"
|
||||||
|
],
|
||||||
|
"orientation" : {
|
||||||
|
"start" : {
|
||||||
|
"x" : 0.5,
|
||||||
|
"y" : 0
|
||||||
|
},
|
||||||
|
"stop" : {
|
||||||
|
"x" : 0.5,
|
||||||
|
"y" : 0.7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"groups" : [
|
||||||
|
{
|
||||||
|
"layers" : [
|
||||||
|
{
|
||||||
|
"image-name" : "pepper 2.svg",
|
||||||
|
"name" : "pepper 2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lighting" : "individual",
|
||||||
|
"shadow" : {
|
||||||
|
"kind" : "none",
|
||||||
|
"opacity" : 0.5
|
||||||
|
},
|
||||||
|
"specular" : true,
|
||||||
|
"translucency" : {
|
||||||
|
"enabled" : true,
|
||||||
|
"value" : 0.5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"layers" : [
|
||||||
|
{
|
||||||
|
"glass-specializations" : [
|
||||||
|
{
|
||||||
|
"value" : false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearance" : "dark",
|
||||||
|
"value" : false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"image-name" : "pocket 2.svg",
|
||||||
|
"name" : "pocket 2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"shadow" : {
|
||||||
|
"kind" : "layer-color",
|
||||||
|
"opacity" : 0.25
|
||||||
|
},
|
||||||
|
"specular-specializations" : [
|
||||||
|
{
|
||||||
|
"value" : false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearance" : "dark",
|
||||||
|
"value" : false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"translucency" : {
|
||||||
|
"enabled" : true,
|
||||||
|
"value" : 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"supported-platforms" : {
|
||||||
|
"squares" : "shared"
|
||||||
|
}
|
||||||
|
}
|
||||||
21
services/apple/Shared (App)/NSBundle+HotPocketExtensions.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// 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;
|
||||||
|
+(NSDictionary *)postAuthenticateURLParams;
|
||||||
|
+(NSString *)postAuthenticateURLScheme;
|
||||||
|
+(NSString *)postAuthenticateURLHost;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
36
services/apple/Shared (App)/NSBundle+HotPocketExtensions.m
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// 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"]];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSDictionary *)postAuthenticateURLParams {
|
||||||
|
NSDictionary *result = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"HPAuthFlowPostAuthenticateURLParts"];
|
||||||
|
if (result == nil) {
|
||||||
|
return [NSDictionary dictionary];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSString *)postAuthenticateURLScheme {
|
||||||
|
NSDictionary *params = [self postAuthenticateURLParams];
|
||||||
|
return [params valueForKey:@"scheme"];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSString *)postAuthenticateURLHost {
|
||||||
|
NSDictionary *params = [self postAuthenticateURLParams];
|
||||||
|
return [params valueForKey:@"host"];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
BIN
services/apple/Shared (App)/Resources/icon-glass-512.png
Normal file
|
After Width: | Height: | Size: 263 KiB |
|
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 {
|
||||||
|
|||||||
@@ -6,12 +6,19 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <AuthenticationServices/AuthenticationServices.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@interface AuthorizationProgressViewController : UIViewController
|
@class MultilineLabel;
|
||||||
|
|
||||||
|
@interface AuthorizationProgressViewController : UIViewController<ASWebAuthenticationPresentationContextProviding>
|
||||||
|
|
||||||
@property IBOutlet UIActivityIndicatorView *progressIndicator;
|
@property IBOutlet UIActivityIndicatorView *progressIndicator;
|
||||||
|
@property IBOutlet MultilineLabel *progressLabel;
|
||||||
|
@property (strong, nullable) NSURL *authorizationURL;
|
||||||
|
@property (strong, nullable) ASWebAuthenticationSession *webAuthenticationSession;
|
||||||
|
@property BOOL userCancelledSession;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|||||||
@@ -8,20 +8,36 @@
|
|||||||
#import "AuthorizationProgressViewController.h"
|
#import "AuthorizationProgressViewController.h"
|
||||||
|
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
|
#import "HPAuthFlow.h"
|
||||||
#import "HPCredentialsHelper.h"
|
#import "HPCredentialsHelper.h"
|
||||||
|
#import "MultilineLabel.h"
|
||||||
|
#import "NSBundle+HotPocketExtensions.h"
|
||||||
|
|
||||||
@interface AuthorizationProgressViewController (AuthorizationProgressViewControllerPrivate)
|
@interface AuthorizationProgressViewController (AuthorizationProgressViewControllerPrivate)
|
||||||
|
|
||||||
#pragma mark - Private interface
|
#pragma mark - Private interface
|
||||||
|
|
||||||
|
-(void)presentAuthorizationError;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation AuthorizationProgressViewController
|
@implementation AuthorizationProgressViewController
|
||||||
|
|
||||||
#pragma mark - View lifecycle
|
#pragma mark - View lifecycle
|
||||||
|
|
||||||
|
-(instancetype)initWithCoder:(NSCoder *)coder {
|
||||||
|
if (self = [super initWithCoder:coder]) {
|
||||||
|
self.authorizationURL = nil;
|
||||||
|
self.webAuthenticationSession = nil;
|
||||||
|
self.userCancelledSession = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
-(void)viewDidLoad {
|
-(void)viewDidLoad {
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
|
self.progressLabel.text = NSLocalizedString(@"Continue to sign in in your browser...", @"Continue to sign in in your browser...");
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)viewWillAppear:(BOOL)animated {
|
-(void)viewWillAppear:(BOOL)animated {
|
||||||
@@ -29,29 +45,74 @@
|
|||||||
[self.progressIndicator startAnimating];
|
[self.progressIndicator startAnimating];
|
||||||
|
|
||||||
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
|
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAuthFlowDidFinish:) name:@"AuthFlowDidFinish" object:appDelegate.authFlow];
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
|
selector:@selector(onAuthFlowDidFinish:)
|
||||||
|
name:@"AuthFlowDidFinish"
|
||||||
|
object:appDelegate.authFlow];
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
|
selector:@selector(onAuthFlowDidReceiveAuthParams:)
|
||||||
|
name:@"AuthFlowDidReceiveAuthParams"
|
||||||
|
object:appDelegate.authFlow];
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)viewWillDisappear:(BOOL)animated {
|
-(void)viewDidAppear:(BOOL)animated {
|
||||||
[super viewWillDisappear:animated];
|
[super viewDidAppear:animated];
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
|
||||||
|
|
||||||
|
ASWebAuthenticationSessionCompletionHandler completionHandler = ^(NSURL *url, NSError *error) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
if (error != nil) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
NSLog(@"[AuthorizationViewController.session completionHandler] error=`%@`", error);
|
||||||
|
#endif
|
||||||
|
if (error.code == ASWebAuthenticationSessionErrorCodeCanceledLogin) {
|
||||||
|
self.userCancelledSession = YES;
|
||||||
|
}
|
||||||
|
[self presentAuthorizationError];
|
||||||
|
} else {
|
||||||
|
HPAuthParams *receivedAuthParams = [appDelegate.authFlow handlePostAuthenticateURL:url];
|
||||||
|
if (receivedAuthParams != nil) {
|
||||||
|
[appDelegate.authFlow handleAuthParams:receivedAuthParams];
|
||||||
|
} else {
|
||||||
|
[self presentAuthorizationError];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.webAuthenticationSession = nil;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
ASWebAuthenticationSessionCallback *callback = [ASWebAuthenticationSessionCallback callbackWithCustomScheme:[NSBundle postAuthenticateURLScheme]];
|
||||||
|
self.webAuthenticationSession = [[ASWebAuthenticationSession alloc] initWithURL:self.authorizationURL
|
||||||
|
callback:callback
|
||||||
|
completionHandler:completionHandler];
|
||||||
|
self.webAuthenticationSession.presentationContextProvider = self;
|
||||||
|
#ifdef DEBUG
|
||||||
|
self.webAuthenticationSession.prefersEphemeralWebBrowserSession = YES;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (self.webAuthenticationSession.canStart == NO) {
|
||||||
|
[self presentAuthorizationError];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[self.webAuthenticationSession start];
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)viewDidDisappear:(BOOL)animated {
|
-(void)viewDidDisappear:(BOOL)animated {
|
||||||
[super viewDidDisappear:animated];
|
[super viewDidDisappear:animated];
|
||||||
|
self.webAuthenticationSession = nil;
|
||||||
|
|
||||||
[self.progressIndicator stopAnimating];
|
[self.progressIndicator stopAnimating];
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Notification handlers
|
# pragma mark - Private interface
|
||||||
|
|
||||||
-(void)onAuthFlowDidFinish:(NSNotification *)notification {
|
-(void)presentAuthorizationError {
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
if (self.userCancelledSession == NO) {
|
||||||
#ifdef DEBUG
|
|
||||||
NSLog(@"-[AuthorizationViewController onAuthFlowDidFinish:] notification=`%@`", notification);
|
|
||||||
#endif
|
|
||||||
HPCredentials *credentials = [[HPCredentialsHelper sharedHelper] getCredentials];
|
|
||||||
|
|
||||||
if (credentials.usable == NO) {
|
|
||||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Oops!", @"Oops!")
|
UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Oops!", @"Oops!")
|
||||||
message:NSLocalizedString(@"HotPocket couldn't complete this operation.", @"HotPocket couldn't complete this operation.")
|
message:NSLocalizedString(@"HotPocket couldn't complete this operation.", @"HotPocket couldn't complete this operation.")
|
||||||
preferredStyle:UIAlertControllerStyleAlert];
|
preferredStyle:UIAlertControllerStyleAlert];
|
||||||
@@ -65,10 +126,36 @@
|
|||||||
}]];
|
}]];
|
||||||
|
|
||||||
[self presentViewController:alert animated:YES completion:nil];
|
[self presentViewController:alert animated:YES completion:nil];
|
||||||
|
} else {
|
||||||
|
[self.navigationController popViewControllerAnimated:YES];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Notification handlers
|
||||||
|
|
||||||
|
-(void)onAuthFlowDidFinish:(NSNotification *)notification {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
#ifdef DEBUG
|
||||||
|
NSLog(@"-[AuthorizationViewController onAuthFlowDidFinish:] notification=`%@`", notification);
|
||||||
|
#endif
|
||||||
|
HPCredentials *credentials = [[HPCredentialsHelper sharedHelper] getCredentials];
|
||||||
|
|
||||||
|
if (credentials.usable == NO) {
|
||||||
|
[self presentAuthorizationError];
|
||||||
} else {
|
} else {
|
||||||
[self.navigationController popToRootViewControllerAnimated:YES];
|
[self.navigationController popToRootViewControllerAnimated:YES];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-(void)onAuthFlowDidReceiveAuthParams:(NSNotification *)notification {
|
||||||
|
self.progressLabel.text = NSLocalizedString(@"Processing authorization...", @"Processing authorization...");
|
||||||
|
}
|
||||||
|
|
||||||
|
# pragma mark - ASWebAuthenticationPresentationContextProviding implementation
|
||||||
|
|
||||||
|
-(ASPresentationAnchor)presentationAnchorForWebAuthenticationSession:(ASWebAuthenticationSession *)session {
|
||||||
|
return self.view.window;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -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 {
|
||||||
@@ -69,15 +73,10 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([application canOpenURL:authURL] == YES) {
|
|
||||||
[application openURL:authURL options:@{} completionHandler:^(BOOL result) {
|
|
||||||
if (result == YES) {
|
|
||||||
AuthorizationProgressViewController *authorizationProgressViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"AuthorizationProgressViewController"];
|
AuthorizationProgressViewController *authorizationProgressViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"AuthorizationProgressViewController"];
|
||||||
|
authorizationProgressViewController.authorizationURL = authURL;
|
||||||
[self.navigationController pushViewController:authorizationProgressViewController animated:YES];
|
[self.navigationController pushViewController:authorizationProgressViewController animated:YES];
|
||||||
}
|
}
|
||||||
}];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Event handlers
|
#pragma mark - Event handlers
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="24127" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="24506" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||||
<device id="retina6_12" orientation="portrait" appearance="light"/>
|
<device id="retina6_12" orientation="portrait" appearance="light"/>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24063"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24504"/>
|
||||||
<capability name="Image references" minToolsVersion="12.0"/>
|
<capability name="Image references" minToolsVersion="12.0"/>
|
||||||
<capability name="Named colors" minToolsVersion="9.0"/>
|
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6HG-Um-bch">
|
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6HG-Um-bch">
|
||||||
<rect key="frame" x="116" y="0.0" width="128" height="128"/>
|
<rect key="frame" x="116" y="0.0" width="128" height="128"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<imageReference key="image" image="icon-mac-384.png"/>
|
<imageReference key="image" image="icon-glass-512.png"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="HotPocket by BTHLabs" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="v6f-dw-6WO">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="HotPocket by BTHLabs" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="v6f-dw-6WO">
|
||||||
<rect key="frame" x="0.0" y="136" width="361" height="29"/>
|
<rect key="frame" x="0.0" y="136" width="361" height="29"/>
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
</scene>
|
</scene>
|
||||||
</scenes>
|
</scenes>
|
||||||
<resources>
|
<resources>
|
||||||
<image name="icon-mac-384.png" width="384" height="384"/>
|
<image name="icon-glass-512.png" width="630" height="630"/>
|
||||||
<namedColor name="BackgroundColor">
|
<namedColor name="BackgroundColor">
|
||||||
<color red="0.12941176470588237" green="0.14509803921568629" blue="0.16078431372549021" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color red="0.12941176470588237" green="0.14509803921568629" blue="0.16078431372549021" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</namedColor>
|
</namedColor>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="24127" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="7Sa-RR-xgc">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="24506" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="7Sa-RR-xgc">
|
||||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24063"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24504"/>
|
||||||
<capability name="Image references" minToolsVersion="12.0"/>
|
<capability name="Image references" minToolsVersion="12.0"/>
|
||||||
<capability name="Named colors" minToolsVersion="9.0"/>
|
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
@@ -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"/>
|
||||||
@@ -213,8 +229,8 @@
|
|||||||
<rect key="frame" x="189" y="306" width="37" height="37"/>
|
<rect key="frame" x="189" y="306" width="37" height="37"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
</activityIndicatorView>
|
</activityIndicatorView>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Awaiting authentication response..." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qiJ-yx-nMd">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Awaiting authentication response..." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qiJ-yx-nMd" customClass="MultilineLabel">
|
||||||
<rect key="frame" x="20" y="359" width="374" height="21"/>
|
<rect key="frame" x="20" y="359" 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"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
@@ -226,6 +242,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="progressIndicator" destination="DNy-gf-n60" id="hJF-jc-ZJ0"/>
|
<outlet property="progressIndicator" destination="DNy-gf-n60" id="hJF-jc-ZJ0"/>
|
||||||
|
<outlet property="progressLabel" destination="qiJ-yx-nMd" id="1Wu-em-XsK"/>
|
||||||
</connections>
|
</connections>
|
||||||
</viewController>
|
</viewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="N3D-cM-5Ro" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="N3D-cM-5Ro" 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
@@ -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
@@ -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[]) {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="24127" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="j1y-V4-xli">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="24506" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="j1y-V4-xli">
|
||||||
<device id="retina6_12" orientation="portrait" appearance="light"/>
|
<device id="retina6_12" orientation="portrait" appearance="light"/>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24063"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24504"/>
|
||||||
<capability name="Image references" minToolsVersion="12.0"/>
|
<capability name="Image references" minToolsVersion="12.0"/>
|
||||||
<capability name="Named colors" minToolsVersion="9.0"/>
|
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
@@ -44,8 +44,8 @@
|
|||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
</activityIndicatorView>
|
</activityIndicatorView>
|
||||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="CqC-1V-R49">
|
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="CqC-1V-R49">
|
||||||
<rect key="frame" x="138" y="107" width="77" height="35"/>
|
<rect key="frame" x="130" y="107" width="92" height="35"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<state key="normal" title="Button"/>
|
<state key="normal" title="Button"/>
|
||||||
<buttonConfiguration key="configuration" style="gray" title="Cancel">
|
<buttonConfiguration key="configuration" style="gray" title="Cancel">
|
||||||
<color key="baseForegroundColor" name="DangerColor"/>
|
<color key="baseForegroundColor" name="DangerColor"/>
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
</subviews>
|
</subviews>
|
||||||
</view>
|
</view>
|
||||||
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9Dr-s7-Kqv" userLabel="Done View">
|
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9Dr-s7-Kqv" userLabel="Done View">
|
||||||
<rect key="frame" x="20" y="299" width="353" height="142"/>
|
<rect key="frame" x="20" y="299" width="353" height="193"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="checkmark.circle.fill" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="0oo-rV-Vfd">
|
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="checkmark.circle.fill" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="0oo-rV-Vfd">
|
||||||
@@ -73,9 +73,9 @@
|
|||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="AHS-eb-Mk8">
|
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="AHS-eb-Mk8">
|
||||||
<rect key="frame" x="143" y="107" width="67" height="35"/>
|
<rect key="frame" x="132" y="107" width="88" height="35"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<color key="tintColor" name="AccentColor"/>
|
<color key="tintColor" name="SecondaryColor"/>
|
||||||
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
||||||
<state key="normal" title="Close"/>
|
<state key="normal" title="Close"/>
|
||||||
<buttonConfiguration key="configuration" style="tinted" title="Close"/>
|
<buttonConfiguration key="configuration" style="tinted" title="Close"/>
|
||||||
@@ -102,9 +102,9 @@
|
|||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="gFP-1G-Hef">
|
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="gFP-1G-Hef">
|
||||||
<rect key="frame" x="143" y="107" width="67" height="35"/>
|
<rect key="frame" x="130" y="107" width="92" height="35"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<color key="tintColor" name="AccentColor"/>
|
<color key="tintColor" name="SecondaryColor"/>
|
||||||
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
||||||
<state key="normal" title="Close"/>
|
<state key="normal" title="Close"/>
|
||||||
<buttonConfiguration key="configuration" style="tinted" title="Close"/>
|
<buttonConfiguration key="configuration" style="tinted" title="Close"/>
|
||||||
@@ -131,9 +131,9 @@
|
|||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="UJs-K5-SJe">
|
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="UJs-K5-SJe">
|
||||||
<rect key="frame" x="143" y="107" width="67" height="35"/>
|
<rect key="frame" x="130" y="107" width="92" height="35"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<color key="tintColor" name="AccentColor"/>
|
<color key="tintColor" name="SecondaryColor"/>
|
||||||
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
||||||
<state key="normal" title="Close"/>
|
<state key="normal" title="Close"/>
|
||||||
<buttonConfiguration key="configuration" style="tinted" title="Close"/>
|
<buttonConfiguration key="configuration" style="tinted" title="Close"/>
|
||||||
@@ -161,8 +161,8 @@
|
|||||||
</label>
|
</label>
|
||||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0WL-Hk-6Bk">
|
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0WL-Hk-6Bk">
|
||||||
<rect key="frame" x="143" y="107" width="67" height="35"/>
|
<rect key="frame" x="143" y="107" width="67" height="35"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<color key="tintColor" name="AccentColor"/>
|
<color key="tintColor" name="SecondaryColor"/>
|
||||||
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
||||||
<state key="normal" title="Close"/>
|
<state key="normal" title="Close"/>
|
||||||
<buttonConfiguration key="configuration" style="tinted" title="Close"/>
|
<buttonConfiguration key="configuration" style="tinted" title="Close"/>
|
||||||
@@ -189,6 +189,7 @@
|
|||||||
<outlet property="errorView" destination="DLn-U6-UcA" id="cl1-I0-nY1"/>
|
<outlet property="errorView" destination="DLn-U6-UcA" id="cl1-I0-nY1"/>
|
||||||
<outlet property="needsSetupView" destination="eqK-cv-2mf" id="Vb3-Y3-8Y8"/>
|
<outlet property="needsSetupView" destination="eqK-cv-2mf" id="Vb3-Y3-8Y8"/>
|
||||||
<outlet property="progressIndicator" destination="1HO-hL-WcQ" id="1Qd-Gt-b3G"/>
|
<outlet property="progressIndicator" destination="1HO-hL-WcQ" id="1Qd-Gt-b3G"/>
|
||||||
|
<outlet property="savedLabel" destination="QoY-OC-nmX" id="cqW-iq-7CR"/>
|
||||||
<outlet property="savingView" destination="zdu-vr-R6t" id="svY-bA-Z9d"/>
|
<outlet property="savingView" destination="zdu-vr-R6t" id="svY-bA-Z9d"/>
|
||||||
<outlet property="unameLabel" destination="xfn-uj-KNk" id="TTp-PV-ttr"/>
|
<outlet property="unameLabel" destination="xfn-uj-KNk" id="TTp-PV-ttr"/>
|
||||||
<outlet property="unprocessableEntityView" destination="ckY-6z-0fe" id="owN-qJ-oBj"/>
|
<outlet property="unprocessableEntityView" destination="ckY-6z-0fe" id="owN-qJ-oBj"/>
|
||||||
@@ -204,14 +205,14 @@
|
|||||||
<image name="exclamationmark.circle.fill" catalog="system" width="128" height="123"/>
|
<image name="exclamationmark.circle.fill" catalog="system" width="128" height="123"/>
|
||||||
<image name="icon-mac-384.png" width="384" height="384"/>
|
<image name="icon-mac-384.png" width="384" height="384"/>
|
||||||
<image name="multiply.circle.fill" catalog="system" width="128" height="123"/>
|
<image name="multiply.circle.fill" catalog="system" width="128" height="123"/>
|
||||||
<namedColor name="AccentColor">
|
|
||||||
<color red="0.10980392156862745" green="0.72941176470588232" blue="0.92941176470588238" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
</namedColor>
|
|
||||||
<namedColor name="BackgroundColor">
|
<namedColor name="BackgroundColor">
|
||||||
<color red="0.12941176470588237" green="0.14509803921568629" blue="0.16078431372549021" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color red="0.12941176470588237" green="0.14509803921568629" blue="0.16078431372549021" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</namedColor>
|
</namedColor>
|
||||||
<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 name="SecondaryColor">
|
||||||
|
<color red="0.0" green="0.50980392156862742" blue="0.8666666666666667" 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"/>
|
||||||
|
|||||||
@@ -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,8 @@
|
|||||||
@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;
|
||||||
|
@property IBOutlet UILabel *savedLabel;
|
||||||
|
|
||||||
-(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)
|
||||||
|
|
||||||
@@ -31,6 +33,21 @@
|
|||||||
#endif
|
#endif
|
||||||
self.errorView.hidden = NO;
|
self.errorView.hidden = NO;
|
||||||
} else {
|
} else {
|
||||||
|
self.savedLabel.text = NSLocalizedString(
|
||||||
|
@"Your link has been saved!",
|
||||||
|
@"Your link has been saved!"
|
||||||
|
);
|
||||||
|
|
||||||
|
NSDictionary *save = result.result;
|
||||||
|
|
||||||
|
BOOL isNetlocBanned = [(NSNumber *)[save valueForKey:@"is_netloc_banned"] boolValue];
|
||||||
|
if (isNetlocBanned == YES) {
|
||||||
|
self.savedLabel.text = NSLocalizedString(
|
||||||
|
@"Your link has been saved, but you may want to update its title.",
|
||||||
|
@"Your link has been saved, but you may want to update its title."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
self.doneView.hidden = NO;
|
self.doneView.hidden = NO;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -68,8 +85,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) {
|
||||||
|
|||||||
@@ -21,18 +21,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
-(void)application:(NSApplication *)application openURLs:(NSArray<NSURL *> *)urls {
|
-(void)application:(NSApplication *)application openURLs:(NSArray<NSURL *> *)urls {
|
||||||
HPAuthParams *receivedAuthParams = nil;
|
|
||||||
for (NSURL *url in urls) {
|
|
||||||
receivedAuthParams = [self.authFlow handlePostAuthenticateURL:url];
|
|
||||||
|
|
||||||
if (receivedAuthParams != nil) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (receivedAuthParams != nil) {
|
|
||||||
[self.authFlow handleAuthParams:receivedAuthParams];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -6,12 +6,19 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import <AuthenticationServices/AuthenticationServices.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@interface AuthorizationProgressViewController : NSViewController
|
@interface AuthorizationProgressViewController : NSViewController<ASWebAuthenticationPresentationContextProviding>
|
||||||
|
|
||||||
@property IBOutlet NSProgressIndicator *progressIndicator;
|
@property IBOutlet NSProgressIndicator *progressIndicator;
|
||||||
|
@property NSString *progressLabelTitle;
|
||||||
|
@property (nullable, strong) NSURL *authorizationURL;
|
||||||
|
@property (nullable, strong) ASWebAuthenticationSession *webAuthenticationSession;
|
||||||
|
@property BOOL userCancelledSession;
|
||||||
|
|
||||||
|
-(IBAction)doCancel:(id)sender;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|||||||
@@ -9,37 +9,133 @@
|
|||||||
|
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
#import "AuthorizationViewController.h"
|
#import "AuthorizationViewController.h"
|
||||||
|
#import "HPAuthFlow.h"
|
||||||
#import "HPCredentialsHelper.h"
|
#import "HPCredentialsHelper.h"
|
||||||
#import "MainViewController.h"
|
#import "MainViewController.h"
|
||||||
|
#import "NSBundle+HotPocketExtensions.h"
|
||||||
#import "ReplaceAnimator.h"
|
#import "ReplaceAnimator.h"
|
||||||
|
|
||||||
@interface AuthorizationProgressViewController (AuthorizationProgressViewControllerPrivate)
|
@interface AuthorizationProgressViewController (AuthorizationProgressViewControllerPrivate)
|
||||||
|
|
||||||
#pragma mark - Private interface
|
#pragma mark - Private interface
|
||||||
|
|
||||||
|
-(void)presentAuthorizationError;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation AuthorizationProgressViewController
|
@implementation AuthorizationProgressViewController
|
||||||
|
|
||||||
#pragma mark - View lifecycle
|
#pragma mark - View lifecycle
|
||||||
|
|
||||||
|
-(instancetype)initWithCoder:(NSCoder *)coder {
|
||||||
|
if (self = [super initWithCoder:coder]) {
|
||||||
|
self.authorizationURL = nil;
|
||||||
|
self.webAuthenticationSession = nil;
|
||||||
|
self.userCancelledSession = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
-(void)viewDidLoad {
|
-(void)viewDidLoad {
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
|
self.progressLabelTitle = NSLocalizedString(@"Continue to sign in in your browser...", @"Continue to sign in in your browser...");
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)viewWillAppear {
|
-(void)viewWillAppear {
|
||||||
AppDelegate *appDelegate = [[NSApplication sharedApplication] delegate];
|
AppDelegate *appDelegate = [[NSApplication sharedApplication] delegate];
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAuthFlowDidFinish:) name:@"AuthFlowDidFinish" object:appDelegate.authFlow];
|
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
|
selector:@selector(onAuthFlowDidFinish:)
|
||||||
|
name:@"AuthFlowDidFinish"
|
||||||
|
object:appDelegate.authFlow];
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
|
selector:@selector(onAuthFlowDidReceiveAuthParams:)
|
||||||
|
name:@"AuthFlowDidReceiveAuthParams"
|
||||||
|
object:appDelegate.authFlow];
|
||||||
|
|
||||||
[self.progressIndicator startAnimation:self];
|
[self.progressIndicator startAnimation:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-(void)viewDidAppear {
|
||||||
|
[super viewDidAppear];
|
||||||
|
AppDelegate *appDelegate = [[NSApplication sharedApplication] delegate];
|
||||||
|
|
||||||
|
ASWebAuthenticationSessionCompletionHandler completionHandler = ^(NSURL *url, NSError *error) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
if (error != nil) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
NSLog(@"[AuthorizationViewController.session completionHandler] error=`%@`", error);
|
||||||
|
#endif
|
||||||
|
if (error.code == ASWebAuthenticationSessionErrorCodeCanceledLogin) {
|
||||||
|
self.userCancelledSession = YES;
|
||||||
|
}
|
||||||
|
[self presentAuthorizationError];
|
||||||
|
} else {
|
||||||
|
HPAuthParams *receivedAuthParams = [appDelegate.authFlow handlePostAuthenticateURL:url];
|
||||||
|
if (receivedAuthParams != nil) {
|
||||||
|
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
|
||||||
|
[appDelegate.authFlow handleAuthParams:receivedAuthParams];
|
||||||
|
} else {
|
||||||
|
[self presentAuthorizationError];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.webAuthenticationSession = nil;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
ASWebAuthenticationSessionCallback *callback = [ASWebAuthenticationSessionCallback callbackWithCustomScheme:[NSBundle postAuthenticateURLScheme]];
|
||||||
|
self.webAuthenticationSession = [[ASWebAuthenticationSession alloc] initWithURL:self.authorizationURL
|
||||||
|
callback:callback
|
||||||
|
completionHandler:completionHandler];
|
||||||
|
self.webAuthenticationSession.presentationContextProvider = self;
|
||||||
|
#ifdef DEBUG
|
||||||
|
self.webAuthenticationSession.prefersEphemeralWebBrowserSession = YES;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (self.webAuthenticationSession.canStart == NO) {
|
||||||
|
[self presentAuthorizationError];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[self.webAuthenticationSession start];
|
||||||
|
}
|
||||||
|
|
||||||
-(void)viewDidDisappear {
|
-(void)viewDidDisappear {
|
||||||
|
[super viewDidDisappear];
|
||||||
|
self.webAuthenticationSession = nil;
|
||||||
|
|
||||||
[self.progressIndicator stopAnimation:self];
|
[self.progressIndicator stopAnimation:self];
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - Actions
|
||||||
|
|
||||||
|
-(IBAction)doCancel:(id)sender {
|
||||||
|
[self.webAuthenticationSession cancel];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Private interface
|
||||||
|
|
||||||
|
-(void)presentAuthorizationError {
|
||||||
|
if (self.userCancelledSession == NO) {
|
||||||
|
NSAlert *alert = [[NSAlert alloc] init];
|
||||||
|
alert.alertStyle = NSAlertStyleCritical;
|
||||||
|
alert.messageText = NSLocalizedString(@"Oops!", @"Oops!");
|
||||||
|
alert.informativeText = NSLocalizedString(@"HotPocket couldn't complete this operation.", @"HotPocket couldn't complete this operation.");
|
||||||
|
[alert beginSheetModalForWindow:self.view.window completionHandler:^(NSModalResponse response) {
|
||||||
|
AuthorizationViewController *authorizationViewController = [self.storyboard instantiateControllerWithIdentifier:@"AuthorizationViewController"];
|
||||||
|
[self presentViewController:authorizationViewController animator:[[ReplaceAnimator alloc] init]];
|
||||||
|
}];
|
||||||
|
} else {
|
||||||
|
AuthorizationViewController *authorizationViewController = [self.storyboard instantiateControllerWithIdentifier:@"AuthorizationViewController"];
|
||||||
|
[self presentViewController:authorizationViewController animator:[[ReplaceAnimator alloc] init]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Notification handlers
|
#pragma mark - Notification handlers
|
||||||
|
|
||||||
-(void)onAuthFlowDidFinish:(NSNotification *)notification {
|
-(void)onAuthFlowDidFinish:(NSNotification *)notification {
|
||||||
@@ -50,14 +146,7 @@
|
|||||||
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
|
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
|
||||||
|
|
||||||
if (credentials.usable == NO) {
|
if (credentials.usable == NO) {
|
||||||
NSAlert *alert = [[NSAlert alloc] init];
|
[self presentAuthorizationError];
|
||||||
alert.alertStyle = NSAlertStyleCritical;
|
|
||||||
alert.messageText = NSLocalizedString(@"Oops!", @"Oops!");
|
|
||||||
alert.informativeText = NSLocalizedString(@"HotPocket couldn't complete this operation.", @"HotPocket couldn't complete this operation.");
|
|
||||||
[alert runModal];
|
|
||||||
|
|
||||||
AuthorizationViewController *authorizationViewController = [self.storyboard instantiateControllerWithIdentifier:@"AuthorizationViewController"];
|
|
||||||
[self presentViewController:authorizationViewController animator:[[ReplaceAnimator alloc] init]];
|
|
||||||
} else {
|
} else {
|
||||||
MainViewController *mainViewController = [self.storyboard instantiateControllerWithIdentifier:@"MainViewController"];
|
MainViewController *mainViewController = [self.storyboard instantiateControllerWithIdentifier:@"MainViewController"];
|
||||||
[self presentViewController:mainViewController animator:[[ReplaceAnimator alloc] init]];
|
[self presentViewController:mainViewController animator:[[ReplaceAnimator alloc] init]];
|
||||||
@@ -65,4 +154,14 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-(void)onAuthFlowDidReceiveAuthParams:(NSNotification *)notification {
|
||||||
|
self.progressLabelTitle = NSLocalizedString(@"Processing authorization...", @"Processing authorization...");
|
||||||
|
}
|
||||||
|
|
||||||
|
# pragma mark - ASWebAuthenticationPresentationContextProviding implementation
|
||||||
|
|
||||||
|
-(ASPresentationAnchor)presentationAnchorForWebAuthenticationSession:(ASWebAuthenticationSession *)session {
|
||||||
|
return self.view.window;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -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)
|
||||||
@@ -31,19 +31,24 @@
|
|||||||
#pragma mark - Actions
|
#pragma mark - Actions
|
||||||
|
|
||||||
-(IBAction)doStartAuthorizationFlow:(id)sender {
|
-(IBAction)doStartAuthorizationFlow:(id)sender {
|
||||||
AppDelegate *appDeleate = [[NSApplication sharedApplication] delegate];
|
AppDelegate *appDelegate = [[NSApplication sharedApplication] delegate];
|
||||||
appDeleate.authFlow.baseURL = [NSURL URLWithString:self.baseURL];
|
appDelegate.authFlow.baseURL = [NSURL URLWithString:self.baseURL];
|
||||||
|
|
||||||
NSURL *authURL = [appDeleate.authFlow start];
|
NSURL *authURL = [appDelegate.authFlow start];
|
||||||
if (authURL == nil) {
|
if (authURL == nil) {
|
||||||
NSBeep();
|
NSBeep();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthorizationProgressViewController *authProgressViewController = [self.storyboard instantiateControllerWithIdentifier:@"AuthorizationProgressViewController"];
|
AuthorizationProgressViewController *authProgressViewController = [self.storyboard instantiateControllerWithIdentifier:@"AuthorizationProgressViewController"];
|
||||||
|
authProgressViewController.authorizationURL = authURL;
|
||||||
[self presentViewController:authProgressViewController animator:[[ReplaceAnimator alloc] init]];
|
[self presentViewController:authProgressViewController animator:[[ReplaceAnimator alloc] init]];
|
||||||
|
}
|
||||||
|
|
||||||
[[NSWorkspace sharedWorkspace] openURL:authURL];
|
# pragma mark - ASWebAuthenticationPresentationContextProviding implementation
|
||||||
|
|
||||||
|
-(ASPresentationAnchor)presentationAnchorForWebAuthenticationSession:(ASWebAuthenticationSession *)session {
|
||||||
|
return self.view.window;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="24127" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="24506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24127"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24506"/>
|
||||||
<capability name="Named colors" minToolsVersion="9.0"/>
|
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
@@ -103,7 +103,7 @@
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="425" height="325"/>
|
<rect key="frame" x="0.0" y="0.0" width="425" height="325"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7sM-F3-Zzf">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7sM-F3-Zzf">
|
||||||
<rect key="frame" x="18" y="153" width="389" height="16"/>
|
<rect key="frame" x="18" y="153" width="389" height="16"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" title="HotPocket Instance URL" id="XwM-DV-kei">
|
<textFieldCell key="cell" lineBreakMode="clipping" title="HotPocket Instance URL" id="XwM-DV-kei">
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ygC-xe-m6y">
|
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ygC-xe-m6y">
|
||||||
<rect key="frame" x="20" y="124" width="385" height="21"/>
|
<rect key="frame" x="20" y="124" width="385" height="21"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="rHK-hP-yWO">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="rHK-hP-yWO">
|
||||||
@@ -128,10 +128,10 @@
|
|||||||
</binding>
|
</binding>
|
||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DIc-8O-uoQ">
|
<textField 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"/>
|
||||||
@@ -140,7 +140,7 @@
|
|||||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="PAH-U3-ltl">
|
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="PAH-U3-ltl">
|
||||||
<rect key="frame" x="180" y="221" width="64" height="64"/>
|
<rect key="frame" x="180" y="221" width="64" height="64"/>
|
||||||
<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" imageScaling="proportionallyDown" image="icon-mac-384" id="jnV-K2-7gf"/>
|
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="icon-glass-512" id="jnV-K2-7gf"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2Zr-9i-XDS">
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2Zr-9i-XDS">
|
||||||
<rect key="frame" x="13" y="33" width="89" height="32"/>
|
<rect key="frame" x="13" y="33" width="89" height="32"/>
|
||||||
@@ -154,7 +154,7 @@
|
|||||||
<action selector="doStartAuthorizationFlow:" target="XfG-lQ-9wD" id="AOi-Wt-gmL"/>
|
<action selector="doStartAuthorizationFlow:" target="XfG-lQ-9wD" id="AOi-Wt-gmL"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="mQc-Ea-NNN">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="mQc-Ea-NNN">
|
||||||
<rect key="frame" x="18" y="185" width="389" height="28"/>
|
<rect key="frame" x="18" y="185" width="389" 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="NTZ-zl-yhk">
|
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="HotPocket by BTHLabs" id="NTZ-zl-yhk">
|
||||||
@@ -177,7 +177,7 @@
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="425" height="325"/>
|
<rect key="frame" x="0.0" y="0.0" width="425" height="325"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="yRj-hC-QYS">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="yRj-hC-QYS">
|
||||||
<rect key="frame" x="18" y="185" width="389" height="28"/>
|
<rect key="frame" x="18" y="185" width="389" 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="F4l-2Z-D79">
|
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="HotPocket by BTHLabs" id="F4l-2Z-D79">
|
||||||
@@ -195,15 +195,32 @@
|
|||||||
<rect key="frame" x="196" y="113" width="32" height="32"/>
|
<rect key="frame" x="196" y="113" width="32" height="32"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
</progressIndicator>
|
</progressIndicator>
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="g9a-gR-c7o">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="g9a-gR-c7o">
|
||||||
<rect key="frame" x="18" y="81" width="389" height="16"/>
|
<rect key="frame" x="18" y="49" width="389" height="48"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Awaiting authorization response..." id="3oi-LK-vKv">
|
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Awaiting authorization response..." id="3oi-LK-vKv">
|
||||||
<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"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
|
<connections>
|
||||||
|
<binding destination="OX4-Oj-1cw" name="value" keyPath="self.progressLabelTitle" id="ydU-jy-p3F"/>
|
||||||
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Sip-bU-V5i">
|
||||||
|
<rect key="frame" x="175" y="14" width="76" height="32"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="nYJ-LO-V7O">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<string key="keyEquivalent" base64-UTF8="YES">
|
||||||
|
Gw
|
||||||
|
</string>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="doCancel:" target="OX4-Oj-1cw" id="nAC-If-aib"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
</subviews>
|
</subviews>
|
||||||
</view>
|
</view>
|
||||||
<connections>
|
<connections>
|
||||||
@@ -227,7 +244,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="fae-mz-0sj"/>
|
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" animates="YES" imageScaling="proportionallyDown" image="icon-mac-384" id="fae-mz-0sj"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="T7q-KB-3Ut">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="T7q-KB-3Ut">
|
||||||
<rect key="frame" x="18" y="185" width="389" height="28"/>
|
<rect key="frame" x="18" y="185" width="389" 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="r5O-Sk-IdK">
|
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="HotPocket by BTHLabs" id="r5O-Sk-IdK">
|
||||||
@@ -236,7 +253,7 @@
|
|||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2h7-bN-dsa">
|
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2h7-bN-dsa">
|
||||||
<rect key="frame" x="18" y="153" width="389" height="16"/>
|
<rect key="frame" x="18" y="153" width="389" height="16"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" selectable="YES" title="HotPocket is configured and ready." id="5fh-mh-WR1">
|
<textFieldCell key="cell" selectable="YES" title="HotPocket is configured and ready." id="5fh-mh-WR1">
|
||||||
@@ -245,7 +262,7 @@
|
|||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uci-UC-wxo">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uci-UC-wxo">
|
||||||
<rect key="frame" x="18" y="89" width="389" height="16"/>
|
<rect key="frame" x="18" y="89" width="389" height="16"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Instance URL" id="azk-ea-KeN">
|
<textFieldCell key="cell" lineBreakMode="clipping" title="Instance URL" id="azk-ea-KeN">
|
||||||
@@ -267,8 +284,8 @@
|
|||||||
<binding destination="r5D-xE-cNT" name="enabled" keyPath="self.logoutButtonEnabled" id="gTs-BO-USz"/>
|
<binding destination="r5D-xE-cNT" name="enabled" keyPath="self.logoutButtonEnabled" id="gTs-BO-USz"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8H3-oU-acU" customClass="LinkLabel">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8H3-oU-acU" customClass="LinkLabel">
|
||||||
<rect key="frame" x="18" y="65" width="389" height="16"/>
|
<rect key="frame" x="18" y="69" width="389" height="16"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" allowsEditingTextAttributes="YES" id="EoA-mM-phM">
|
<textFieldCell key="cell" lineBreakMode="clipping" allowsEditingTextAttributes="YES" id="EoA-mM-phM">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@@ -276,7 +293,7 @@
|
|||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9pl-Ap-yxc">
|
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9pl-Ap-yxc">
|
||||||
<rect key="frame" x="18" y="113" width="389" height="32"/>
|
<rect key="frame" x="18" y="113" width="389" height="32"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" selectable="YES" title="Safari and Share Extensions are installed." id="dy7-bw-DYh">
|
<textFieldCell key="cell" selectable="YES" title="Safari and Share Extensions are installed." id="dy7-bw-DYh">
|
||||||
@@ -297,6 +314,7 @@
|
|||||||
</scene>
|
</scene>
|
||||||
</scenes>
|
</scenes>
|
||||||
<resources>
|
<resources>
|
||||||
|
<image name="icon-glass-512" width="630" height="630"/>
|
||||||
<image name="icon-mac-384" width="384" height="384"/>
|
<image name="icon-mac-384" width="384" height="384"/>
|
||||||
<namedColor name="AccentColor">
|
<namedColor name="AccentColor">
|
||||||
<color red="0.10980392156862745" green="0.72941176470588232" blue="0.92941176470588238" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color red="0.10980392156862745" green="0.72941176470588232" blue="0.92941176470588238" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24127" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24127"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24506"/>
|
||||||
<capability name="Named colors" minToolsVersion="9.0"/>
|
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||||
<capability name="System colors introduced in macOS 10.14" minToolsVersion="10.0"/>
|
<capability name="System colors introduced in macOS 10.14" minToolsVersion="10.0"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
@@ -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">
|
||||||
@@ -102,6 +102,9 @@ Gw
|
|||||||
<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"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
|
<connections>
|
||||||
|
<binding destination="-2" name="value" keyPath="self.savedLabelText" id="l2G-Uh-L0d"/>
|
||||||
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
</subviews>
|
</subviews>
|
||||||
<connections>
|
<connections>
|
||||||
@@ -118,7 +121,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 +186,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 +214,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 +236,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"/>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
@property BOOL errorViewHidden;
|
@property BOOL errorViewHidden;
|
||||||
@property BOOL unprocessableEntityViewHidden;
|
@property BOOL unprocessableEntityViewHidden;
|
||||||
@property NSString *uname;
|
@property NSString *uname;
|
||||||
|
@property NSString *savedLabelText;
|
||||||
|
|
||||||
@property IBOutlet NSProgressIndicator *progressIndicator;
|
@property IBOutlet NSProgressIndicator *progressIndicator;
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
@@ -28,6 +29,21 @@
|
|||||||
#endif
|
#endif
|
||||||
self.errorViewHidden = NO;
|
self.errorViewHidden = NO;
|
||||||
} else {
|
} else {
|
||||||
|
self.savedLabelText = NSLocalizedString(
|
||||||
|
@"Your link has been saved!",
|
||||||
|
@"Your link has been saved!"
|
||||||
|
);
|
||||||
|
|
||||||
|
NSDictionary *save = result.result;
|
||||||
|
|
||||||
|
BOOL isNetlocBanned = [(NSNumber *)[save valueForKey:@"is_netloc_banned"] boolValue];
|
||||||
|
if (isNetlocBanned == YES) {
|
||||||
|
self.savedLabelText = NSLocalizedString(
|
||||||
|
@"Your link has been saved, but you may want to update its title.",
|
||||||
|
@"Your link has been saved, but you may want to update its title."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
self.doneViewHidden = NO;
|
self.doneViewHidden = NO;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -69,8 +85,11 @@
|
|||||||
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.savedLabelText = NSLocalizedString(
|
||||||
|
@"Your link has been saved!",
|
||||||
|
@"Your link has been saved!"
|
||||||
|
);
|
||||||
|
|
||||||
self.api = [[HPAPI alloc] init];
|
self.api = [[HPAPI alloc] init];
|
||||||
if (self.api.rpcClient.hasCredentials == YES) {
|
if (self.api.rpcClient.hasCredentials == YES) {
|
||||||
|
|||||||
458
services/apple/poetry.lock
generated
@@ -1,5 +1,72 @@
|
|||||||
# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand.
|
# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand.
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ast-serialize"
|
||||||
|
version = "0.8.0"
|
||||||
|
description = "Python bindings for mypy AST serialization"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
groups = ["dev"]
|
||||||
|
files = [
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:3d822605fa7bb326ef868d25fafced7fc660fa46d9b90c02ea86d5e2f5d325f7"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:2efa40b068197d5efb62655b43baadb842ed71c4958cccd3e8b86a35726f0119"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:db1b957291bca08c7e72f43a12357b2948e20775d970e3fc3dac0aa3160ab725"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdc0d5b18ff8fb364e87923e47c0a91d0d69dbcaeaa274591f7fd26892cc3a3a"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9da7330f3e235bf7da89b8d39205c6350fc0c08a85379743f2df9fff87d6d980"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3186969ee66a9863b00acc6523ace44c56974eecb348a7ea4b228d9f0b80e19"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40a57b73731be45da4fa41430c4d5dc94a24b3a4faba7b9e069978c0402064ea"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5075b9da3ef807eda752502446dfecea3b381c4900b7e27a5d5f4f899eb39951"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:293cc1c5bfa741f8e3fbe8175b9c07beee487c9a6fdbb25a5acad9f1df2d30a9"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e0910c3442a75216dde0f102d854ba2aaa71d2482e0ee213630b9bf29584fba3"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:43dd6d596879bb1cb8a12cc9dae7bb10090a39a35883026c24f82488a195619a"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:8c9d537f59e936392cfd3597789d1390304dd659efc3c486ce7f40fb6b8a9f53"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:f0190a33d7f97c65e9069f7a7f40499eea6b5cbe260c558378109caf20ce934b"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:77308ae6c5cf5264cc0f01a7c556ec77a9e68eb1f61b093534d698139fdc3b14"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8d53a23f27e1ed3a36b2d26fd2a1a6228c8e85a1ed62ff7cdb44bd610769f20a"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ffa5e7cb08f96fed9121f77b224151e41caf88feab9d652bb46c78202b6fbeda"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314t-win32.whl", hash = "sha256:fa70ed4dea0bb18b30a1789c77baa701d0ef30c474f2ccabdea61e25623a8827"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d8b3c8eee4c1baef9d4e84d2a59a805501617127be42615cb48970b15b0892b6"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:ac4f0a83c55a9b782f79ad55a5247b7db123c1db405959791c2ef886e9710c9f"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-abi3.abi3t-macosx_10_12_x86_64.whl", hash = "sha256:86b8a1e6d90467345356098b040150e82fbc26d24a7a202224b13dc1f6264ca0"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-abi3.abi3t-macosx_11_0_arm64.whl", hash = "sha256:39e92ff8e8cb45947fe9007174b2950e1fb098e6abd00266a13cd3bcf6675068"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c85d8d18db5b2dfcb3b7e38a4d600ca35504c0ed8a6f75cd1c811e4ffe248a15"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9830ff7e764f74d9eefb01170c61a9f0fd2c027dac5fcb72e064decd57d56371"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6479d9722a4cd21b578f5478074c41e6169f04811996ec881655560f703a5bba"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a63bed264e818cd83eec11feed0f50aa162542b91132ef58afebc857182763a5"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d187197d234aa45d6cfa2b096be5f666e8cc2e7eb3722d0ab8926293cf5720c"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_31_riscv64.whl", hash = "sha256:2d39a56282cfcc0d8eeea37267c754be59c98d48505c23b1dae5c6011f3813dd"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f7cc5f10386994c0f4844f1e6d6a97127e9b478660eb6dec2b257644f0acab64"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-abi3.abi3t-musllinux_1_2_aarch64.whl", hash = "sha256:6102f2f985c2e542be85cd857678ec9356fefa792b93cadfadd31139f5696f27"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-abi3.abi3t-musllinux_1_2_armv7l.whl", hash = "sha256:3a8660fe66667b76a6e9dccd1d33e66b229fde3b308db991c041609226c005b6"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-abi3.abi3t-musllinux_1_2_i686.whl", hash = "sha256:e7266307e5fba39836edb79def8608887af48820508bff3c5f2941e1e04d1534"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-abi3.abi3t-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca7e6fd1ad845d1cc649dc2ecd499db2f8f46af5bf8da7b70dd858774cc038b"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-abi3.abi3t-musllinux_1_2_riscv64.whl", hash = "sha256:2880350b13d3eae69a0d70bc1fb6c9bfaca4dbd0e20ba8cd1aa483080b56ff06"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-abi3.abi3t-musllinux_1_2_x86_64.whl", hash = "sha256:ab0f9a59f7d63d0d441b56b9a818b273705264352d5115cfee12e940e816d958"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-abi3.abi3t-win32.whl", hash = "sha256:0485a25ef519c62e749ee3c1ad8070e591b380d67226349eb5a70b228dc1ac4a"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-abi3.abi3t-win_amd64.whl", hash = "sha256:bd84d60bca7079e741be4ac5dbe237751a59d7f6f9f0126b11880d63822cbe16"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-abi3.abi3t-win_arm64.whl", hash = "sha256:057769b5921336eb2d9124f2a731b42ed05ffdac559b840dbdf6f3937cf153dc"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp315-cp315-pyemscripten_2026_5_wasm32.whl", hash = "sha256:a02cbed7d8bfdcdee88edaac12bd50d53d9953aaa2e1852ef078625be5f1c0b5"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:e1bd223df0f6c96b396975fa604cb33bce53d9b4a0185490be4c4a289f7c9c87"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:ddd3b61f45c132da66c5476b281891e08c1fd87fbdabe8a6973e1622efc85f06"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f9caa63fad8241257ae401b5ff0a64026c6adb36b8e86cbe8782d9ea505daf6"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3926fa117b5e65019853a2969966d11c7175af377a3425991f3fe73784412405"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:485f1113af805e9e170b95ef993ca3fbd4f89c04bab25c58b4fc632d854801ab"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccebbed24f1281062d5852353c72c47502955926cfcb8345ffb3a44d87ff3d3"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:252f883290d1cdb728eb7fe1d9a7221b88af5a329aae0bc91ddee4dafb820331"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp39-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:96abc072ad29db8d02194afd47d68987322622787daceae82398d7b69f3ba2e6"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9118ad3e369727060b2696fc4078f250ecffca4248ba87f537f55cea9f9dce06"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:f359df4bd921918af8bebd142a376c77511d7151cc8ba852760b587b5a4a54f3"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:e94f9121d13fa36cbf21314783c77d05ae3a0868decd18cf5233fdcc6de49ac8"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:54f95b486018d262bcb387a9afd96f0da74508b442762b80c769454a6fbb3ee3"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp39-abi3-musllinux_1_2_ppc64le.whl", hash = "sha256:4c38b915511e32bc718c49dbce98ff9af36bac0ad6a604f58000cd5e3aecdba7"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp39-abi3-musllinux_1_2_riscv64.whl", hash = "sha256:9a2ef9cf12f2de4f1028c42c1dd7d775255e0fb3e5bb48896c97e35ef52366fe"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6f18048fe9f6dd266bd577cdec48bdcecb74faaa01fe941324435483b013ed2a"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp39-abi3-win32.whl", hash = "sha256:31883542dd6c94d178f5db3d32fbd69c5eb88b3a7c018e7ac8cc0c45195ddbed"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp39-abi3-win_amd64.whl", hash = "sha256:861794565b06337005c1447ef23103a3d5a627d08bdc827870d00d0b28ef5f51"},
|
||||||
|
{file = "ast_serialize-0.8.0-cp39-abi3-win_arm64.whl", hash = "sha256:b2a5978662fd4db463dfb4b974d2b10ac6430b98f5333aabc7051909df3561d0"},
|
||||||
|
{file = "ast_serialize-0.8.0.tar.gz", hash = "sha256:6c37c43e4004dfb42d321ddedc569dc17ff4259296f3af577c9ea46a809bc010"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "asttokens"
|
name = "asttokens"
|
||||||
version = "3.0.0"
|
version = "3.0.0"
|
||||||
@@ -56,40 +123,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 +160,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 +202,35 @@ ipython = {version = ">=7.31.1", markers = "python_version >= \"3.11\""}
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipython"
|
name = "ipython"
|
||||||
version = "9.6.0"
|
version = "9.16.1"
|
||||||
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.16.1-py3-none-any.whl", hash = "sha256:4acae635506f6d352d94c4899a19d5f85f8bc4d230932342dca556fdab1c69b4"},
|
||||||
{file = "ipython-9.6.0.tar.gz", hash = "sha256:5603d6d5d356378be5043e69441a072b50a5b33b4503428c77b04cb8ce7bc731"},
|
{file = "ipython-9.16.1.tar.gz", hash = "sha256:5a3d1f9a47ff216d6cf9cf863124f6a2c1a198d1354c546a4d24a370a283b64c"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
colorama = {version = "*", markers = "sys_platform == \"win32\""}
|
colorama = {version = ">=0.4.4", markers = "sys_platform == \"win32\""}
|
||||||
decorator = "*"
|
ipython-pygments-lexers = ">=1.0.0"
|
||||||
ipython-pygments-lexers = "*"
|
jedi = ">=0.18.2"
|
||||||
jedi = ">=0.16"
|
matplotlib-inline = ">=0.1.6"
|
||||||
matplotlib-inline = "*"
|
pexpect = {version = ">4.6", 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"
|
psutil = {version = ">=7", markers = "sys_platform != \"emscripten\" and sys_platform != \"cygwin\""}
|
||||||
stack_data = "*"
|
pygments = ">=2.14.0"
|
||||||
|
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 = ["argcomplete (>=3.0)", "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 (>=80.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 (>=23.0.0)", "pytest (>=7.0.0)", "pytest-asyncio (>=1.0.0)", "setuptools (>=80.0)", "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 (>=2.0)", "pandas (>2.1)", "trio (>=0.22.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipython-pygments-lexers"
|
name = "ipython-pygments-lexers"
|
||||||
@@ -216,19 +249,18 @@ pygments = "*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "isort"
|
name = "isort"
|
||||||
version = "7.0.0"
|
version = "8.0.1"
|
||||||
description = "A Python utility / library to sort Python imports."
|
description = "A Python utility / library to sort Python imports."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.10.0"
|
python-versions = ">=3.10.0"
|
||||||
groups = ["dev"]
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "isort-7.0.0-py3-none-any.whl", hash = "sha256:1bcabac8bc3c36c7fb7b98a76c8abb18e0f841a3ba81decac7691008592499c1"},
|
{file = "isort-8.0.1-py3-none-any.whl", hash = "sha256:28b89bc70f751b559aeca209e6120393d43fbe2490de0559662be7a9787e3d75"},
|
||||||
{file = "isort-7.0.0.tar.gz", hash = "sha256:5513527951aadb3ac4292a41a16cbc50dd1642432f5e8c20057d414bdafb4187"},
|
{file = "isort-8.0.1.tar.gz", hash = "sha256:171ac4ff559cdc060bcfff550bc8404a486fee0caab245679c2abe7cb253c78d"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
colors = ["colorama"]
|
colors = ["colorama"]
|
||||||
plugins = ["setuptools"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jedi"
|
name = "jedi"
|
||||||
@@ -250,6 +282,154 @@ docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alab
|
|||||||
qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"]
|
qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"]
|
||||||
testing = ["Django", "attrs", "colorama", "docopt", "pytest (<9.0.0)"]
|
testing = ["Django", "attrs", "colorama", "docopt", "pytest (<9.0.0)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "librt"
|
||||||
|
version = "0.15.0"
|
||||||
|
description = "Mypyc runtime library"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.9"
|
||||||
|
groups = ["dev"]
|
||||||
|
markers = "platform_python_implementation != \"PyPy\""
|
||||||
|
files = [
|
||||||
|
{file = "librt-0.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e1a49adf16a7c9d9646816c2946135527197b6fcf4347c7b8b761cf1bfbf4489"},
|
||||||
|
{file = "librt-0.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:81a398f45b45a59200e13cd5ad1ae1d3f44334de98b148331afe2cdfee701c52"},
|
||||||
|
{file = "librt-0.15.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4eafbaff06b9563f8b1c850621ce51605de05208e09d4d71ce490bc972b7b9e8"},
|
||||||
|
{file = "librt-0.15.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:b0411b4066db926b80258c60dcb0e6db4c9cee312eab45b7e8866b17ddf9ada1"},
|
||||||
|
{file = "librt-0.15.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:febb1ce6cac545a54e6b769982824e955a700fdd9fbf3a08a3d82c990968b57d"},
|
||||||
|
{file = "librt-0.15.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b230acc1c3bfe2d6f2627ba2b95dc92e58aa494600e9722d0e6ccbc931e59702"},
|
||||||
|
{file = "librt-0.15.0-cp310-cp310-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6da110e5f314c19ab8478464d02ae18808ae73d522c15260fa4918acdcd64da9"},
|
||||||
|
{file = "librt-0.15.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:eab9208b00ca55bf75983ec99f7bf13acc746a36102e98953addaad7f7ea1e1b"},
|
||||||
|
{file = "librt-0.15.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6c013cd3a1721e69e14380ada97eaa4b7b0cdf1c6b96fa765d4ea47c875088db"},
|
||||||
|
{file = "librt-0.15.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:567b1c430f8bd560e689421468278ac5941bab4a05303b5d95b6ae10db03f451"},
|
||||||
|
{file = "librt-0.15.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:29c4cab9df457b19672c39be7f384ebb2bc925c4e2684b8780c222b43eb36389"},
|
||||||
|
{file = "librt-0.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bccbd8e5b0bffb7106cf18eb1baa3d7194b1cebb3b4b1cdbd4bdb19382a6ee6c"},
|
||||||
|
{file = "librt-0.15.0-cp310-cp310-win32.whl", hash = "sha256:8ae493ed5f659a7761c43d42f183db514536073ded9bcf671d2d1df47e29a07e"},
|
||||||
|
{file = "librt-0.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:bc25fb356d0c7810bb49ff3df908ad1fda6995d660ab099ded69244ed7ab6053"},
|
||||||
|
{file = "librt-0.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:823b92cf3c18ecd08afc70c42473888b41b6e8ef5046f3b82c05c154a2fa3d22"},
|
||||||
|
{file = "librt-0.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c70bc1b602cf59917e8f0c7a2cbc8bcc6fbc14d5486136b00707a79619121d63"},
|
||||||
|
{file = "librt-0.15.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:814ff83a25b5fce8b9c80c4dd803153fb5c5599fc74db9e022466938368957ef"},
|
||||||
|
{file = "librt-0.15.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:57f5eeb6ad4c180de583b1038e61fe5fbd9796bb69a8a1c1a0c7ddbec4c8c60f"},
|
||||||
|
{file = "librt-0.15.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:82909c8f7eb9952656b65d3147afde4cf8e6d5a991eebc86418b5e65843b0ab8"},
|
||||||
|
{file = "librt-0.15.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f779070399f991400fc451719e0ea388eb7de313388bada2c127a35de05f798a"},
|
||||||
|
{file = "librt-0.15.0-cp311-cp311-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bac89069bc496ebdf4f79ebb57bbd10d0b214c8454225deb672d91002bd17e18"},
|
||||||
|
{file = "librt-0.15.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e0d00c708fb2f5822b152429b1ac80a58dbbbc3f6c232c4d13a3f7fcf2ea5b4c"},
|
||||||
|
{file = "librt-0.15.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6c6624fe268625869485553dd7cc1daf30d22558215bb2a4ff16f67a9801a31a"},
|
||||||
|
{file = "librt-0.15.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f56b397858a23dacf35ede366ed2212fdc03a6a57a1ad36468ad6e9dc5fac091"},
|
||||||
|
{file = "librt-0.15.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:4388184646efe2054911c5b00a1077d6d1ee86a95b7e8ba96dc7850a809f3f40"},
|
||||||
|
{file = "librt-0.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:97335f59082f9fe2ce6c2a9cc6433a0114bbb6cd4d5c09dd76c95c68b9f9a8b0"},
|
||||||
|
{file = "librt-0.15.0-cp311-cp311-win32.whl", hash = "sha256:83380ffde38062a2e9bb55d83e74474f6614665528b98a6928720fc006dfffbb"},
|
||||||
|
{file = "librt-0.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:f75720477ee05d509a310e856cacc8d909adc182f7b91193c207bcc26d7ee6db"},
|
||||||
|
{file = "librt-0.15.0-cp311-cp311-win_arm64.whl", hash = "sha256:256237037a3ab001ae8d9803b2d43562a4c3aa38739843694349e4d5ebb0fd56"},
|
||||||
|
{file = "librt-0.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e87bc679f86a99aa3b26e3c78eeb821a247c9a28eae48eaafcc32c3bf4c3bb9e"},
|
||||||
|
{file = "librt-0.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:71599e011ac880e8e45d46047d714871894c7d4ab6f25626f8d4f89da21f368d"},
|
||||||
|
{file = "librt-0.15.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c802434092b769b1d613ed2e13fac15fbfce1934a74bd10283b03c0fae231cd1"},
|
||||||
|
{file = "librt-0.15.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:5500eeae393a184d14e1f35645962c27129d20c81afa4069e6ef826ebc2b3aaa"},
|
||||||
|
{file = "librt-0.15.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6ecfc32dfb46fb7b565bcd6abf9412acf978775a998273d22888a6d7953730dd"},
|
||||||
|
{file = "librt-0.15.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:89cc46cfd15022e35084355478c9ac809d90b1152222706ac9a7655ec21df6fa"},
|
||||||
|
{file = "librt-0.15.0-cp312-cp312-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d5f51401d102c885b9ca509e62c79b1dbff286e1b9b047fde6f763780789356d"},
|
||||||
|
{file = "librt-0.15.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:cc30523e3f1a23fb7511cc659834a0d01a1042bb9de359bc1c131cc4ec6c9656"},
|
||||||
|
{file = "librt-0.15.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:59fe030d8ae4a57e3fb7756bf35a858de74e04066fc8555c53d0af979132af81"},
|
||||||
|
{file = "librt-0.15.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5a6526a2a956bbb1e4ae3568c82e650fc99119c66bb011ea60715744955a2b4d"},
|
||||||
|
{file = "librt-0.15.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:85ea21ec6730194d67156b0e0b5430ccb1d61f8b8b907e39b37f9812b74a13f0"},
|
||||||
|
{file = "librt-0.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1e47b8ba865d7ede071a91a7163073bbaeb72541f1ef8a07d512c45c7b5007f2"},
|
||||||
|
{file = "librt-0.15.0-cp312-cp312-win32.whl", hash = "sha256:a5207ec414d1c4a2a7231b2086970dc036f94293cdf338190984958a013a42f1"},
|
||||||
|
{file = "librt-0.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:73b30cfa976659b3917c8f6153bdb0591c6a9ec6583599fd24a689b690622022"},
|
||||||
|
{file = "librt-0.15.0-cp312-cp312-win_arm64.whl", hash = "sha256:a54cf9e0ef47b96af580849db5471142200568ce1e02cbf416addab551369570"},
|
||||||
|
{file = "librt-0.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:db13ca398005abcbe538deda87b686d9bd08b7001cf40c4c06b444960ae10a26"},
|
||||||
|
{file = "librt-0.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa1f1995789dca3698bc550aaceb09a51bd5df0a057ff84ff15296cd1975b801"},
|
||||||
|
{file = "librt-0.15.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55456ea87d8df21808446d03817be2f65e20391c1c615d9187440dff28cd08dc"},
|
||||||
|
{file = "librt-0.15.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:5a86a5a08c2235316bdb359d5dbb6ce0abfca7fac06363103e2c5af571d92f95"},
|
||||||
|
{file = "librt-0.15.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e56b6a368529bed262da40ce13f8fef590db0479819cca84f16a1f01ac356d0b"},
|
||||||
|
{file = "librt-0.15.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:234d8d394721fa0d786af15ebf1f3fb7f3ed82fd1cd0cde45c2f247b5d4281d2"},
|
||||||
|
{file = "librt-0.15.0-cp313-cp313-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d8363d7accb0286ac3a0e633f396e93800dafb8150494505daf9515bbda591f3"},
|
||||||
|
{file = "librt-0.15.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0f0ee3644d951f31055ad07d77d92520e84505dd7a432cc4cd501dd70ee06785"},
|
||||||
|
{file = "librt-0.15.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2cfd1a81a648806e6a7717be4cc4d1bb392fa229752bf8444ba365e381e984d6"},
|
||||||
|
{file = "librt-0.15.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a6cd22c9da0d866558e46a041f1cc0c2bbb26b61b137b2347fa834c332e1d101"},
|
||||||
|
{file = "librt-0.15.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:6d5225ef8801e4ea5e482fa9b5dfb891dd9ef6f6d870f1f25d449ca2c70ac218"},
|
||||||
|
{file = "librt-0.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d28a05796b99f749bf8794f17ba9ba1612d0076b802e9cfc62c554634e9ce3b"},
|
||||||
|
{file = "librt-0.15.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:2067ff438048cead9d223ca5675bae2a25e520a7c3e6c1498bf9c6892d22caab"},
|
||||||
|
{file = "librt-0.15.0-cp313-cp313-win32.whl", hash = "sha256:1cd3b721f24c206398b9e26da3c3a9c011e6e89d06f318ba8ebefc30f1003890"},
|
||||||
|
{file = "librt-0.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:f395a4a9a03ac062dbe9a9f82e0c720502e590a38feee6a757bc82e9c63afbd8"},
|
||||||
|
{file = "librt-0.15.0-cp313-cp313-win_arm64.whl", hash = "sha256:0a15cb554761247d84a3ec0cbdf4078d70725384f0e4662c0fa3b26266eb60ad"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f5de7feedc56337a088eb15cd9fafa9938367362221d8cc62c642b7f94821993"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6c0eb900c0e91f4aebe680845242e614f1864edfd44106380d0752ac29522bf8"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e8c9a650a188e38bac005048cbe6342e81407782944d01934540ab75e417df21"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:92bfed8deec93df30286b9fe9e3b1dd17329cc076a192b4ee5ec223841d54953"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ec4b19788f835711a2072f9dbe6b03b3bf32ed1f0fb30cf399bdd59d9f0c33fa"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4c7bacb70930f3d0a56f4ecf1be474a1f0d941b01dd73b756f3c256d42cb879"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3e79f05e4a08b4d880342673312bbc895b56df7765605796f15902eb5367d3ae"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a417149c0cba4d50b61e992e5a15e69eaf96746609b461cc4ed168aeef6b79dd"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:da7a94d6a3411f579d72aa3e3bc5fbca7ed4549f3dbd7e5de3aa567333374285"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:856f743ae607f2c1380eccb566c0038a9fb3eabf0fc2be2704d76d9f73557239"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:779a6e7c894737e5983e7790a9c78c4000c30e23c9aada08081bdbea53b0fa60"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:96bb17dbe8bab3c0954fbebfc69ed395599de75b6bbc35e3270a878e15d4dd65"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:7220697efaa6e5348fc3d18ee7f8563d4bfecd9872b37ffb915bfc1d08840622"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314-win32.whl", hash = "sha256:f54598964d357b1c5ab77cf5d92f21e598fe0e23cdbe9618480807f81b4eba15"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314-win_amd64.whl", hash = "sha256:3ff5893a2c23d886aa9ce786de5ac6ddc74aeeaf90743682b74d920e117d2e28"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314-win_arm64.whl", hash = "sha256:3722a099730704c9a3d70c879fc0f51daec25fe5f1555672d97bc595abeafb95"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:38c0c7d4b6fc06c3324b3f9162c8391bfc4fd9dde53afe1033ce7edb48d5a714"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8b2fdd7ead3c995c37940a790690660d0ca006c302db26cc51933f6766866fc3"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2fde98cf1fc4bac144ce23c2c4c017b924ba714509ea9334977b0b27050c837d"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:e3b461183c5fa7681b48560f91515f53a953122fb30c71e07abc67d7ddf58c38"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4bbcc257e3babea20a91715c361b24554ec4e8f51aa578568afc230799fe1a19"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b845b8d48088fad0cadc84be4b8fda63203be7e9237b71015b3925443c1f35ab"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b30e600e8f337b9bd7f39b86d9fdfedc73cc46e3d0f745931a23a234220bb7e2"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:64b0c8c35aa4c4ed79896359f3e0b285cbe4e610042106500da4811c322cc108"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:0da0d94cb802f32a0524653e7201f2cef72d5f700a5407678f5290483d4fcd08"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:4a6369168d371207339b1e50d4532b06a7121586141f82599505a3f315751d47"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:c434e072557ade9cbc642d052c89d031efe47d5c9614523619d0d74a02378e81"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c7eec6a42018bc1d45763b1c162d3d2bf7c3b9a1b0ed30d3e91dcba390efefcc"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314t-win32.whl", hash = "sha256:6912fa5e635d74529ac7cdb1bdf6ca3af4453da8d1edbe0110ee1cb4ad407ebf"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8e11699ed745931c395acd3621b07062e0f840efa6935aad87a64ed0995f0915"},
|
||||||
|
{file = "librt-0.15.0-cp314-cp314t-win_arm64.whl", hash = "sha256:5d2a91724463bfed4f573cd7a9fdc856d2e230d0c0e5a61416a93481dccd8605"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:8443e38dcfcfdbcf5add5118c623efd788d65ac2e25756d6251a54a06a4d0aca"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:6d15a29033c57490cfe2069097c6fc4049e4e65ffbb749be7dc453b7c4c68965"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d2c05c729b589e734c09578bf5964be48a911765484840d017bbc84f49d4c4ad"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:fa60887537e1d0cd2d9982269d33a709bf54b195cd2b9364fc0a758022af5bd9"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d8bc24219b24c0af375718942ab75e3544b2763085f40f965be4326734ae8328"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:86a21a7bd3fe3a419512ef424cc1c020f6771d0b29cfddff36d1635a855e63f0"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dbab647e88d90b3167b91efe7091e248653688ed4337e4f90907a722c7361bb9"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:d8edcf6f550e918dca779c069b9e156385c60b406f99fc7641f32c52f7193659"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:8b62076030baa2d8b1501a46bf0e19c27a489aa90671c55665bff7887f7660b0"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:d00d20d1818e82a07a0ee0aa89a98b17ed7916b92441090b683719cb20a59b6d"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:4e6ee93fc3cf848dcbf0cce2eca73d8e7dcd0cc2b6df3a529d57750b30a4c55c"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:32896a0af72508ea979e0acb4e4c04cbeeae04938167950d535c83c45597167d"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315-pyemscripten_2026_5_wasm32.whl", hash = "sha256:ec3ba415afaf951f6951b1dd16d3c8e4f540065fc382d7e70b823a79567ca374"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315-win32.whl", hash = "sha256:d2813ba2503764f0450680c533d13df7cff9b49df1411062eded5f67db4195b9"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315-win_amd64.whl", hash = "sha256:b87d67e33afaf265262f2a66db578284b88ee2e6fcd224579cb5c15518677ad8"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315-win_arm64.whl", hash = "sha256:713bd7df21170b982e729e46870f31d6b437bd1a9b4648cffb529bd3c2ec5c4b"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:3de789c82752730f94782a5ee518baf9c05edf85733aeaf73bb6e518755cdf54"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:e0b5deec9a8664eb722c797241970fd4aa1894d25fda36a1ddac0f7407606bd6"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5563302a8359bc2295bb7084d1a8ed1519df96afb30eb2aa4e0bff7b54228988"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:22d6263b9d39d7bbb286fa791945646e3218f1be2d693e36fb630f1d0e59cd13"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:39ffd14646190c454f0d86e0d256b33f00a87a26ab410e619773b841d0e41416"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c47318cd3a61401452de11282242937e3e057c4fd3dbaf601e269d0928a06c0a"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a56a1d4f859a82ca5b99fc4b82c9b027b15e3c455c5cd99e7d0719f27bb20b6c"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:077471b3182db4e17c36ae91555f36a4d2c00080b267f749bcad34a478a9a302"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:411ca4d1b905b860ceba7570dd6717a71dedaddcc4b0f77ece710aa41ee11f8d"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:1256589e0b0adb31751d685a68bce29d73407ddf4ef05d4188f49d5dcf9566d9"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:f42b74a53e5f26a0ba0007411a7455b66c67ce4022a39cc1f56fc4efd65bcbab"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:291bf73caf78b9e88d6fae9bfd693207ff7d832e2fdbe2cf8e746bc13f5f892b"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315t-win32.whl", hash = "sha256:c16d15ee371643ab48dc8248a3e680ebbeca573a13af2c3dd0c985b142d77162"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315t-win_amd64.whl", hash = "sha256:dbd605739f228912dc49027cb764456b9757750bdc2b6b7773164db7096c6fd1"},
|
||||||
|
{file = "librt-0.15.0-cp315-cp315t-win_arm64.whl", hash = "sha256:84d244b00604d17df3fc7736c327892d6bba66181254aa4087be807b6c342bdc"},
|
||||||
|
{file = "librt-0.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0e2d0c0acf5b0ada7d045912b7cf787c21315c95b38b1fa939ef72d45d366b3d"},
|
||||||
|
{file = "librt-0.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f9ca190fe9edc0eb08eec558a509a16d28d91c35667b8f043cba40ed5e77a959"},
|
||||||
|
{file = "librt-0.15.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:80811e1c42386ea95c6fb30571d3250ad43d7863f883f787f70517f441150e59"},
|
||||||
|
{file = "librt-0.15.0-cp39-cp39-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:88c2a17815c266e6d8180204ff62cb739ab869ada4a746d4c505331526ac58f1"},
|
||||||
|
{file = "librt-0.15.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a5fa8f1f916988d0bf1afea005bda37f56ac41a18016e813ccf0097a8d460ca4"},
|
||||||
|
{file = "librt-0.15.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:355e3a4c725225a14262004fc1872a552b9d3634b4f791a0dfc80804aafbfd55"},
|
||||||
|
{file = "librt-0.15.0-cp39-cp39-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fc1ed11c4ad0b91af24def2050f2840ea4567828e3dd058fbe608d982f6e5465"},
|
||||||
|
{file = "librt-0.15.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1f4ef2e71db33df4309167ed7f1520c4fae5e611226e159fa9cf33f93e6ddb3d"},
|
||||||
|
{file = "librt-0.15.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1a1a8cd430c7dd0c083f455cb1b328d7fc682b05c31b940906f7845bdff80881"},
|
||||||
|
{file = "librt-0.15.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:04d5387b908676c0b8d5d2f5fb58373b4ea382d81f7a6f0fab8ea2a462bb4738"},
|
||||||
|
{file = "librt-0.15.0-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:1172c6ad2a88b646e7fe3b480e3fac4ab4418b3443fd8a4061fdd531e0622fc7"},
|
||||||
|
{file = "librt-0.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:52e8db01f603f5da0ca30987479acff98769382efc8e142fa3962395dcf3ffdb"},
|
||||||
|
{file = "librt-0.15.0-cp39-cp39-win32.whl", hash = "sha256:e4c911f15a1652ca94ae9f1abd92e74cbb1b3597d2d92fdd556202f94e8cd455"},
|
||||||
|
{file = "librt-0.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:68242379c9b65a582b6e97318a1e9fbd6d445e58954f2d437991c4804ab11578"},
|
||||||
|
{file = "librt-0.15.0.tar.gz", hash = "sha256:4e66cbe84437497d951b799d3e1551291b6fb3d643820a7014b3655d57a59162"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matplotlib-inline"
|
name = "matplotlib-inline"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
@@ -279,56 +459,75 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mypy"
|
name = "mypy"
|
||||||
version = "1.18.2"
|
version = "2.3.1"
|
||||||
description = "Optional static typing for Python"
|
description = "Optional static typing for Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.10"
|
||||||
groups = ["dev"]
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "mypy-1.18.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c1eab0cf6294dafe397c261a75f96dc2c31bffe3b944faa24db5def4e2b0f77c"},
|
{file = "mypy-2.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:57a936373fc690c43a8cd7e7e12a35148e4ec5aa7698ad7fc0a9f918bdc5be41"},
|
||||||
{file = "mypy-1.18.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7a780ca61fc239e4865968ebc5240bb3bf610ef59ac398de9a7421b54e4a207e"},
|
{file = "mypy-2.3.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d00d769056bde2f4e69c175071eba45cfb44fa1ed92bdfbfe64a93e0543b0cf0"},
|
||||||
{file = "mypy-1.18.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:448acd386266989ef11662ce3c8011fd2a7b632e0ec7d61a98edd8e27472225b"},
|
{file = "mypy-2.3.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2166b29228835e1f88ff411e96639e6ca3c7fdde84b62ec211f70f86b4051167"},
|
||||||
{file = "mypy-1.18.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f9e171c465ad3901dc652643ee4bffa8e9fef4d7d0eece23b428908c77a76a66"},
|
{file = "mypy-2.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:83d36c2924df7426333abe7faf4724a7e1aab0d9fd41625e81b4683034b80c13"},
|
||||||
{file = "mypy-1.18.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:592ec214750bc00741af1f80cbf96b5013d81486b7bb24cb052382c19e40b428"},
|
{file = "mypy-2.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:f12fdb70459d0060dea40b29e52163a961b156106d68d57882a6a9f648983a53"},
|
||||||
{file = "mypy-1.18.2-cp310-cp310-win_amd64.whl", hash = "sha256:7fb95f97199ea11769ebe3638c29b550b5221e997c63b14ef93d2e971606ebed"},
|
{file = "mypy-2.3.1-cp310-cp310-win_arm64.whl", hash = "sha256:e099200a1b1b1223a4951f0a90cbff1b8c91b250ba599dab1f7217a628144d90"},
|
||||||
{file = "mypy-1.18.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:807d9315ab9d464125aa9fcf6d84fde6e1dc67da0b6f80e7405506b8ac72bc7f"},
|
{file = "mypy-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94f04929f1c44c35fb0061e912087edaf504acede963a4a7d00680bd089d8531"},
|
||||||
{file = "mypy-1.18.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:776bb00de1778caf4db739c6e83919c1d85a448f71979b6a0edd774ea8399341"},
|
{file = "mypy-2.3.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f5d716048611e85ca9eefb2e1baa5d73ede389b5820ded260ea27c757d667af8"},
|
||||||
{file = "mypy-1.18.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1379451880512ffce14505493bd9fe469e0697543717298242574882cf8cdb8d"},
|
{file = "mypy-2.3.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b091a455111214cb5c9d54a57b9618e9a49f9fe2a42e4e1ac86e9d104ed96ce8"},
|
||||||
{file = "mypy-1.18.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1331eb7fd110d60c24999893320967594ff84c38ac6d19e0a76c5fd809a84c86"},
|
{file = "mypy-2.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:df12e20c9efd614738c71b390007ecd0181125afc4ccafca04d78a1d2eed2c01"},
|
||||||
{file = "mypy-1.18.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ca30b50a51e7ba93b00422e486cbb124f1c56a535e20eff7b2d6ab72b3b2e37"},
|
{file = "mypy-2.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:52eaf3a155f35cf80b40220288c861eb45f14a2340c1f6cbfbdb0feff32879d1"},
|
||||||
{file = "mypy-1.18.2-cp311-cp311-win_amd64.whl", hash = "sha256:664dc726e67fa54e14536f6e1224bcfce1d9e5ac02426d2326e2bb4e081d1ce8"},
|
{file = "mypy-2.3.1-cp311-cp311-win_arm64.whl", hash = "sha256:9b4eacbee8a69836c06eff6d0dd4e134a07c2b047755b30c08625fe214f322c6"},
|
||||||
{file = "mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:33eca32dd124b29400c31d7cf784e795b050ace0e1f91b8dc035672725617e34"},
|
{file = "mypy-2.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a32bbbb940af990d3be0b8af321c7b6815bb1b3b48142fe7459b9cc5f58959ff"},
|
||||||
{file = "mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a3c47adf30d65e89b2dcd2fa32f3aeb5e94ca970d2c15fcb25e297871c8e4764"},
|
{file = "mypy-2.3.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff715e45b2231a8e85de1d163d1b42791e4d7aab8f5145f85fee1b710b735aff"},
|
||||||
{file = "mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d6c838e831a062f5f29d11c9057c6009f60cb294fea33a98422688181fe2893"},
|
{file = "mypy-2.3.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:858fc57d3d91fa728e33e7ad71def60fc6272694607b306cd3292db53ae39080"},
|
||||||
{file = "mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01199871b6110a2ce984bde85acd481232d17413868c9807e95c1b0739a58914"},
|
{file = "mypy-2.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:851833db876e7b650f93719c74b7879a08e338979c96054fdfc3bfd90a486355"},
|
||||||
{file = "mypy-1.18.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a2afc0fa0b0e91b4599ddfe0f91e2c26c2b5a5ab263737e998d6817874c5f7c8"},
|
{file = "mypy-2.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:4c5095a327483591c94e0c8d3ef9e50d4ab1369b541eae007c1f23bc2a41f6bb"},
|
||||||
{file = "mypy-1.18.2-cp312-cp312-win_amd64.whl", hash = "sha256:d8068d0afe682c7c4897c0f7ce84ea77f6de953262b12d07038f4d296d547074"},
|
{file = "mypy-2.3.1-cp312-cp312-win_arm64.whl", hash = "sha256:bbfe022634a2a195406bd469e888d2eaf193b02ba7e607391cd7640374aaae3b"},
|
||||||
{file = "mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc"},
|
{file = "mypy-2.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:114dff494000f18bd10d5d95d84b8567b26da60279ecbe838131841df20e635d"},
|
||||||
{file = "mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e"},
|
{file = "mypy-2.3.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8637731bb5eee3671eb2c3200827aa3564ed8a9309ecee4d1afe77e6d031bdb"},
|
||||||
{file = "mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986"},
|
{file = "mypy-2.3.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c80fbc405ed8020f5ff3802dc18cf060197bcdd3fbdd6a26ef2fd34dfdd5226"},
|
||||||
{file = "mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a431a6f1ef14cf8c144c6b14793a23ec4eae3db28277c358136e79d7d062f62d"},
|
{file = "mypy-2.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:84081f538ce27375045c02e3d7f81bd11d853400621ae245d87ce7b6c420ec74"},
|
||||||
{file = "mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7ab28cc197f1dd77a67e1c6f35cd1f8e8b73ed2217e4fc005f9e6a504e46e7ba"},
|
{file = "mypy-2.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:e9144ac16fde007096f9563eb2041b4433c2d705c4218edeb79e7e9d01035ee6"},
|
||||||
{file = "mypy-1.18.2-cp313-cp313-win_amd64.whl", hash = "sha256:0e2785a84b34a72ba55fb5daf079a1003a34c05b22238da94fcae2bbe46f3544"},
|
{file = "mypy-2.3.1-cp313-cp313-win_arm64.whl", hash = "sha256:77ad9529e67dca28e511f5cd5671436584ce91f6d3bac159a353158187b986ac"},
|
||||||
{file = "mypy-1.18.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:62f0e1e988ad41c2a110edde6c398383a889d95b36b3e60bcf155f5164c4fdce"},
|
{file = "mypy-2.3.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:192abaedf75da1bc0b1cef104927e70ec49c1ef0031cc4825c7ee10a438ed24d"},
|
||||||
{file = "mypy-1.18.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8795a039bab805ff0c1dfdb8cd3344642c2b99b8e439d057aba30850b8d3423d"},
|
{file = "mypy-2.3.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf678dffd16efcda2c15cbd30e9ecc0081388e29ea23687a88e686ed92638dc3"},
|
||||||
{file = "mypy-1.18.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6ca1e64b24a700ab5ce10133f7ccd956a04715463d30498e64ea8715236f9c9c"},
|
{file = "mypy-2.3.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e036f06b41630f4c8a1d48f9ac6aa26acc65f8be089973f5519da643318f03f"},
|
||||||
{file = "mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb"},
|
{file = "mypy-2.3.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:71af9c8a894e862b58e92abb08e53b05a384a1e5e5d6dc7cda59126211a53d82"},
|
||||||
{file = "mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075"},
|
{file = "mypy-2.3.1-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:3c80cd23d85368bdd9f37d5231dfd97d35bcbf5bf41af96ef3a9b078ad1957f9"},
|
||||||
{file = "mypy-1.18.2-cp314-cp314-win_amd64.whl", hash = "sha256:749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf"},
|
{file = "mypy-2.3.1-cp314-cp314-win_amd64.whl", hash = "sha256:4956f34d145e145562a0a0bf367f642bbc85c04ec2baf47ae015947c3169a85d"},
|
||||||
{file = "mypy-1.18.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:25a9c8fb67b00599f839cf472713f54249a62efd53a54b565eb61956a7e3296b"},
|
{file = "mypy-2.3.1-cp314-cp314-win_arm64.whl", hash = "sha256:cfb12e360242d23d91f5e978d94f58ea66acf5804c4fb6f2f794a20d4cb1b595"},
|
||||||
{file = "mypy-1.18.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2b9c7e284ee20e7598d6f42e13ca40b4928e6957ed6813d1ab6348aa3f47133"},
|
{file = "mypy-2.3.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e5f1c50bb05b64e2026b52867e8d21106f01313c744a2c4ecc34c90d12e8d6e2"},
|
||||||
{file = "mypy-1.18.2-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6985ed057513e344e43a26cc1cd815c7a94602fb6a3130a34798625bc2f07b6"},
|
{file = "mypy-2.3.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:667196b352f4cf304ded4c10f90cfc179263a1acfb3cdcfa984bdfd340d498bc"},
|
||||||
{file = "mypy-1.18.2-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22f27105f1525ec024b5c630c0b9f36d5c1cc4d447d61fe51ff4bd60633f47ac"},
|
{file = "mypy-2.3.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b9c53e395c12cad2c6d4b67d5da7c6057638a132d85c08b73646b18f802a0045"},
|
||||||
{file = "mypy-1.18.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:030c52d0ea8144e721e49b1f68391e39553d7451f0c3f8a7565b59e19fcb608b"},
|
{file = "mypy-2.3.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:18162b128c3f9c703cd35f5537446900b0d21a2549aa7a95d21380d2ef643fb0"},
|
||||||
{file = "mypy-1.18.2-cp39-cp39-win_amd64.whl", hash = "sha256:aa5e07ac1a60a253445797e42b8b2963c9675563a94f11291ab40718b016a7a0"},
|
{file = "mypy-2.3.1-cp314-cp314t-win_amd64.whl", hash = "sha256:30c0477d4aab7b7f39c8397dc877f2c96b9fe5588ec379f372c56eb63d599f63"},
|
||||||
{file = "mypy-1.18.2-py3-none-any.whl", hash = "sha256:22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e"},
|
{file = "mypy-2.3.1-cp314-cp314t-win_arm64.whl", hash = "sha256:6941ab3619377bc3f32ca02876b07d27f216f5201604b664d3937ea0fdd23bb4"},
|
||||||
{file = "mypy-1.18.2.tar.gz", hash = "sha256:06a398102a5f203d7477b2923dda3634c36727fa5c237d8f859ef90c42a9924b"},
|
{file = "mypy-2.3.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:6f041a6de52c9217ca125e78ba0a335cb7fd98a1c0580978e49ab2b126f70b57"},
|
||||||
|
{file = "mypy-2.3.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5159ae60f5dbc3a498af5ba8365505808ac8031bc63f9e00304ad545d40bdd9b"},
|
||||||
|
{file = "mypy-2.3.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:47a8a7a0a7f6f6e63995c0ac36fa0c07b127413fdc81f0439b7f3dccafd33561"},
|
||||||
|
{file = "mypy-2.3.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:2329c0501293d4e1f33bc15d04d6304d65a1cdda967ee93a05c1e681a3923133"},
|
||||||
|
{file = "mypy-2.3.1-cp315-cp315-pyemscripten_2026_5_wasm32.whl", hash = "sha256:bb26deed807bdb0457cf3e3f1cd7c4a1cf9d66864eaf1b4a61e06805d4c6b1f9"},
|
||||||
|
{file = "mypy-2.3.1-cp315-cp315-win_amd64.whl", hash = "sha256:375d7013876a8233b2d05be185bfa09f689696cd999ce8b1cfe6acac5c80e8a3"},
|
||||||
|
{file = "mypy-2.3.1-cp315-cp315-win_arm64.whl", hash = "sha256:586b3612214cceabb3c0f588c97e7d1e535393f06a60e912e994f6b3ace97523"},
|
||||||
|
{file = "mypy-2.3.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:ef0c6335cda9d807f8193d8ff6204a72bc909fa9882aacbca14f43cdb7188306"},
|
||||||
|
{file = "mypy-2.3.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e598c8c66401d26b150872154a286e6d484cf2789c3bb28a7556806298423021"},
|
||||||
|
{file = "mypy-2.3.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eda22fd4efa9dcd39331d1dede9b5b8b8a7fd69af07592e778433da98610d29e"},
|
||||||
|
{file = "mypy-2.3.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:2a0ba2e57847849fb0d1fcdabb32786d223095ed8bc121dfe322bcdb3d9c46bc"},
|
||||||
|
{file = "mypy-2.3.1-cp315-cp315t-win_amd64.whl", hash = "sha256:3f7e865dd51f235f60a2dbcd8728a1c095f5ca28f095d48a725b84cd935735c4"},
|
||||||
|
{file = "mypy-2.3.1-cp315-cp315t-win_arm64.whl", hash = "sha256:8ad80807dc3ab8ea978b1b2b6e4a657194ace1d4ef03e0e731aff1abd517da29"},
|
||||||
|
{file = "mypy-2.3.1-py3-none-any.whl", hash = "sha256:6ed5c7e3419083268e5c9258bd1c1ef91af44a9e89374dbcaf37b775716e72eb"},
|
||||||
|
{file = "mypy-2.3.1.tar.gz", hash = "sha256:47c1b1207258513a9d93495f69c8be9de73916186f0e52703e8c461b7a623419"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
ast-serialize = ">=0.6.0,<1.0.0"
|
||||||
|
librt = {version = ">=0.13.0", markers = "platform_python_implementation != \"PyPy\""}
|
||||||
mypy_extensions = ">=1.0.0"
|
mypy_extensions = ">=1.0.0"
|
||||||
pathspec = ">=0.9.0"
|
pathspec = ">=1.0.0"
|
||||||
typing_extensions = ">=4.6.0"
|
typing_extensions = [
|
||||||
|
{version = ">=4.6.0", markers = "python_version < \"3.15\""},
|
||||||
|
{version = ">=4.14.0", markers = "python_version >= \"3.15\""},
|
||||||
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
dmypy = ["psutil (>=4.0)"]
|
dmypy = ["psutil (>=4.0)"]
|
||||||
@@ -367,16 +566,21 @@ testing = ["docopt", "pytest"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pathspec"
|
name = "pathspec"
|
||||||
version = "0.12.1"
|
version = "1.1.1"
|
||||||
description = "Utility library for gitignore style pattern matching of file paths."
|
description = "Utility library for gitignore style pattern matching of file paths."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.9"
|
||||||
groups = ["dev"]
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"},
|
{file = "pathspec-1.1.1-py3-none-any.whl", hash = "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189"},
|
||||||
{file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"},
|
{file = "pathspec-1.1.1.tar.gz", hash = "sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
hyperscan = ["hyperscan (>=0.7)"]
|
||||||
|
optional = ["typing-extensions (>=4)"]
|
||||||
|
re2 = ["google-re2 (>=1.1)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pexpect"
|
name = "pexpect"
|
||||||
version = "4.9.0"
|
version = "4.9.0"
|
||||||
@@ -408,6 +612,42 @@ files = [
|
|||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
wcwidth = "*"
|
wcwidth = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "psutil"
|
||||||
|
version = "7.2.2"
|
||||||
|
description = "Cross-platform lib for process and system monitoring."
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
groups = ["dev"]
|
||||||
|
markers = "sys_platform != \"emscripten\" and sys_platform != \"cygwin\""
|
||||||
|
files = [
|
||||||
|
{file = "psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b"},
|
||||||
|
{file = "psutil-7.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea"},
|
||||||
|
{file = "psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63"},
|
||||||
|
{file = "psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312"},
|
||||||
|
{file = "psutil-7.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b"},
|
||||||
|
{file = "psutil-7.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9"},
|
||||||
|
{file = "psutil-7.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00"},
|
||||||
|
{file = "psutil-7.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9"},
|
||||||
|
{file = "psutil-7.2.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a"},
|
||||||
|
{file = "psutil-7.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf"},
|
||||||
|
{file = "psutil-7.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1"},
|
||||||
|
{file = "psutil-7.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841"},
|
||||||
|
{file = "psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486"},
|
||||||
|
{file = "psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979"},
|
||||||
|
{file = "psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9"},
|
||||||
|
{file = "psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e"},
|
||||||
|
{file = "psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8"},
|
||||||
|
{file = "psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc"},
|
||||||
|
{file = "psutil-7.2.2-cp37-abi3-win_amd64.whl", hash = "sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988"},
|
||||||
|
{file = "psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee"},
|
||||||
|
{file = "psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["abi3audit", "black", "check-manifest", "colorama ; os_name == \"nt\"", "coverage", "packaging", "psleak", "pylint", "pyperf", "pypinfo", "pyreadline3 ; os_name == \"nt\"", "pytest", "pytest-cov", "pytest-instafail", "pytest-xdist", "pywin32 ; os_name == \"nt\" and implementation_name != \"pypy\"", "requests", "rstcheck", "ruff", "setuptools", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "validate-pyproject[all]", "virtualenv", "vulture", "wheel", "wheel ; os_name == \"nt\" and implementation_name != \"pypy\"", "wmi ; os_name == \"nt\" and implementation_name != \"pypy\""]
|
||||||
|
test = ["psleak", "pytest", "pytest-instafail", "pytest-xdist", "pywin32 ; os_name == \"nt\" and implementation_name != \"pypy\"", "setuptools", "wheel ; os_name == \"nt\" and implementation_name != \"pypy\"", "wmi ; os_name == \"nt\" and implementation_name != \"pypy\""]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ptyprocess"
|
name = "ptyprocess"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@@ -523,18 +763,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 +777,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 = "4bb5001f3c3cd2a3ab45ada4dc6c408703d1c309a499afde1845922ed792d59a"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "hotpocket-apple"
|
name = "hotpocket-apple"
|
||||||
version = "25.10.21"
|
version = "26.8.20"
|
||||||
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,17 +8,16 @@ 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.16.1"
|
||||||
isort = "7.0.0"
|
isort = "8.0.1"
|
||||||
mypy = "1.18.2"
|
mypy = "2.3.1"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core"]
|
requires = ["poetry-core"]
|
||||||
|
|||||||
@@ -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-20260818-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-20260818-01 AS deployment-build
|
||||||
|
|
||||||
ARG APP_USER_UID
|
ARG APP_USER_UID
|
||||||
ARG APP_USER_GID
|
ARG APP_USER_GID
|
||||||
@@ -25,13 +27,13 @@ COPY --chown=$APP_USER_UID:$APP_USER_GID packages/common/ /srv/packages/common/
|
|||||||
COPY --chown=$APP_USER_UID:$APP_USER_GID packages/soa/ /srv/packages/soa/
|
COPY --chown=$APP_USER_UID:$APP_USER_GID packages/soa/ /srv/packages/soa/
|
||||||
|
|
||||||
RUN poetry install --only main,deployment && \
|
RUN poetry install --only main,deployment && \
|
||||||
minify -i --css-precision 0 --js-precision 0 --js-version 2022 hotpocket_backend/apps/ui/static/ui/css/hotpocket-backend*.css hotpocket_backend/apps/ui/static/ui/js/hotpocket*.js && \
|
minify -i --css-precision 0 --js-precision 0 --js-version 2022 hotpocket_backend/apps/ui/static/ui/css/hotpocket-backend*.css hotpocket_backend/apps/ui/static/ui/js/hotpocket-backend*.js && \
|
||||||
./manage.py collectstatic --settings hotpocket_backend.settings.deployment.build --noinput && \
|
./manage.py collectstatic --settings hotpocket_backend.settings.deployment.build --noinput && \
|
||||||
find hotpocket_backend/static/ -name "*.map*" -delete && \
|
find hotpocket_backend/static/ -name "*.map*" -delete && \
|
||||||
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-20260818-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 = '26.8.20'
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
from .access_token import AccessToken # noqa: F401
|
from .access_token import AccessToken # noqa: F401
|
||||||
from .account import AccountAdmin # noqa: F401
|
from .account import AccountAdmin # noqa: F401
|
||||||
|
from .auth_key import AuthKey # noqa: F401
|
||||||
|
|||||||
@@ -2,16 +2,41 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from hotpocket_backend.apps.accounts.models import AccessToken
|
from hotpocket_backend.apps.accounts.models import AccessToken
|
||||||
|
|
||||||
|
|
||||||
class AccessTokenAdmin(admin.ModelAdmin):
|
class AccessTokenAdmin(admin.ModelAdmin):
|
||||||
list_display = ('pk', 'account_uuid', 'origin', 'created_at', 'is_active')
|
list_display = (
|
||||||
|
'pk', 'account_uuid', 'origin', 'created_at', 'render_is_active',
|
||||||
|
)
|
||||||
search_fields = ('pk', 'account_uuid', 'key', 'origin')
|
search_fields = ('pk', 'account_uuid', 'key', 'origin')
|
||||||
|
readonly_fields = (
|
||||||
|
'pk',
|
||||||
|
'account_uuid',
|
||||||
|
'key',
|
||||||
|
'origin',
|
||||||
|
'meta',
|
||||||
|
'created_at',
|
||||||
|
'deleted_at',
|
||||||
|
)
|
||||||
|
ordering = ['-created_at']
|
||||||
|
|
||||||
|
def has_change_permission(self, request, obj=None):
|
||||||
|
return False
|
||||||
|
|
||||||
def has_delete_permission(self, request, obj=None):
|
def has_delete_permission(self, request, obj=None):
|
||||||
return request.user.is_superuser
|
return request.user.is_superuser
|
||||||
|
|
||||||
|
@admin.display(
|
||||||
|
description=_('Is Active?'), boolean=True, ordering='-deleted_at',
|
||||||
|
)
|
||||||
|
def render_is_active(self, obj: AccessToken | None = None) -> bool | None:
|
||||||
|
if obj is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return obj.is_active
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(AccessToken, AccessTokenAdmin)
|
admin.site.register(AccessToken, AccessTokenAdmin)
|
||||||
|
|||||||
@@ -3,15 +3,26 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.contrib.auth.admin import UserAdmin
|
from django.contrib.auth.admin import UserAdmin
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from hotpocket_backend.apps.accounts.models import Account
|
from hotpocket_backend.apps.accounts.models import Account
|
||||||
|
|
||||||
|
|
||||||
class AccountAdmin(UserAdmin):
|
class AccountAdmin(UserAdmin):
|
||||||
list_display = (*UserAdmin.list_display, 'is_active')
|
list_display = (*UserAdmin.list_display, 'render_is_active')
|
||||||
|
ordering = ['username']
|
||||||
|
|
||||||
def has_delete_permission(self, request, obj=None):
|
def has_delete_permission(self, request, obj=None):
|
||||||
return request.user.is_superuser
|
return request.user.is_superuser
|
||||||
|
|
||||||
|
@admin.display(
|
||||||
|
description=_('Is Active?'), boolean=True, ordering='-is_active',
|
||||||
|
)
|
||||||
|
def render_is_active(self, obj: Account | None = None) -> bool | None:
|
||||||
|
if obj is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return obj.is_active
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Account, AccountAdmin)
|
admin.site.register(Account, AccountAdmin)
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from hotpocket_backend.apps.accounts.models import AuthKey
|
||||||
|
|
||||||
|
|
||||||
|
class AuthKeyAdmin(admin.ModelAdmin):
|
||||||
|
list_display = (
|
||||||
|
'pk', 'account_uuid', 'key', 'created_at', 'consumed_at', 'render_is_active',
|
||||||
|
)
|
||||||
|
search_fields = ('pk', 'account_uuid', 'key')
|
||||||
|
readonly_fields = (
|
||||||
|
'pk',
|
||||||
|
'account_uuid',
|
||||||
|
'key',
|
||||||
|
'consumed_at',
|
||||||
|
'created_at',
|
||||||
|
'deleted_at',
|
||||||
|
)
|
||||||
|
ordering = ['-created_at']
|
||||||
|
|
||||||
|
def has_change_permission(self, request, obj=None):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def has_delete_permission(self, request, obj=None):
|
||||||
|
return request.user.is_superuser
|
||||||
|
|
||||||
|
@admin.display(
|
||||||
|
description=_('Is Active?'), boolean=True, ordering='-deleted_at',
|
||||||
|
)
|
||||||
|
def render_is_active(self, obj: AuthKey | None = None) -> bool | None:
|
||||||
|
if obj is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return obj.is_active
|
||||||
|
|
||||||
|
|
||||||
|
admin.site.register(AuthKey, AuthKeyAdmin)
|
||||||
@@ -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
@@ -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,
|
||||||
|
)
|
||||||