mirror of
https://github.com/suitenumerique/meet.git
synced 2026-07-27 20:29:09 +00:00
Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ca6abed0fc | |||
| b6daa6d53f | |||
| 15133f9d6b | |||
| bea1f18ab8 | |||
| d5a614d2b5 | |||
| 108db2e3e5 | |||
| 73496406e8 | |||
| c5c96369c8 | |||
| e9f90e95b1 | |||
| f57fbf2d35 | |||
| 920f4558fc | |||
| 9df901b9d6 | |||
| c09c440631 | |||
| cd7ce77074 | |||
| 6d3c26419d | |||
| 9dbc38984e | |||
| 1bd5a294e4 | |||
| 4d98ed4977 | |||
| bf32c073c6 | |||
| 4f2c4bfaf9 | |||
| dacf705329 | |||
| 8296738347 | |||
| 04be495351 | |||
| 43185605eb | |||
| cf3fb208e2 | |||
| 4ca230eb12 | |||
| 4b5e0cb2a3 | |||
| 45f374610f | |||
| b419a2bfd2 | |||
| ee8d96bee7 | |||
| c65ff2d75d | |||
| ea1c90d8ca | |||
| 3e963e3e6d | |||
| 82769128a1 | |||
| 05f4ce6b2e | |||
| 508984ecfa | |||
| a05507f73d | |||
| a27def119c | |||
| fce94f38ce | |||
| 83bd9c5ce3 | |||
| bfbfade99a | |||
| 16daf7b8d3 | |||
| fcad79d662 | |||
| 2424ce17ec | |||
| 4715905334 | |||
| 7c05aedcfe | |||
| 7347fc7c86 | |||
| ada7d9a666 | |||
| 0cb3fb8e3c | |||
| dcb788b57b | |||
| 73bcb9d598 |
@@ -12,6 +12,9 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- 'main'
|
- 'main'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
env:
|
env:
|
||||||
DOCKER_USER: 1001:127
|
DOCKER_USER: 1001:127
|
||||||
DOCKER_CONTAINER_REGISTRY_HOSTNAME: docker.io
|
DOCKER_CONTAINER_REGISTRY_HOSTNAME: docker.io
|
||||||
@@ -20,6 +23,8 @@ env:
|
|||||||
jobs:
|
jobs:
|
||||||
build-and-push-backend:
|
build-and-push-backend:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout repository
|
name: Checkout repository
|
||||||
@@ -43,12 +48,12 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKER_HUB_USER }}
|
username: ${{ secrets.DOCKER_HUB_USER }}
|
||||||
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
||||||
# -
|
-
|
||||||
# name: Run trivy scan
|
name: Run trivy scan
|
||||||
# uses: numerique-gouv/action-trivy-cache@main
|
uses: numerique-gouv/action-trivy-cache@main
|
||||||
# with:
|
with:
|
||||||
# docker-build-args: '--target backend-production -f Dockerfile'
|
docker-build-args: '--target backend-production -f Dockerfile'
|
||||||
# docker-image-name: '${{ env.DOCKER_CONTAINER_REGISTRY_HOSTNAME }}/${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-backend:${{ github.sha }}'
|
docker-image-name: '${{ env.DOCKER_CONTAINER_REGISTRY_HOSTNAME }}/${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-backend:${{ github.sha }}'
|
||||||
-
|
-
|
||||||
name: Build and push
|
name: Build and push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
@@ -63,6 +68,8 @@ jobs:
|
|||||||
|
|
||||||
build-and-push-frontend-generic:
|
build-and-push-frontend-generic:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout repository
|
name: Checkout repository
|
||||||
@@ -86,12 +93,12 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKER_HUB_USER }}
|
username: ${{ secrets.DOCKER_HUB_USER }}
|
||||||
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
||||||
# -
|
-
|
||||||
# name: Run trivy scan
|
name: Run trivy scan
|
||||||
# uses: numerique-gouv/action-trivy-cache@main
|
uses: numerique-gouv/action-trivy-cache@main
|
||||||
# with:
|
with:
|
||||||
# docker-build-args: '-f src/frontend/Dockerfile --target frontend-production'
|
docker-build-args: '-f src/frontend/Dockerfile --target frontend-production'
|
||||||
# docker-image-name: '${{ env.DOCKER_CONTAINER_REGISTRY_HOSTNAME }}/${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-frontend:${{ github.sha }}'
|
docker-image-name: '${{ env.DOCKER_CONTAINER_REGISTRY_HOSTNAME }}/${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-frontend:${{ github.sha }}'
|
||||||
-
|
-
|
||||||
name: Build and push
|
name: Build and push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
@@ -107,6 +114,8 @@ jobs:
|
|||||||
|
|
||||||
build-and-push-frontend-dinum:
|
build-and-push-frontend-dinum:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout repository
|
name: Checkout repository
|
||||||
@@ -130,12 +139,12 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKER_HUB_USER }}
|
username: ${{ secrets.DOCKER_HUB_USER }}
|
||||||
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
||||||
# -
|
-
|
||||||
# name: Run trivy scan
|
name: Run trivy scan
|
||||||
# uses: numerique-gouv/action-trivy-cache@main
|
uses: numerique-gouv/action-trivy-cache@main
|
||||||
# with:
|
with:
|
||||||
# docker-build-args: '-f docker/dinum-frontend/Dockerfile --target frontend-production'
|
docker-build-args: '-f docker/dinum-frontend/Dockerfile --target frontend-production'
|
||||||
# docker-image-name: '${{ env.DOCKER_CONTAINER_REGISTRY_HOSTNAME }}/${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-frontend-dinum:${{ github.sha }}'
|
docker-image-name: '${{ env.DOCKER_CONTAINER_REGISTRY_HOSTNAME }}/${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-frontend-dinum:${{ github.sha }}'
|
||||||
-
|
-
|
||||||
name: Build and push
|
name: Build and push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
@@ -151,6 +160,8 @@ jobs:
|
|||||||
|
|
||||||
build-and-push-summary:
|
build-and-push-summary:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout repository
|
name: Checkout repository
|
||||||
@@ -174,13 +185,13 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKER_HUB_USER }}
|
username: ${{ secrets.DOCKER_HUB_USER }}
|
||||||
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
||||||
# -
|
-
|
||||||
# name: Run trivy scan
|
name: Run trivy scan
|
||||||
# uses: numerique-gouv/action-trivy-cache@main
|
uses: numerique-gouv/action-trivy-cache@main
|
||||||
# continue-on-error: true
|
continue-on-error: true
|
||||||
# with:
|
with:
|
||||||
# docker-build-args: '-f src/summary/Dockerfile --target production'
|
docker-build-args: '-f src/summary/Dockerfile --target production'
|
||||||
# docker-image-name: '${{ env.DOCKER_CONTAINER_REGISTRY_HOSTNAME }}/${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-summary:${{ github.sha }}'
|
docker-image-name: '${{ env.DOCKER_CONTAINER_REGISTRY_HOSTNAME }}/${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-summary:${{ github.sha }}'
|
||||||
docker-context: './src/summary'
|
docker-context: './src/summary'
|
||||||
-
|
-
|
||||||
name: Build and push
|
name: Build and push
|
||||||
@@ -197,6 +208,8 @@ jobs:
|
|||||||
|
|
||||||
build-and-push-agents:
|
build-and-push-agents:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout repository
|
name: Checkout repository
|
||||||
@@ -220,14 +233,14 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKER_HUB_USER }}
|
username: ${{ secrets.DOCKER_HUB_USER }}
|
||||||
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
||||||
# -
|
-
|
||||||
# name: Run trivy scan
|
name: Run trivy scan
|
||||||
# uses: numerique-gouv/action-trivy-cache@main
|
uses: numerique-gouv/action-trivy-cache@main
|
||||||
# continue-on-error: true
|
continue-on-error: true
|
||||||
# with:
|
with:
|
||||||
# docker-build-args: '-f src/agents/Dockerfile --target production'
|
docker-build-args: '-f src/agents/Dockerfile --target production'
|
||||||
# docker-image-name: '${{ env.DOCKER_CONTAINER_REGISTRY_HOSTNAME }}/${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-agents:${{ github.sha }}'
|
docker-image-name: '${{ env.DOCKER_CONTAINER_REGISTRY_HOSTNAME }}/${{ env.DOCKER_CONTAINER_REGISTRY_NAMESPACE }}/meet-agents:${{ github.sha }}'
|
||||||
# docker-context: './src/agents'
|
docker-context: './src/agents'
|
||||||
-
|
-
|
||||||
name: Build and push
|
name: Build and push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
@@ -242,6 +255,8 @@ jobs:
|
|||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|
||||||
notify-argocd:
|
notify-argocd:
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
needs:
|
needs:
|
||||||
- build-and-push-frontend-generic
|
- build-and-push-frontend-generic
|
||||||
- build-and-push-frontend-dinum
|
- build-and-push-frontend-dinum
|
||||||
|
|||||||
@@ -297,6 +297,46 @@ jobs:
|
|||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: uv run pytest -n 2
|
run: uv run pytest -n 2
|
||||||
|
|
||||||
|
test-summary:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: src/summary
|
||||||
|
|
||||||
|
env:
|
||||||
|
APP_API_TOKEN: "test-api-token"
|
||||||
|
AWS_STORAGE_BUCKET_NAME: "http://meet-media-storage"
|
||||||
|
AWS_S3_ENDPOINT_URL: "minio:9000"
|
||||||
|
AWS_S3_ACCESS_KEY_ID: "meet"
|
||||||
|
AWS_S3_SECRET_ACCESS_KEY: "password"
|
||||||
|
WHISPERX_BASE_URL: "https://configure-your-url.com"
|
||||||
|
WHISPERX_ASR_MODEL: "large-v2"
|
||||||
|
WHISPERX_API_KEY: "test-whisperx-secret"
|
||||||
|
WHISPERX_DEFAULT_LANGUAGE: "fr"
|
||||||
|
LLM_BASE_URL: "https://configure-your-url.com"
|
||||||
|
LLM_API_KEY: "test-llm-secret"
|
||||||
|
LLM_MODEL: "test-llm-model"
|
||||||
|
WEBHOOK_API_TOKEN: "test-webhook-secret"
|
||||||
|
WEBHOOK_URL: "https://configure-your-url.com"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Install Python
|
||||||
|
uses: actions/setup-python@v6
|
||||||
|
with:
|
||||||
|
python-version: "3.13"
|
||||||
|
cache: "pip"
|
||||||
|
|
||||||
|
- name: Install development dependencies
|
||||||
|
run: pip install --user .[dev]
|
||||||
|
|
||||||
|
- name: Run summary tests
|
||||||
|
run: ~/.local/bin/pytest
|
||||||
|
|
||||||
lint-front:
|
lint-front:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
|
|||||||
+44
-2
@@ -8,6 +8,42 @@ and this project adheres to
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- ⬆️(dependencies) update python dependencies
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- ⚡️(helm) Add pod and container securityContext #4805
|
||||||
|
- 🔒️(backend) fix email disclosure in room invitation endpoint #1200
|
||||||
|
- 🐛(backend) fix regression in update-participant endpoint #1204
|
||||||
|
|
||||||
|
## [1.12.0] - 2026-03-24
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- ♻️(backend) configurable SESSION_ENGINE #1038 #1154
|
||||||
|
- ♿️(frontend) fix sidepanel accessibility aria-label #1182
|
||||||
|
- ♿️(frontend) fix more tools heading hierarchy #1181
|
||||||
|
- ♿️(fronted) improve button descriptions for More tools actions #1184
|
||||||
|
- 💄(spinner) enforce spinner height #1183
|
||||||
|
- 💄(custom-background) add upload indicator with preview #1183
|
||||||
|
- ♿️(backend) improve logo accessibility in recording email notification #1092
|
||||||
|
- ♿️(summary) improve accessibility of transcription download link #1187
|
||||||
|
- 💄(frontend) show OS-specific shortcut in participant tile hint #1193
|
||||||
|
- ⬆️(frontend) bump flatted from 3.3.1 to 3.4.2 in /src/frontend #1188
|
||||||
|
- ⬆️️️(frontend) bump undici from 6.23.0 to 6.24.1 in /src/frontend
|
||||||
|
- ⬆️️️(frontend) bump hono from 4.12.2 to 4.12.7 in /src/frontend
|
||||||
|
- ⬆️️️(frontend) bump dompurify from 3.3.1 to 3.3.2 in /src/frontend
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- 🐛(frontend) disable personal custom background while deleting #1183
|
||||||
|
- 🐛(frontend) auto-select new custom background when not logged in #1183
|
||||||
|
- 🐛(frontend) fix device selection not applying during conference #1156
|
||||||
|
|
||||||
|
## [1.11.0] - 2026-03-19
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- ✨(helm) support celery with our Django backend #1124
|
- ✨(helm) support celery with our Django backend #1124
|
||||||
@@ -15,19 +51,24 @@ and this project adheres to
|
|||||||
- ✨(backend) add authenticated user rate throttling on request-entry #1129
|
- ✨(backend) add authenticated user rate throttling on request-entry #1129
|
||||||
- ✨(backend) expose `is_active` field for Application in Django admin #1133
|
- ✨(backend) expose `is_active` field for Application in Django admin #1133
|
||||||
- ✨(file-upload) disable by default & limit count by user #1141
|
- ✨(file-upload) disable by default & limit count by user #1141
|
||||||
|
- ✨(frontend) custom background #1067
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- ♿️(frontend) Caption text size setting for accessibility #1062
|
- ♿️(frontend) Caption text size setting for accessibility #1062
|
||||||
- ♿️(frontend) sync html lang attribute with i18n for screen readers #1111
|
- ♿️(frontend) sync html lang attribute with i18n for screen readers #1111
|
||||||
- ♿️(frontend) improve MoreLink a11y and UX on home page #1112
|
- ♿️(frontend) improve MoreLink a11y and UX on home page #1112
|
||||||
- ♿(frontend) improve chat toast a11y for screen readers #1109
|
- ♿️(frontend) improve chat toast a11y for screen readers #1109
|
||||||
- ♿(frontend) improve ui and aria labels for help article links #1108
|
- ♿️(frontend) improve ui and aria labels for help article links #1108
|
||||||
- 🌐(frontend) improve German translation #1125
|
- 🌐(frontend) improve German translation #1125
|
||||||
- 🔨(python-env) migrate meet main app to UV #1120
|
- 🔨(python-env) migrate meet main app to UV #1120
|
||||||
- ♻️(backend) align Application model field with `is_active` convention #1133
|
- ♻️(backend) align Application model field with `is_active` convention #1133
|
||||||
- 🔐(backend) avoids revealing the inactive status of an application #1135
|
- 🔐(backend) avoids revealing the inactive status of an application #1135
|
||||||
- ⚡️(helm) reduce initialDelaySeconds and add periods seconds #1139
|
- ⚡️(helm) reduce initialDelaySeconds and add periods seconds #1139
|
||||||
|
- 🔒️(backend) avoid information exposure through exception messages #1144
|
||||||
|
- ⬆️(dependencies) update PyJWT to v2.12.0 [SECURITY] #1151
|
||||||
|
- 📌(agents) unpin OpenSSL and related dependencies #1167
|
||||||
|
- ♿️(frontend) add caption font and background color customization #1122
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
@@ -35,6 +76,7 @@ and this project adheres to
|
|||||||
- 🩹(backend) add page_size to pagination for room endpoints #1131
|
- 🩹(backend) add page_size to pagination for room endpoints #1131
|
||||||
- 🐛(backend) refactor lobby throttling to use participant id #1129
|
- 🐛(backend) refactor lobby throttling to use participant id #1129
|
||||||
- 🩹(backend) ignore non-recording uploads in storage webhook handler #1142
|
- 🩹(backend) ignore non-recording uploads in storage webhook handler #1142
|
||||||
|
- 🐛(frontend) fix dimension mismatch in BackgroundCustomProcessor #1116
|
||||||
|
|
||||||
## [1.10.0] - 2026-03-05
|
## [1.10.0] - 2026-03-05
|
||||||
|
|
||||||
|
|||||||
@@ -191,6 +191,7 @@ lint-pylint: ## lint back-end python sources with pylint only on changed files f
|
|||||||
|
|
||||||
test: ## run project tests
|
test: ## run project tests
|
||||||
@$(MAKE) test-back-parallel
|
@$(MAKE) test-back-parallel
|
||||||
|
@$(MAKE) test-summary
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
|
|
||||||
test-back: ## run back-end tests
|
test-back: ## run back-end tests
|
||||||
@@ -203,6 +204,11 @@ test-back-parallel: ## run all back-end tests in parallel
|
|||||||
bin/pytest -n auto $${args:-${1}}
|
bin/pytest -n auto $${args:-${1}}
|
||||||
.PHONY: test-back-parallel
|
.PHONY: test-back-parallel
|
||||||
|
|
||||||
|
test-summary: ## run summary tests
|
||||||
|
@args="$(filter-out $@,$(MAKECMDGOALS))" && \
|
||||||
|
bin/pytest-summary $${args:-${1}}
|
||||||
|
.PHONY: test-summary
|
||||||
|
|
||||||
makemigrations: ## run django makemigrations for the Meet project.
|
makemigrations: ## run django makemigrations for the Meet project.
|
||||||
@echo "$(BOLD)Running makemigrations$(RESET)"
|
@echo "$(BOLD)Running makemigrations$(RESET)"
|
||||||
@$(COMPOSE) up -d postgresql
|
@$(COMPOSE) up -d postgresql
|
||||||
|
|||||||
Executable
+7
@@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
source "$(dirname "${BASH_SOURCE[0]}")/_config.sh"
|
||||||
|
|
||||||
|
_dc_run \
|
||||||
|
app-summary-dev \
|
||||||
|
python -m pytest "$@"
|
||||||
@@ -61,11 +61,10 @@ services:
|
|||||||
`docker compose up -d`
|
`docker compose up -d`
|
||||||
```
|
```
|
||||||
|
|
||||||
Your keycloak instance is now available on https://doc.yourdomain.tld
|
Your keycloak instance is now available on https://id.yourdomain.tld
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> Version of the images are set to latest, you should pin it to the desired version to avoid unwanted upgrades when pulling latest image. You can find available versions on [Keycloak registry](https://quay.io/repository/keycloak/keycloak?tab=tags).
|
> Version of the images are set to latest, you should pin it to the desired version to avoid unwanted upgrades when pulling latest image. You can find available versions on [Keycloak registry](https://quay.io/repository/keycloak/keycloak?tab=tags).
|
||||||
```
|
|
||||||
|
|
||||||
## Creating an OIDC Client for Meet Application
|
## Creating an OIDC Client for Meet Application
|
||||||
|
|
||||||
@@ -76,7 +75,7 @@ Your keycloak instance is now available on https://doc.yourdomain.tld
|
|||||||
3. Enter the name of the realm - `meet`.
|
3. Enter the name of the realm - `meet`.
|
||||||
4. Click "Create".
|
4. Click "Create".
|
||||||
|
|
||||||
#### Step 2: Create a New Client
|
### Step 2: Create a New Client
|
||||||
|
|
||||||
1. Navigate to the "Clients" tab.
|
1. Navigate to the "Clients" tab.
|
||||||
2. Click on the "Create client" button.
|
2. Click on the "Create client" button.
|
||||||
@@ -86,7 +85,7 @@ Your keycloak instance is now available on https://doc.yourdomain.tld
|
|||||||
1. Set the "Web Origins" to the URL of your meet application - e.g. `https://meet.example.com`.
|
1. Set the "Web Origins" to the URL of your meet application - e.g. `https://meet.example.com`.
|
||||||
1. Click "Save".
|
1. Click "Save".
|
||||||
|
|
||||||
#### Step 3: Get Client Credentials
|
### Step 3: Get Client Credentials
|
||||||
|
|
||||||
1. Go to the "Credentials" tab.
|
1. Go to the "Credentials" tab.
|
||||||
2. Copy the client ID (`meet` in this example) and the client secret.
|
2. Copy the client ID (`meet` in this example) and the client secret.
|
||||||
|
|||||||
@@ -190,6 +190,7 @@ paths:
|
|||||||
'403':
|
'403':
|
||||||
$ref: '#/components/responses/ForbiddenError'
|
$ref: '#/components/responses/ForbiddenError'
|
||||||
|
|
||||||
|
/rooms/:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
- Rooms
|
- Rooms
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ paths:
|
|||||||
'403':
|
'403':
|
||||||
$ref: '#/components/responses/ForbiddenError'
|
$ref: '#/components/responses/ForbiddenError'
|
||||||
|
|
||||||
|
/rooms/:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
- Rooms
|
- Rooms
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ AWS_S3_DOMAIN_REPLACE=http://localhost:9000
|
|||||||
AWS_S3_ENDPOINT_URL=http://minio:9000
|
AWS_S3_ENDPOINT_URL=http://minio:9000
|
||||||
AWS_S3_ACCESS_KEY_ID=meet
|
AWS_S3_ACCESS_KEY_ID=meet
|
||||||
AWS_S3_SECRET_ACCESS_KEY=password
|
AWS_S3_SECRET_ACCESS_KEY=password
|
||||||
MEDIA_BASE_URL=http://localhost:8083
|
MEDIA_BASE_URL=http://localhost:3000
|
||||||
FILE_UPLOAD_ENABLED=True
|
FILE_UPLOAD_ENABLED=True
|
||||||
|
|
||||||
# OIDC
|
# OIDC
|
||||||
|
|||||||
@@ -36,6 +36,12 @@
|
|||||||
"matchPackageNames": ["django"],
|
"matchPackageNames": ["django"],
|
||||||
"allowedVersions": "<6.0.0"
|
"allowedVersions": "<6.0.0"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"groupName": "allowed brevo versions",
|
||||||
|
"matchManagers": ["pep621"],
|
||||||
|
"matchPackageNames": ["brevo-python"],
|
||||||
|
"allowedVersions": "<3.0.0"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"groupName": "ignored js dependencies",
|
"groupName": "ignored js dependencies",
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ FROM python:3.13-slim AS base
|
|||||||
RUN apt-get update && apt-get install -y \
|
RUN apt-get update && apt-get install -y \
|
||||||
libglib2.0-0 \
|
libglib2.0-0 \
|
||||||
libgobject-2.0-0 \
|
libgobject-2.0-0 \
|
||||||
"openssl=3.5.4-1~deb13u2" \
|
|
||||||
"libssl3t64=3.5.4-1~deb13u2" \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
FROM base AS builder
|
FROM base AS builder
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "agents"
|
name = "agents"
|
||||||
version = "1.10.0"
|
version = "1.12.0"
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"livekit-agents==1.3.10",
|
"livekit-agents==1.4.5",
|
||||||
"livekit-plugins-deepgram==1.3.10",
|
"livekit-plugins-deepgram==1.4.5",
|
||||||
"livekit-plugins-silero==1.3.10",
|
"livekit-plugins-silero==1.4.5",
|
||||||
"livekit-plugins-kyutai-lasuite==0.0.6",
|
"livekit-plugins-kyutai-lasuite==0.0.6",
|
||||||
"python-dotenv==1.2.1",
|
"python-dotenv==1.2.2",
|
||||||
"protobuf==6.33.5"
|
"protobuf==6.33.5"
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
dev = [
|
dev = [
|
||||||
"ruff==0.14.4",
|
"ruff==0.15.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
|
|||||||
@@ -303,6 +303,9 @@ class MuteParticipantSerializer(BaseParticipantsManagementSerializer):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
TrackSource = Literal["SCREEN_SHARE", "SCREEN_SHARE_AUDIO", "CAMERA", "MICROPHONE"]
|
||||||
|
|
||||||
|
|
||||||
class ParticipantPermission(BaseModel):
|
class ParticipantPermission(BaseModel):
|
||||||
"""Mirror the LiveKit ParticipantPermission protobuf.
|
"""Mirror the LiveKit ParticipantPermission protobuf.
|
||||||
|
|
||||||
@@ -313,9 +316,7 @@ class ParticipantPermission(BaseModel):
|
|||||||
can_subscribe: bool | None = None
|
can_subscribe: bool | None = None
|
||||||
can_publish: bool | None = None
|
can_publish: bool | None = None
|
||||||
can_publish_data: bool | None = None
|
can_publish_data: bool | None = None
|
||||||
can_publish_sources: list[int] = Field(
|
can_publish_sources: list[TrackSource] = Field(default_factory=list)
|
||||||
default_factory=list
|
|
||||||
) # TrackSource enum values
|
|
||||||
hidden: bool | None = None
|
hidden: bool | None = None
|
||||||
recorder: bool | None = None
|
recorder: bool | None = None
|
||||||
can_update_metadata: bool | None = None
|
can_update_metadata: bool | None = None
|
||||||
@@ -366,14 +367,6 @@ class UpdateParticipantSerializer(BaseParticipantsManagementSerializer):
|
|||||||
f"Setting the following participant permissions is not allowed: "
|
f"Setting the following participant permissions is not allowed: "
|
||||||
f"{', '.join(suspicious_fields)}."
|
f"{', '.join(suspicious_fields)}."
|
||||||
)
|
)
|
||||||
if permission.can_subscribe_metrics is not None:
|
|
||||||
raise serializers.ValidationError(
|
|
||||||
{
|
|
||||||
"permission": {
|
|
||||||
"can_subscribe_metrics": "This permission is not implemented."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
return permission
|
return permission
|
||||||
|
|
||||||
|
|||||||
@@ -488,9 +488,7 @@ class RoomViewSet(
|
|||||||
if status_code == drf_status.HTTP_500_INTERNAL_SERVER_ERROR:
|
if status_code == drf_status.HTTP_500_INTERNAL_SERVER_ERROR:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
return drf_response.Response(
|
return drf_response.Response({"status": "error"}, status=status_code)
|
||||||
{"status": "error", "message": str(e)}, status=status_code
|
|
||||||
)
|
|
||||||
|
|
||||||
@decorators.action(
|
@decorators.action(
|
||||||
detail=False,
|
detail=False,
|
||||||
@@ -757,10 +755,10 @@ class RecordingViewSet(
|
|||||||
recording_id = parser.get_recording_id(request.data)
|
recording_id = parser.get_recording_id(request.data)
|
||||||
|
|
||||||
except ParsingEventDataError as e:
|
except ParsingEventDataError as e:
|
||||||
raise drf_exceptions.PermissionDenied(f"Invalid request data: {e}") from e
|
raise drf_exceptions.PermissionDenied("Invalid request data.") from e
|
||||||
|
|
||||||
except InvalidBucketError as e:
|
except InvalidBucketError as e:
|
||||||
raise drf_exceptions.PermissionDenied("Invalid bucket specified") from e
|
raise drf_exceptions.PermissionDenied("Invalid bucket specified.") from e
|
||||||
|
|
||||||
except InvalidFilepathError:
|
except InvalidFilepathError:
|
||||||
return drf_response.Response(
|
return drf_response.Response(
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ FILE_EXT_REGEX = r"[a-zA-Z0-9]{1,10}"
|
|||||||
|
|
||||||
# pylint: disable=line-too-long
|
# pylint: disable=line-too-long
|
||||||
RECORDING_STORAGE_URL_PATTERN = re.compile(
|
RECORDING_STORAGE_URL_PATTERN = re.compile(
|
||||||
f"{settings.MEDIA_URL:s}{settings.RECORDING_OUTPUT_FOLDER}/(?P<recording_id>{UUID_REGEX:s}).(?P<extension>{FILE_EXT_REGEX:s})"
|
rf"{settings.MEDIA_URL:s}{settings.RECORDING_OUTPUT_FOLDER}/(?P<recording_id>{UUID_REGEX:s})\.(?P<extension>{FILE_EXT_REGEX:s})"
|
||||||
)
|
)
|
||||||
|
|
||||||
MEDIA_STORAGE_URL_PATTERN = re.compile(
|
MEDIA_STORAGE_URL_PATTERN = re.compile(
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import smtplib
|
|||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.mail import send_mail
|
from django.core.mail import EmailMultiAlternatives
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.utils.translation import get_language, override
|
from django.utils.translation import get_language, override
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
@@ -45,15 +45,18 @@ class InvitationService:
|
|||||||
)
|
)
|
||||||
) # Force translation
|
) # Force translation
|
||||||
|
|
||||||
|
email = EmailMultiAlternatives(
|
||||||
|
subject=subject,
|
||||||
|
body=msg_plain,
|
||||||
|
from_email=settings.EMAIL_FROM,
|
||||||
|
to=[],
|
||||||
|
bcc=emails,
|
||||||
|
)
|
||||||
|
|
||||||
|
email.attach_alternative(msg_html, "text/html")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
send_mail(
|
email.send()
|
||||||
subject,
|
|
||||||
msg_plain,
|
|
||||||
settings.EMAIL_FROM,
|
|
||||||
emails,
|
|
||||||
html_message=msg_html,
|
|
||||||
fail_silently=False,
|
|
||||||
)
|
|
||||||
except smtplib.SMTPException as e:
|
except smtplib.SMTPException as e:
|
||||||
logger.error("invitation to %s was not sent: %s", emails, e)
|
logger.error("invitations were not sent: %s", e)
|
||||||
raise InvitationError("Could not send invitation") from e
|
raise InvitationError("Could not send invitation") from e
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ def test_save_recording_parsing_error(recording_settings, mock_get_parser, clien
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert response.status_code == 403
|
assert response.status_code == 403
|
||||||
assert response.json() == {"detail": "Invalid request data: Error message"}
|
assert response.json() == {"detail": "Invalid request data."}
|
||||||
|
|
||||||
|
|
||||||
def test_save_recording_bucket_error(recording_settings, mock_get_parser, client):
|
def test_save_recording_bucket_error(recording_settings, mock_get_parser, client):
|
||||||
@@ -112,7 +112,7 @@ def test_save_recording_bucket_error(recording_settings, mock_get_parser, client
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert response.status_code == 403
|
assert response.status_code == 403
|
||||||
assert response.json() == {"detail": "Invalid bucket specified"}
|
assert response.json() == {"detail": "Invalid bucket specified."}
|
||||||
|
|
||||||
|
|
||||||
def test_save_recording_filetype_error(recording_settings, mock_get_parser):
|
def test_save_recording_filetype_error(recording_settings, mock_get_parser):
|
||||||
|
|||||||
@@ -240,10 +240,9 @@ def test_api_rooms_invite_error(mock_invite_to_room):
|
|||||||
mock_invite_to_room.assert_called_once()
|
mock_invite_to_room.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
@mock.patch("core.services.invitation.send_mail")
|
@mock.patch("core.services.invitation.EmailMultiAlternatives")
|
||||||
def test_api_rooms_invite_success(mock_send_mail, settings):
|
def test_api_rooms_invite_success(mock_email_class, settings):
|
||||||
"""Test privileged users should successfully send invitation emails."""
|
"""Test privileged users should successfully send invitation emails."""
|
||||||
|
|
||||||
settings.EMAIL_BRAND_NAME = "ACME"
|
settings.EMAIL_BRAND_NAME = "ACME"
|
||||||
settings.EMAIL_LOGO_IMG = "https://acme.com/logo"
|
settings.EMAIL_LOGO_IMG = "https://acme.com/logo"
|
||||||
settings.EMAIL_APP_BASE_URL = "https://acme.com"
|
settings.EMAIL_APP_BASE_URL = "https://acme.com"
|
||||||
@@ -255,7 +254,6 @@ def test_api_rooms_invite_success(mock_send_mail, settings):
|
|||||||
user = UserFactory()
|
user = UserFactory()
|
||||||
|
|
||||||
room.accesses.create(user=user, role=random.choice(["administrator", "owner"]))
|
room.accesses.create(user=user, role=random.choice(["administrator", "owner"]))
|
||||||
|
|
||||||
client.force_login(user)
|
client.force_login(user)
|
||||||
|
|
||||||
data = {"emails": ["fabien@yopmail.com", "gerald@yopmail.com"]}
|
data = {"emails": ["fabien@yopmail.com", "gerald@yopmail.com"]}
|
||||||
@@ -269,26 +267,38 @@ def test_api_rooms_invite_success(mock_send_mail, settings):
|
|||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.json() == {"status": "success", "message": "invitations sent"}
|
assert response.json() == {"status": "success", "message": "invitations sent"}
|
||||||
|
|
||||||
mock_send_mail.assert_called_once()
|
mock_email_class.assert_called_once()
|
||||||
|
|
||||||
subject, body, sender, recipients = mock_send_mail.call_args[0]
|
# Check constructor arguments
|
||||||
|
call_kwargs = mock_email_class.call_args[1] # EmailMultiAlternatives(**kwargs)
|
||||||
|
|
||||||
assert (
|
assert call_kwargs["subject"] == (
|
||||||
subject == f"Video call in progress: {user.email} is waiting for you to connect"
|
f"Video call in progress: {user.email} is waiting for you to connect"
|
||||||
|
)
|
||||||
|
assert call_kwargs["from_email"] == "notifications@acme.com"
|
||||||
|
assert call_kwargs["to"] == []
|
||||||
|
assert sorted(call_kwargs["bcc"]) == sorted(
|
||||||
|
["fabien@yopmail.com", "gerald@yopmail.com"]
|
||||||
)
|
)
|
||||||
|
|
||||||
# Verify email contains expected content
|
# Check plain text body
|
||||||
|
plain_body = call_kwargs["body"]
|
||||||
required_content = [
|
required_content = [
|
||||||
"ACME", # Brand name
|
"ACME",
|
||||||
"https://acme.com/logo", # Logo URL
|
"https://acme.com/logo",
|
||||||
f"https://acme.com/{room.slug}", # Room url
|
f"https://acme.com/{room.slug}",
|
||||||
f"acme.com/{room.slug}", # Room link
|
f"acme.com/{room.slug}",
|
||||||
]
|
]
|
||||||
|
|
||||||
for content in required_content:
|
for content in required_content:
|
||||||
assert content in body
|
assert content in plain_body
|
||||||
|
|
||||||
assert sender == "notifications@acme.com"
|
# Check HTML alternative was attached
|
||||||
|
mock_instance = mock_email_class.return_value
|
||||||
|
mock_instance.attach_alternative.assert_called_once()
|
||||||
|
html_body, mimetype = mock_instance.attach_alternative.call_args[0]
|
||||||
|
assert mimetype == "text/html"
|
||||||
|
for content in required_content:
|
||||||
|
assert content in html_body
|
||||||
|
|
||||||
# Verify all owners received the email (order-independent comparison)
|
# Check send was called
|
||||||
assert sorted(recipients) == sorted(["fabien@yopmail.com", "gerald@yopmail.com"])
|
mock_instance.send.assert_called_once()
|
||||||
|
|||||||
@@ -130,10 +130,11 @@ def test_update_participant_success(mock_livekit_client):
|
|||||||
"can_publish": True,
|
"can_publish": True,
|
||||||
"can_publish_data": True,
|
"can_publish_data": True,
|
||||||
"can_publish_sources": [
|
"can_publish_sources": [
|
||||||
1,
|
"CAMERA",
|
||||||
2,
|
"MICROPHONE",
|
||||||
], # [TrackSource.CAMERA, TrackSource.MICROPHONE]
|
],
|
||||||
"can_update_metadata": True,
|
"can_update_metadata": True,
|
||||||
|
"can_subscribe_metrics": True,
|
||||||
},
|
},
|
||||||
"name": "John Doe",
|
"name": "John Doe",
|
||||||
}
|
}
|
||||||
@@ -155,8 +156,14 @@ def test_update_participant_success(mock_livekit_client):
|
|||||||
{"can_subscribe": True},
|
{"can_subscribe": True},
|
||||||
{"can_publish": True},
|
{"can_publish": True},
|
||||||
{"can_publish_data": True},
|
{"can_publish_data": True},
|
||||||
{"can_publish_sources": [1, 2]},
|
{
|
||||||
|
"can_publish_sources": [
|
||||||
|
"CAMERA",
|
||||||
|
"MICROPHONE",
|
||||||
|
]
|
||||||
|
},
|
||||||
{"can_update_metadata": True},
|
{"can_update_metadata": True},
|
||||||
|
{"can_subscribe_metrics": False},
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_update_participant_permission_fields_are_optional(
|
def test_update_participant_permission_fields_are_optional(
|
||||||
@@ -264,35 +271,6 @@ def test_update_participant_suspicious_permission_multiple(mock_suspicious):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("value", (False, True))
|
|
||||||
def test_update_participant_unimplemented_can_subscribe_metrics(value):
|
|
||||||
"""Test update participant raises 400 when can_subscribe_metrics is set."""
|
|
||||||
client = APIClient()
|
|
||||||
room = RoomFactory()
|
|
||||||
user = UserFactory()
|
|
||||||
UserResourceAccessFactory(
|
|
||||||
resource=room, user=user, role=random.choice(["administrator", "owner"])
|
|
||||||
)
|
|
||||||
client.force_authenticate(user=user)
|
|
||||||
|
|
||||||
payload = {
|
|
||||||
"participant_identity": str(uuid4()),
|
|
||||||
"permission": {
|
|
||||||
"can_subscribe": True,
|
|
||||||
"can_publish": True,
|
|
||||||
"can_publish_data": True,
|
|
||||||
"can_update_metadata": False,
|
|
||||||
"can_subscribe_metrics": value,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
url = reverse("rooms-update-participant", kwargs={"pk": room.id})
|
|
||||||
response = client.post(url, payload, format="json")
|
|
||||||
|
|
||||||
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
|
||||||
assert "can_subscribe_metrics" in str(response.data)
|
|
||||||
|
|
||||||
|
|
||||||
def test_update_participant_forbidden_without_access():
|
def test_update_participant_forbidden_without_access():
|
||||||
"""Test update participant returns 403 when user lacks room privileges."""
|
"""Test update participant returns 403 when user lacks room privileges."""
|
||||||
client = APIClient()
|
client = APIClient()
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ def test_missing_auth_header(client, serialized_event_data, mock_livekit_config)
|
|||||||
assert response.status_code == 401
|
assert response.status_code == 401
|
||||||
assert response.json() == {
|
assert response.json() == {
|
||||||
"status": "error",
|
"status": "error",
|
||||||
"message": "Authorization header missing",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -91,7 +90,7 @@ def test_invalid_payload(client, auth_token, mock_livekit_config):
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert response.status_code == 400
|
assert response.status_code == 400
|
||||||
assert response.json() == {"status": "error", "message": "Invalid webhook payload"}
|
assert response.json() == {"status": "error"}
|
||||||
|
|
||||||
|
|
||||||
def test_unknown_event_type(client, mock_livekit_config):
|
def test_unknown_event_type(client, mock_livekit_config):
|
||||||
@@ -116,7 +115,6 @@ def test_unknown_event_type(client, mock_livekit_config):
|
|||||||
assert response.status_code == 422
|
assert response.status_code == 422
|
||||||
assert response.json() == {
|
assert response.json() == {
|
||||||
"status": "error",
|
"status": "error",
|
||||||
"message": "Unknown webhook type: unknown_event_type",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -452,7 +452,11 @@ class Base(Configuration):
|
|||||||
CELERY_BROKER_TRANSPORT_OPTIONS = values.DictValue({}, environ_prefix=None)
|
CELERY_BROKER_TRANSPORT_OPTIONS = values.DictValue({}, environ_prefix=None)
|
||||||
|
|
||||||
# Session
|
# Session
|
||||||
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
|
SESSION_ENGINE = values.Value(
|
||||||
|
default="django.contrib.sessions.backends.cache",
|
||||||
|
environ_name="SESSION_ENGINE",
|
||||||
|
environ_prefix=None,
|
||||||
|
)
|
||||||
SESSION_CACHE_ALIAS = "default"
|
SESSION_CACHE_ALIAS = "default"
|
||||||
SESSION_COOKIE_AGE = values.PositiveIntegerValue(
|
SESSION_COOKIE_AGE = values.PositiveIntegerValue(
|
||||||
default=60 * 60 * 12, environ_name="SESSION_COOKIE_AGE", environ_prefix=None
|
default=60 * 60 * 12, environ_name="SESSION_COOKIE_AGE", environ_prefix=None
|
||||||
|
|||||||
+20
-15
@@ -7,7 +7,7 @@ build-backend = "uv_build"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "meet"
|
name = "meet"
|
||||||
version = "1.10.0"
|
version = "1.12.0"
|
||||||
authors = [{ "name" = "DINUM", "email" = "dev@mail.numerique.gouv.fr" }]
|
authors = [{ "name" = "DINUM", "email" = "dev@mail.numerique.gouv.fr" }]
|
||||||
classifiers = [
|
classifiers = [
|
||||||
"Development Status :: 5 - Production/Stable",
|
"Development Status :: 5 - Production/Stable",
|
||||||
@@ -24,16 +24,16 @@ keywords = ["Django", "Contacts", "Templates", "RBAC"]
|
|||||||
license = "MIT"
|
license = "MIT"
|
||||||
requires-python = ">=3.13"
|
requires-python = ">=3.13"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"boto3==1.42.49",
|
"boto3==1.42.68",
|
||||||
"Brotli==1.2.0",
|
"Brotli==1.2.0",
|
||||||
"brevo-python==1.2.0",
|
"brevo-python==1.2.0",
|
||||||
"celery[redis]==5.6.2",
|
"celery[redis]==5.6.2",
|
||||||
"dj-database-url==3.1.0",
|
"dj-database-url==3.1.2",
|
||||||
"django-configurations==2.5.1",
|
"django-configurations==2.5.1",
|
||||||
"django-cors-headers==4.9.0",
|
"django-cors-headers==4.9.0",
|
||||||
"django-countries==8.2.0",
|
"django-countries==8.2.0",
|
||||||
"django-filter==25.2",
|
"django-filter==25.2",
|
||||||
"django-lasuite[all]==0.0.24",
|
"django-lasuite[all]==0.0.25",
|
||||||
"django-parler==2.3",
|
"django-parler==2.3",
|
||||||
"redis==5.2.1",
|
"redis==5.2.1",
|
||||||
"django-redis==6.0.0",
|
"django-redis==6.0.0",
|
||||||
@@ -43,21 +43,21 @@ dependencies = [
|
|||||||
"django==5.2.12",
|
"django==5.2.12",
|
||||||
"djangorestframework==3.16.1",
|
"djangorestframework==3.16.1",
|
||||||
"drf_spectacular==0.29.0",
|
"drf_spectacular==0.29.0",
|
||||||
"dockerflow==2026.1.26",
|
"dockerflow==2026.3.4",
|
||||||
"easy_thumbnails==2.10.1",
|
"easy_thumbnails==2.10.1",
|
||||||
"factory_boy==3.3.3",
|
"factory_boy==3.3.3",
|
||||||
"gunicorn==25.1.0",
|
"gunicorn==25.1.0",
|
||||||
"jsonschema==4.26.0",
|
"jsonschema==4.26.0",
|
||||||
"markdown==3.10.2",
|
"markdown==3.10.2",
|
||||||
"nested-multipart-parser==1.6.0",
|
"nested-multipart-parser==1.6.0",
|
||||||
"psycopg[binary]==3.3.2",
|
"psycopg[binary]==3.3.3",
|
||||||
"pydantic==2.12.4",
|
"pydantic==2.12.5",
|
||||||
"PyJWT==2.11.0",
|
"PyJWT==2.12.1",
|
||||||
"python-frontmatter==1.1.0",
|
"python-frontmatter==1.1.0",
|
||||||
"python-magic==0.4.27",
|
"python-magic==0.4.27",
|
||||||
"requests==2.32.5",
|
"requests==2.32.5",
|
||||||
"sentry-sdk==2.53.0",
|
"sentry-sdk==2.54.0",
|
||||||
"whitenoise==6.11.0",
|
"whitenoise==6.12.0",
|
||||||
"mozilla-django-oidc==5.0.2",
|
"mozilla-django-oidc==5.0.2",
|
||||||
"livekit-api==1.1.0",
|
"livekit-api==1.1.0",
|
||||||
"aiohttp==3.13.3",
|
"aiohttp==3.13.3",
|
||||||
@@ -72,11 +72,11 @@ dependencies = [
|
|||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
dev = [
|
dev = [
|
||||||
"django-extensions==4.1",
|
"django-extensions==4.1",
|
||||||
"drf-spectacular-sidecar==2026.1.1",
|
"drf-spectacular-sidecar==2026.3.1",
|
||||||
"freezegun==1.5.5",
|
"freezegun==1.5.5",
|
||||||
"ipdb==0.13.13",
|
"ipdb==0.13.13",
|
||||||
"ipython==9.10.0",
|
"ipython==9.11.0",
|
||||||
"pyfakefs==6.1.1",
|
"pyfakefs==6.1.5",
|
||||||
"pylint-django==2.7.0",
|
"pylint-django==2.7.0",
|
||||||
"pylint<4.0.0",
|
"pylint<4.0.0",
|
||||||
"pytest-cov==7.0.0",
|
"pytest-cov==7.0.0",
|
||||||
@@ -84,12 +84,17 @@ dev = [
|
|||||||
"pytest==9.0.2",
|
"pytest==9.0.2",
|
||||||
"pytest-icdiff==0.9",
|
"pytest-icdiff==0.9",
|
||||||
"pytest-xdist==3.8.0",
|
"pytest-xdist==3.8.0",
|
||||||
"responses==0.25.8",
|
"responses==0.26.0",
|
||||||
"ruff==0.15.1",
|
"ruff==0.15.6",
|
||||||
"types-requests==2.32.4.20260107",
|
"types-requests==2.32.4.20260107",
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.uv.build-backend]
|
[tool.uv.build-backend]
|
||||||
|
module-name = [
|
||||||
|
"core",
|
||||||
|
"demo",
|
||||||
|
"meet"
|
||||||
|
]
|
||||||
module-root = ""
|
module-root = ""
|
||||||
source-exclude = [
|
source-exclude = [
|
||||||
"**/tests/**",
|
"**/tests/**",
|
||||||
|
|||||||
Generated
+99
-99
@@ -159,30 +159,30 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "boto3"
|
name = "boto3"
|
||||||
version = "1.42.49"
|
version = "1.42.68"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "botocore" },
|
{ name = "botocore" },
|
||||||
{ name = "jmespath" },
|
{ name = "jmespath" },
|
||||||
{ name = "s3transfer" },
|
{ name = "s3transfer" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/20/91/105aa17e0f3a566d33e2d8a3b32a70f553b1ad500d9756c6dd63991d8354/boto3-1.42.49.tar.gz", hash = "sha256:9cd252f640567b86e92b0a8ffdd4ade9a3018ee357c724bff6a21b8c8a41be0c", size = 112877, upload-time = "2026-02-13T20:29:57.062Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/06/ae/60c642aa5413e560b671da825329f510b29a77274ed0f580bde77562294d/boto3-1.42.68.tar.gz", hash = "sha256:3f349f967ab38c23425626d130962bcb363e75f042734fe856ea8c5a00eef03c", size = 112761, upload-time = "2026-03-13T19:32:17.137Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/12/b1/1fa30cd7b26617d59efbe3a4f3660a5b8b397a4623bf1e67016c4cb6dd0e/boto3-1.42.49-py3-none-any.whl", hash = "sha256:99e1df4361c3f6ff6ade65803c043ea96314826134962dd3b385433b309eb819", size = 140606, upload-time = "2026-02-13T20:29:55.366Z" },
|
{ url = "https://files.pythonhosted.org/packages/fb/f6/dc6e993479dbb597d68223fbf61cb026511737696b15bd7d2a33e9b2c24f/boto3-1.42.68-py3-none-any.whl", hash = "sha256:dbff353eb7dc93cbddd7926ed24793e0174c04adbe88860dfa639568442e4962", size = 140556, upload-time = "2026-03-13T19:32:14.951Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "botocore"
|
name = "botocore"
|
||||||
version = "1.42.64"
|
version = "1.42.73"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "jmespath" },
|
{ name = "jmespath" },
|
||||||
{ name = "python-dateutil" },
|
{ name = "python-dateutil" },
|
||||||
{ name = "urllib3" },
|
{ name = "urllib3" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/d3/3c/ac4bc939da695d2c648bf28f7b204ab741e4504e81749ccf943403cc07ca/botocore-1.42.64.tar.gz", hash = "sha256:4ee2aece227b9171ace8b749af694a77ab984fceab1639f2626bd0d6fb1aa69d", size = 14967869, upload-time = "2026-03-09T19:51:46.213Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/28/23/0c88ca116ef63b1ae77c901cd5d2095d22a8dbde9e80df74545db4a061b4/botocore-1.42.73.tar.gz", hash = "sha256:575858641e4949aaf2af1ced145b8524529edf006d075877af6b82ff96ad854c", size = 15008008, upload-time = "2026-03-20T19:39:40.082Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/33/0f/a0feb9a93da8f583217432dce71ce1940d6d8aa5884bad340872a504ba3f/botocore-1.42.64-py3-none-any.whl", hash = "sha256:f77c5cb76ed30576ed0bc73b591265d03dddffff02a9208d3ee0c790f43d3cd2", size = 14641339, upload-time = "2026-03-09T19:51:41.244Z" },
|
{ url = "https://files.pythonhosted.org/packages/8e/65/971f3d55015f4d133a6ff3ad74cd39f4b8dd8f53f7775a3c2ad378ea5145/botocore-1.42.73-py3-none-any.whl", hash = "sha256:7b62e2a12f7a1b08eb7360eecd23bb16fe3b7ab7f5617cf91b25476c6f86a0fe", size = 14681861, upload-time = "2026-03-20T19:39:35.341Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -545,14 +545,14 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dj-database-url"
|
name = "dj-database-url"
|
||||||
version = "3.1.0"
|
version = "3.1.2"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "django" },
|
{ name = "django" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/95/c6/88676a7333fb7c668e626b55f8bfc8527dd863973eb1c40412b95d27747d/dj_database_url-3.1.0.tar.gz", hash = "sha256:d80218426b83f9302c8d27d4fccf52de5cf0cab179f0645fb2839f37605d1353", size = 7924, upload-time = "2026-01-04T09:18:32.693Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/03/f6/00b625e9d371b980aa261011d0dc906a16444cb688f94215e0dc86996eb5/dj_database_url-3.1.2.tar.gz", hash = "sha256:63c20e4bbaa51690dfd4c8d189521f6bf6bc9da9fcdb23d95d2ee8ee87f9ec62", size = 11490, upload-time = "2026-02-19T15:30:23.638Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/68/1b/e84f7472ab0bdacc3fd09556eb4dd40d88246941d465cc103b36a8dabcd8/dj_database_url-3.1.0-py3-none-any.whl", hash = "sha256:155a56fbbecbaaf1348ccd73bf29138b4c9988363ba08261a0f0145e392e638c", size = 8849, upload-time = "2026-01-04T09:18:43.77Z" },
|
{ url = "https://files.pythonhosted.org/packages/cf/a9/57c66006373381f1d3e5bd94216f1d371228a89f443d3030e010f73dd198/dj_database_url-3.1.2-py3-none-any.whl", hash = "sha256:544e015fee3efa5127a1eb1cca465f4ace578265b3671fe61d0ed7dbafb5ec8a", size = 8953, upload-time = "2026-02-19T15:30:39.37Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -633,7 +633,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "django-lasuite"
|
name = "django-lasuite"
|
||||||
version = "0.0.24"
|
version = "0.0.25"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "django" },
|
{ name = "django" },
|
||||||
@@ -644,9 +644,9 @@ dependencies = [
|
|||||||
{ name = "requests" },
|
{ name = "requests" },
|
||||||
{ name = "requests-toolbelt" },
|
{ name = "requests-toolbelt" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/53/dc/4002ba20b964237a609628d53b950c5aecf6387119058831e0ee33176f59/django_lasuite-0.0.24.tar.gz", hash = "sha256:3231b0178a2187405c8faae447225c5dd069263a9a09e73e2a36427be4bf2388", size = 34293, upload-time = "2026-02-11T12:25:42.558Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/5e/bc/5826a3e5ada5dad1ff6af9a2e1eb598a0dc2cb9c4d2dbf011f1bbb310c9e/django_lasuite-0.0.25.tar.gz", hash = "sha256:ee44783942e6ead74a732f6d7280c5fca961b66581350ce01c0589c3e80684cf", size = 34819, upload-time = "2026-03-10T13:40:28.705Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/5d/90/9170b8f443ab5d34b32d7cd386ce3b38ca35baae966da4a1d77b4f4ab3d2/django_lasuite-0.0.24-py3-none-any.whl", hash = "sha256:c37e0b3606a23fd4094ca435fa4edf7a64d325be64b0310fa6577f75d515d856", size = 52620, upload-time = "2026-02-11T12:25:40.626Z" },
|
{ url = "https://files.pythonhosted.org/packages/61/2f/819ebbc9d3a4b8233cef1e9b0b607724e4acf527988393b04a4036b9c235/django_lasuite-0.0.25-py3-none-any.whl", hash = "sha256:4c10f625005cd41d05e8d34269f1a3b58fea8be5296528bd58596227f50d9884", size = 54034, upload-time = "2026-03-10T13:40:26.903Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.optional-dependencies]
|
[package.optional-dependencies]
|
||||||
@@ -737,11 +737,11 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dockerflow"
|
name = "dockerflow"
|
||||||
version = "2026.1.26"
|
version = "2026.3.4"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/11/08/7abe8458ce6fa82e694ba9b792b4158596fd681782976699d3f15642a23a/dockerflow-2026.1.26.tar.gz", hash = "sha256:c45667ec078944a468b9a634c866587b4cf31559d0e6f369fbadd21edce66b38", size = 68042, upload-time = "2026-01-26T15:30:06.606Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/9c/03/935f8399094611981b37634a7ee078484b3995f744135339e51385638f6c/dockerflow-2026.3.4.tar.gz", hash = "sha256:6cc7fcab2a078d06aeca8b02e22fd7f6766dca322fb30aed6910684dbc08690c", size = 68701, upload-time = "2026-03-04T09:01:28.178Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/de/88/26cec1e8ce09b4022233f232962fba72650c22941d7a609d10b9eec9f748/dockerflow-2026.1.26-py2.py3-none-any.whl", hash = "sha256:26f02d8842672921b2a49f1e019fac54ed2ee69dc673ed80f7b237b67394c2be", size = 35992, upload-time = "2026-01-26T15:30:05.525Z" },
|
{ url = "https://files.pythonhosted.org/packages/86/b9/2d7bf30eb0c24e60e61e4f6ae7574e123d3fa51b39a612e146c94158446a/dockerflow-2026.3.4-py2.py3-none-any.whl", hash = "sha256:38fe0ad30a4aedf68e589919695d502fc6f584a761b56a91f56e80cbadfbf61a", size = 36424, upload-time = "2026-03-04T09:01:26.631Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -763,14 +763,14 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "drf-spectacular-sidecar"
|
name = "drf-spectacular-sidecar"
|
||||||
version = "2026.1.1"
|
version = "2026.3.1"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "django" },
|
{ name = "django" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/1e/81/c7b0e3ccbd5a039c4f4fcfecf88391a666ca1406a953886e2f39295b1c90/drf_spectacular_sidecar-2026.1.1.tar.gz", hash = "sha256:6f7c173a8ddbbbdafc7a27e028614b65f07a89ca90f996a432d57460463b56be", size = 2468060, upload-time = "2026-01-01T11:27:12.682Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/aa/42/2f8c1b2846399d47094ec414bc0d6a7cce7ba95fd6545a97285eee89f7f1/drf_spectacular_sidecar-2026.3.1.tar.gz", hash = "sha256:5b7fedad66e3851f2f442480792c08115d79217959d01645b93d3d2258938be1", size = 2461501, upload-time = "2026-03-01T11:31:19.708Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/db/96/38725edda526f3e9e597f531beeec94b0ef433d9494f06a13b7636eecb6e/drf_spectacular_sidecar-2026.1.1-py3-none-any.whl", hash = "sha256:af8df62f1b594ec280351336d837eaf2402ab25a6bc2a1fad7aee9935821070f", size = 2489520, upload-time = "2026-01-01T11:27:11.056Z" },
|
{ url = "https://files.pythonhosted.org/packages/c1/28/2d5e64d101ebc5180674fcaf7b5a35e398e2f8d9688b2e8d52b0e1394e7d/drf_spectacular_sidecar-2026.3.1-py3-none-any.whl", hash = "sha256:864edb83e022e13e3941c325c3cc0c954c843fa2e1d0bc95e81887664b2d3dad", size = 2481725, upload-time = "2026-03-01T11:31:18.469Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -976,7 +976,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipython"
|
name = "ipython"
|
||||||
version = "9.10.0"
|
version = "9.11.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||||
@@ -990,9 +990,9 @@ dependencies = [
|
|||||||
{ name = "stack-data" },
|
{ name = "stack-data" },
|
||||||
{ name = "traitlets" },
|
{ name = "traitlets" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/a6/60/2111715ea11f39b1535bed6024b7dec7918b71e5e5d30855a5b503056b50/ipython-9.10.0.tar.gz", hash = "sha256:cd9e656be97618a0676d058134cd44e6dc7012c0e5cb36a9ce96a8c904adaf77", size = 4426526, upload-time = "2026-02-02T10:00:33.594Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/86/28/a4698eda5a8928a45d6b693578b135b753e14fa1c2b36ee9441e69a45576/ipython-9.11.0.tar.gz", hash = "sha256:2a94bc4406b22ecc7e4cb95b98450f3ea493a76bec8896cda11b78d7752a6667", size = 4427354, upload-time = "2026-03-05T08:57:30.549Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/3d/aa/898dec789a05731cd5a9f50605b7b44a72bd198fd0d4528e11fc610177cc/ipython-9.10.0-py3-none-any.whl", hash = "sha256:c6ab68cc23bba8c7e18e9b932797014cc61ea7fd6f19de180ab9ba73e65ee58d", size = 622774, upload-time = "2026-02-02T10:00:31.503Z" },
|
{ url = "https://files.pythonhosted.org/packages/b2/90/45c72becc57158facc6a6404f663b77bbcea2519ca57f760e2879ae1315d/ipython-9.11.0-py3-none-any.whl", hash = "sha256:6922d5bcf944c6e525a76a0a304451b60a2b6f875e86656d8bc2dfda5d710e19", size = 624222, upload-time = "2026-03-05T08:57:28.94Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1157,7 +1157,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "meet"
|
name = "meet"
|
||||||
version = "1.10.0"
|
version = "1.12.0"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "aiohttp" },
|
{ name = "aiohttp" },
|
||||||
@@ -1222,24 +1222,24 @@ dev = [
|
|||||||
[package.metadata]
|
[package.metadata]
|
||||||
requires-dist = [
|
requires-dist = [
|
||||||
{ name = "aiohttp", specifier = "==3.13.3" },
|
{ name = "aiohttp", specifier = "==3.13.3" },
|
||||||
{ name = "boto3", specifier = "==1.42.49" },
|
{ name = "boto3", specifier = "==1.42.68" },
|
||||||
{ name = "brevo-python", specifier = "==1.2.0" },
|
{ name = "brevo-python", specifier = "==1.2.0" },
|
||||||
{ name = "brotli", specifier = "==1.2.0" },
|
{ name = "brotli", specifier = "==1.2.0" },
|
||||||
{ name = "celery", extras = ["redis"], specifier = "==5.6.2" },
|
{ name = "celery", extras = ["redis"], specifier = "==5.6.2" },
|
||||||
{ name = "dj-database-url", specifier = "==3.1.0" },
|
{ name = "dj-database-url", specifier = "==3.1.2" },
|
||||||
{ name = "django", specifier = "==5.2.12" },
|
{ name = "django", specifier = "==5.2.12" },
|
||||||
{ name = "django-configurations", specifier = "==2.5.1" },
|
{ name = "django-configurations", specifier = "==2.5.1" },
|
||||||
{ name = "django-cors-headers", specifier = "==4.9.0" },
|
{ name = "django-cors-headers", specifier = "==4.9.0" },
|
||||||
{ name = "django-countries", specifier = "==8.2.0" },
|
{ name = "django-countries", specifier = "==8.2.0" },
|
||||||
{ name = "django-filter", specifier = "==25.2" },
|
{ name = "django-filter", specifier = "==25.2" },
|
||||||
{ name = "django-lasuite", extras = ["all"], specifier = "==0.0.24" },
|
{ name = "django-lasuite", extras = ["all"], specifier = "==0.0.25" },
|
||||||
{ name = "django-parler", specifier = "==2.3" },
|
{ name = "django-parler", specifier = "==2.3" },
|
||||||
{ name = "django-pydantic-field", specifier = "==0.5.4" },
|
{ name = "django-pydantic-field", specifier = "==0.5.4" },
|
||||||
{ name = "django-redis", specifier = "==6.0.0" },
|
{ name = "django-redis", specifier = "==6.0.0" },
|
||||||
{ name = "django-storages", extras = ["s3"], specifier = "==1.14.6" },
|
{ name = "django-storages", extras = ["s3"], specifier = "==1.14.6" },
|
||||||
{ name = "django-timezone-field", specifier = ">=5.1" },
|
{ name = "django-timezone-field", specifier = ">=5.1" },
|
||||||
{ name = "djangorestframework", specifier = "==3.16.1" },
|
{ name = "djangorestframework", specifier = "==3.16.1" },
|
||||||
{ name = "dockerflow", specifier = "==2026.1.26" },
|
{ name = "dockerflow", specifier = "==2026.3.4" },
|
||||||
{ name = "drf-spectacular", specifier = "==0.29.0" },
|
{ name = "drf-spectacular", specifier = "==0.29.0" },
|
||||||
{ name = "easy-thumbnails", specifier = "==2.10.1" },
|
{ name = "easy-thumbnails", specifier = "==2.10.1" },
|
||||||
{ name = "factory-boy", specifier = "==3.3.3" },
|
{ name = "factory-boy", specifier = "==3.3.3" },
|
||||||
@@ -1249,25 +1249,25 @@ requires-dist = [
|
|||||||
{ name = "markdown", specifier = "==3.10.2" },
|
{ name = "markdown", specifier = "==3.10.2" },
|
||||||
{ name = "mozilla-django-oidc", specifier = "==5.0.2" },
|
{ name = "mozilla-django-oidc", specifier = "==5.0.2" },
|
||||||
{ name = "nested-multipart-parser", specifier = "==1.6.0" },
|
{ name = "nested-multipart-parser", specifier = "==1.6.0" },
|
||||||
{ name = "psycopg", extras = ["binary"], specifier = "==3.3.2" },
|
{ name = "psycopg", extras = ["binary"], specifier = "==3.3.3" },
|
||||||
{ name = "pydantic", specifier = "==2.12.4" },
|
{ name = "pydantic", specifier = "==2.12.5" },
|
||||||
{ name = "pyjwt", specifier = "==2.11.0" },
|
{ name = "pyjwt", specifier = "==2.12.1" },
|
||||||
{ name = "python-frontmatter", specifier = "==1.1.0" },
|
{ name = "python-frontmatter", specifier = "==1.1.0" },
|
||||||
{ name = "python-magic", specifier = "==0.4.27" },
|
{ name = "python-magic", specifier = "==0.4.27" },
|
||||||
{ name = "redis", specifier = "==5.2.1" },
|
{ name = "redis", specifier = "==5.2.1" },
|
||||||
{ name = "requests", specifier = "==2.32.5" },
|
{ name = "requests", specifier = "==2.32.5" },
|
||||||
{ name = "sentry-sdk", specifier = "==2.53.0" },
|
{ name = "sentry-sdk", specifier = "==2.54.0" },
|
||||||
{ name = "whitenoise", specifier = "==6.11.0" },
|
{ name = "whitenoise", specifier = "==6.12.0" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.metadata.requires-dev]
|
[package.metadata.requires-dev]
|
||||||
dev = [
|
dev = [
|
||||||
{ name = "django-extensions", specifier = "==4.1" },
|
{ name = "django-extensions", specifier = "==4.1" },
|
||||||
{ name = "drf-spectacular-sidecar", specifier = "==2026.1.1" },
|
{ name = "drf-spectacular-sidecar", specifier = "==2026.3.1" },
|
||||||
{ name = "freezegun", specifier = "==1.5.5" },
|
{ name = "freezegun", specifier = "==1.5.5" },
|
||||||
{ name = "ipdb", specifier = "==0.13.13" },
|
{ name = "ipdb", specifier = "==0.13.13" },
|
||||||
{ name = "ipython", specifier = "==9.10.0" },
|
{ name = "ipython", specifier = "==9.11.0" },
|
||||||
{ name = "pyfakefs", specifier = "==6.1.1" },
|
{ name = "pyfakefs", specifier = "==6.1.5" },
|
||||||
{ name = "pylint", specifier = "<4.0.0" },
|
{ name = "pylint", specifier = "<4.0.0" },
|
||||||
{ name = "pylint-django", specifier = "==2.7.0" },
|
{ name = "pylint-django", specifier = "==2.7.0" },
|
||||||
{ name = "pytest", specifier = "==9.0.2" },
|
{ name = "pytest", specifier = "==9.0.2" },
|
||||||
@@ -1275,8 +1275,8 @@ dev = [
|
|||||||
{ name = "pytest-django", specifier = "==4.12.0" },
|
{ name = "pytest-django", specifier = "==4.12.0" },
|
||||||
{ name = "pytest-icdiff", specifier = "==0.9" },
|
{ name = "pytest-icdiff", specifier = "==0.9" },
|
||||||
{ name = "pytest-xdist", specifier = "==3.8.0" },
|
{ name = "pytest-xdist", specifier = "==3.8.0" },
|
||||||
{ name = "responses", specifier = "==0.25.8" },
|
{ name = "responses", specifier = "==0.26.0" },
|
||||||
{ name = "ruff", specifier = "==0.15.1" },
|
{ name = "ruff", specifier = "==0.15.6" },
|
||||||
{ name = "types-requests", specifier = "==2.32.4.20260107" },
|
{ name = "types-requests", specifier = "==2.32.4.20260107" },
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1595,14 +1595,14 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "psycopg"
|
name = "psycopg"
|
||||||
version = "3.3.2"
|
version = "3.3.3"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "tzdata", marker = "sys_platform == 'win32'" },
|
{ name = "tzdata", marker = "sys_platform == 'win32'" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/e0/1a/7d9ef4fdc13ef7f15b934c393edc97a35c281bb7d3c3329fbfcbe915a7c2/psycopg-3.3.2.tar.gz", hash = "sha256:707a67975ee214d200511177a6a80e56e654754c9afca06a7194ea6bbfde9ca7", size = 165630, upload-time = "2025-12-06T17:34:53.899Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/d3/b6/379d0a960f8f435ec78720462fd94c4863e7a31237cf81bf76d0af5883bf/psycopg-3.3.3.tar.gz", hash = "sha256:5e9a47458b3c1583326513b2556a2a9473a1001a56c9efe9e587245b43148dd9", size = 165624, upload-time = "2026-02-18T16:52:16.546Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/8c/51/2779ccdf9305981a06b21a6b27e8547c948d85c41c76ff434192784a4c93/psycopg-3.3.2-py3-none-any.whl", hash = "sha256:3e94bc5f4690247d734599af56e51bae8e0db8e4311ea413f801fef82b14a99b", size = 212774, upload-time = "2025-12-06T17:31:41.414Z" },
|
{ url = "https://files.pythonhosted.org/packages/c8/5b/181e2e3becb7672b502f0ed7f16ed7352aca7c109cfb94cf3878a9186db9/psycopg-3.3.3-py3-none-any.whl", hash = "sha256:f96525a72bcfade6584ab17e89de415ff360748c766f0106959144dcbb38c698", size = 212768, upload-time = "2026-02-18T16:46:27.365Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.optional-dependencies]
|
[package.optional-dependencies]
|
||||||
@@ -1612,31 +1612,31 @@ binary = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "psycopg-binary"
|
name = "psycopg-binary"
|
||||||
version = "3.3.2"
|
version = "3.3.3"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/14/73/7ca7cb22b9ac7393fb5de7d28ca97e8347c375c8498b3bff2c99c1f38038/psycopg_binary-3.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fc5a189e89cbfff174588665bb18d28d2d0428366cc9dae5864afcaa2e57380b", size = 4579068, upload-time = "2025-12-06T17:33:39.303Z" },
|
{ url = "https://files.pythonhosted.org/packages/03/0a/cac9fdf1df16a269ba0e5f0f06cac61f826c94cadb39df028cdfe19d3a33/psycopg_binary-3.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05f32239aec25c5fb15f7948cffdc2dc0dac098e48b80a140e4ba32b572a2e7d", size = 4590414, upload-time = "2026-02-18T16:50:01.441Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f5/42/0cf38ff6c62c792fc5b55398a853a77663210ebd51ed6f0c4a05b06f95a6/psycopg_binary-3.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:083c2e182be433f290dc2c516fd72b9b47054fcd305cce791e0a50d9e93e06f2", size = 4657520, upload-time = "2025-12-06T17:33:42.536Z" },
|
{ url = "https://files.pythonhosted.org/packages/9c/c0/d8f8508fbf440edbc0099b1abff33003cd80c9e66eb3a1e78834e3fb4fb9/psycopg_binary-3.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7c84f9d214f2d1de2fafebc17fa68ac3f6561a59e291553dfc45ad299f4898c1", size = 4669021, upload-time = "2026-02-18T16:50:08.803Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3b/60/df846bc84cbf2231e01b0fff48b09841fe486fa177665e50f4995b1bfa44/psycopg_binary-3.3.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:ac230e3643d1c436a2dfb59ca84357dfc6862c9f372fc5dbd96bafecae581f9f", size = 5452086, upload-time = "2025-12-06T17:33:46.54Z" },
|
{ url = "https://files.pythonhosted.org/packages/04/05/097016b77e343b4568feddf12c72171fc513acef9a4214d21b9478569068/psycopg_binary-3.3.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e77957d2ba17cada11be09a5066d93026cdb61ada7c8893101d7fe1c6e1f3925", size = 5467453, upload-time = "2026-02-18T16:50:14.985Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ab/85/30c846a00db86b1b53fd5bfd4b4edfbd0c00de8f2c75dd105610bd7568fc/psycopg_binary-3.3.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d8c899a540f6c7585cee53cddc929dd4d2db90fd828e37f5d4017b63acbc1a5d", size = 5131125, upload-time = "2025-12-06T17:33:50.413Z" },
|
{ url = "https://files.pythonhosted.org/packages/91/23/73244e5feb55b5ca109cede6e97f32ef45189f0fdac4c80d75c99862729d/psycopg_binary-3.3.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:42961609ac07c232a427da7c87a468d3c82fee6762c220f38e37cfdacb2b178d", size = 5151135, upload-time = "2026-02-18T16:50:24.82Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/6d/15/9968732013373f36f8a2a3fb76104dffc8efd9db78709caa5ae1a87b1f80/psycopg_binary-3.3.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50ff10ab8c0abdb5a5451b9315538865b50ba64c907742a1385fdf5f5772b73e", size = 6722914, upload-time = "2025-12-06T17:33:54.544Z" },
|
{ url = "https://files.pythonhosted.org/packages/11/49/5309473b9803b207682095201d8708bbc7842ddf3f192488a69204e36455/psycopg_binary-3.3.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae07a3114313dd91fce686cab2f4c44af094398519af0e0f854bc707e1aeedf1", size = 6737315, upload-time = "2026-02-18T16:50:35.106Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b2/ba/29e361fe02143ac5ff5a1ca3e45697344cfbebe2eaf8c4e7eec164bff9a0/psycopg_binary-3.3.2-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:23d2594af848c1fd3d874a9364bef50730124e72df7bb145a20cb45e728c50ed", size = 4966081, upload-time = "2025-12-06T17:33:58.477Z" },
|
{ url = "https://files.pythonhosted.org/packages/d4/5d/03abe74ef34d460b33c4d9662bf6ec1dd38888324323c1a1752133c10377/psycopg_binary-3.3.3-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d257c58d7b36a621dcce1d01476ad8b60f12d80eb1406aee4cf796f88b2ae482", size = 4979783, upload-time = "2026-02-18T16:50:42.067Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/99/45/1be90c8f1a1a237046903e91202fb06708745c179f220b361d6333ed7641/psycopg_binary-3.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ea4fe6b4ead3bbbe27244ea224fcd1f53cb119afc38b71a2f3ce570149a03e30", size = 4493332, upload-time = "2025-12-06T17:34:02.011Z" },
|
{ url = "https://files.pythonhosted.org/packages/f0/6c/3fbf8e604e15f2f3752900434046c00c90bb8764305a1b81112bff30ba24/psycopg_binary-3.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:07c7211f9327d522c9c47560cae00a4ecf6687f4e02d779d035dd3177b41cb12", size = 4509023, upload-time = "2026-02-18T16:50:50.116Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/2e/b5/bbdc07d5f0a5e90c617abd624368182aa131485e18038b2c6c85fc054aed/psycopg_binary-3.3.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:742ce48cde825b8e52fb1a658253d6d1ff66d152081cbc76aa45e2986534858d", size = 4170781, upload-time = "2025-12-06T17:34:05.298Z" },
|
{ url = "https://files.pythonhosted.org/packages/9c/6b/1a06b43b7c7af756c80b67eac8bfaa51d77e68635a8a8d246e4f0bb7604a/psycopg_binary-3.3.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8e7e9eca9b363dbedeceeadd8be97149d2499081f3c52d141d7cd1f395a91f83", size = 4185874, upload-time = "2026-02-18T16:50:55.97Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d1/2a/0d45e4f4da2bd78c3237ffa03475ef3751f69a81919c54a6e610eb1a7c96/psycopg_binary-3.3.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e22bf6b54df994aff37ab52695d635f1ef73155e781eee1f5fa75bc08b58c8da", size = 3910544, upload-time = "2025-12-06T17:34:08.251Z" },
|
{ url = "https://files.pythonhosted.org/packages/2b/d3/bf49e3dcaadba510170c8d111e5e69e5ae3f981c1554c5bb71c75ce354bb/psycopg_binary-3.3.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:cb85b1d5702877c16f28d7b92ba030c1f49ebcc9b87d03d8c10bf45a2f1c7508", size = 3925668, upload-time = "2026-02-18T16:51:03.299Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3a/62/a8e0f092f4dbef9a94b032fb71e214cf0a375010692fbe7493a766339e47/psycopg_binary-3.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8db9034cde3bcdafc66980f0130813f5c5d19e74b3f2a19fb3cfbc25ad113121", size = 4220070, upload-time = "2025-12-06T17:34:11.392Z" },
|
{ url = "https://files.pythonhosted.org/packages/f8/92/0aac830ed6a944fe334404e1687a074e4215630725753f0e3e9a9a595b62/psycopg_binary-3.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4d4606c84d04b80f9138d72f1e28c6c02dc5ae0c7b8f3f8aaf89c681ce1cd1b1", size = 4234973, upload-time = "2026-02-18T16:51:09.097Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/09/e6/5fc8d8aff8afa114bb4a94a0341b9309311e8bf3ab32d816032f8b984d4e/psycopg_binary-3.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:df65174c7cf6b05ea273ce955927d3270b3a6e27b0b12762b009ce6082b8d3fc", size = 3540922, upload-time = "2025-12-06T17:34:14.88Z" },
|
{ url = "https://files.pythonhosted.org/packages/2e/96/102244653ee5a143ece5afe33f00f52fe64e389dfce8dbc87580c6d70d3d/psycopg_binary-3.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:74eae563166ebf74e8d950ff359be037b85723d99ca83f57d9b244a871d6c13b", size = 3551342, upload-time = "2026-02-18T16:51:13.892Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/bd/75/ad18c0b97b852aba286d06befb398cc6d383e9dfd0a518369af275a5a526/psycopg_binary-3.3.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:9ca24062cd9b2270e4d77576042e9cc2b1d543f09da5aba1f1a3d016cea28390", size = 4596371, upload-time = "2025-12-06T17:34:18.007Z" },
|
{ url = "https://files.pythonhosted.org/packages/a2/71/7a57e5b12275fe7e7d84d54113f0226080423a869118419c9106c083a21c/psycopg_binary-3.3.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:497852c5eaf1f0c2d88ab74a64a8097c099deac0c71de1cbcf18659a8a04a4b2", size = 4607368, upload-time = "2026-02-18T16:51:19.295Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/5a/79/91649d94c8d89f84af5da7c9d474bfba35b08eb8f492ca3422b08f0a6427/psycopg_binary-3.3.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c749770da0947bc972e512f35366dd4950c0e34afad89e60b9787a37e97cb443", size = 4675139, upload-time = "2025-12-06T17:34:21.374Z" },
|
{ url = "https://files.pythonhosted.org/packages/c7/04/cb834f120f2b2c10d4003515ef9ca9d688115b9431735e3936ae48549af8/psycopg_binary-3.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:258d1ea53464d29768bf25930f43291949f4c7becc706f6e220c515a63a24edd", size = 4687047, upload-time = "2026-02-18T16:51:23.84Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/56/ac/b26e004880f054549ec9396594e1ffe435810b0673e428e619ed722e4244/psycopg_binary-3.3.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:03b7cd73fb8c45d272a34ae7249713e32492891492681e3cf11dff9531cf37e9", size = 5456120, upload-time = "2025-12-06T17:34:25.102Z" },
|
{ url = "https://files.pythonhosted.org/packages/40/e9/47a69692d3da9704468041aa5ed3ad6fc7f6bb1a5ae788d261a26bbca6c7/psycopg_binary-3.3.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:111c59897a452196116db12e7f608da472fbff000693a21040e35fc978b23430", size = 5487096, upload-time = "2026-02-18T16:51:29.645Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/4b/8d/410681dccd6f2999fb115cc248521ec50dd2b0aba66ae8de7e81efdebbee/psycopg_binary-3.3.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:43b130e3b6edcb5ee856c7167ccb8561b473308c870ed83978ae478613764f1c", size = 5133484, upload-time = "2025-12-06T17:34:28.933Z" },
|
{ url = "https://files.pythonhosted.org/packages/0b/b6/0e0dd6a2f802864a4ae3dbadf4ec620f05e3904c7842b326aafc43e5f464/psycopg_binary-3.3.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:17bb6600e2455993946385249a3c3d0af52cd70c1c1cdbf712e9d696d0b0bf1b", size = 5168720, upload-time = "2026-02-18T16:51:36.499Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/66/30/ebbab99ea2cfa099d7b11b742ce13415d44f800555bfa4ad2911dc645b71/psycopg_binary-3.3.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7c1feba5a8c617922321aef945865334e468337b8fc5c73074f5e63143013b5a", size = 6731818, upload-time = "2025-12-06T17:34:33.094Z" },
|
{ url = "https://files.pythonhosted.org/packages/6f/0d/977af38ac19a6b55d22dff508bd743fd7c1901e1b73657e7937c7cccb0a3/psycopg_binary-3.3.3-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:642050398583d61c9856210568eb09a8e4f2fe8224bf3be21b67a370e677eead", size = 6762076, upload-time = "2026-02-18T16:51:43.167Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/70/02/d260646253b7ad805d60e0de47f9b811d6544078452579466a098598b6f4/psycopg_binary-3.3.2-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cabb2a554d9a0a6bf84037d86ca91782f087dfff2a61298d0b00c19c0bc43f6d", size = 4983859, upload-time = "2025-12-06T17:34:36.457Z" },
|
{ url = "https://files.pythonhosted.org/packages/34/40/912a39d48322cf86895c0eaf2d5b95cb899402443faefd4b09abbba6b6e1/psycopg_binary-3.3.3-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:533efe6dc3a7cba5e2a84e38970786bb966306863e45f3db152007e9f48638a6", size = 4997623, upload-time = "2026-02-18T16:51:47.707Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/72/8d/e778d7bad1a7910aa36281f092bd85c5702f508fd9bb0ea2020ffbb6585c/psycopg_binary-3.3.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:74bc306c4b4df35b09bc8cecf806b271e1c5d708f7900145e4e54a2e5dedfed0", size = 4516388, upload-time = "2025-12-06T17:34:40.129Z" },
|
{ url = "https://files.pythonhosted.org/packages/98/0c/c14d0e259c65dc7be854d926993f151077887391d5a081118907a9d89603/psycopg_binary-3.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5958dbf28b77ce2033482f6cb9ef04d43f5d8f4b7636e6963d5626f000efb23e", size = 4532096, upload-time = "2026-02-18T16:51:51.421Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/bd/f1/64e82098722e2ab3521797584caf515284be09c1e08a872551b6edbb0074/psycopg_binary-3.3.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:d79b0093f0fbf7a962d6a46ae292dc056c65d16a8ee9361f3cfbafd4c197ab14", size = 4192382, upload-time = "2025-12-06T17:34:43.279Z" },
|
{ url = "https://files.pythonhosted.org/packages/39/21/8b7c50a194cfca6ea0fd4d1f276158307785775426e90700ab2eba5cd623/psycopg_binary-3.3.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:a6af77b6626ce92b5817bf294b4d45ec1a6161dba80fc2d82cdffdd6814fd023", size = 4208884, upload-time = "2026-02-18T16:51:57.336Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/fa/d0/c20f4e668e89494972e551c31be2a0016e3f50d552d7ae9ac07086407599/psycopg_binary-3.3.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:1586e220be05547c77afc326741dd41cc7fba38a81f9931f616ae98865439678", size = 3928660, upload-time = "2025-12-06T17:34:46.757Z" },
|
{ url = "https://files.pythonhosted.org/packages/c7/2c/a4981bf42cf30ebba0424971d7ce70a222ae9b82594c42fc3f2105d7b525/psycopg_binary-3.3.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:47f06fcbe8542b4d96d7392c476a74ada521c5aebdb41c3c0155f6595fc14c8d", size = 3944542, upload-time = "2026-02-18T16:52:04.266Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/0f/e1/99746c171de22539fd5eb1c9ca21dc805b54cfae502d7451d237d1dbc349/psycopg_binary-3.3.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:458696a5fa5dad5b6fb5d5862c22454434ce4fe1cf66ca6c0de5f904cbc1ae3e", size = 4239169, upload-time = "2025-12-06T17:34:49.751Z" },
|
{ url = "https://files.pythonhosted.org/packages/60/e9/b7c29b56aa0b85a4e0c4d89db691c1ceef08f46a356369144430c155a2f5/psycopg_binary-3.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e7800e6c6b5dc4b0ca7cc7370f770f53ac83886b76afda0848065a674231e856", size = 4254339, upload-time = "2026-02-18T16:52:10.444Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/72/f7/212343c1c9cfac35fd943c527af85e9091d633176e2a407a0797856ff7b9/psycopg_binary-3.3.2-cp314-cp314-win_amd64.whl", hash = "sha256:04bb2de4ba69d6f8395b446ede795e8884c040ec71d01dd07ac2b2d18d4153d1", size = 3642122, upload-time = "2025-12-06T17:34:52.506Z" },
|
{ url = "https://files.pythonhosted.org/packages/98/5a/291d89f44d3820fffb7a04ebc8f3ef5dda4f542f44a5daea0c55a84abf45/psycopg_binary-3.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:165f22ab5a9513a3d7425ffb7fcc7955ed8ccaeef6d37e369d6cc1dff1582383", size = 3652796, upload-time = "2026-02-18T16:52:14.02Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1668,7 +1668,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pydantic"
|
name = "pydantic"
|
||||||
version = "2.12.4"
|
version = "2.12.5"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "annotated-types" },
|
{ name = "annotated-types" },
|
||||||
@@ -1676,9 +1676,9 @@ dependencies = [
|
|||||||
{ name = "typing-extensions" },
|
{ name = "typing-extensions" },
|
||||||
{ name = "typing-inspection" },
|
{ name = "typing-inspection" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/96/ad/a17bc283d7d81837c061c49e3eaa27a45991759a1b7eae1031921c6bd924/pydantic-2.12.4.tar.gz", hash = "sha256:0f8cb9555000a4b5b617f66bfd2566264c4984b27589d3b845685983e8ea85ac", size = 821038, upload-time = "2025-11-05T10:50:08.59Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/82/2f/e68750da9b04856e2a7ec56fc6f034a5a79775e9b9a81882252789873798/pydantic-2.12.4-py3-none-any.whl", hash = "sha256:92d3d202a745d46f9be6df459ac5a064fdaa3c1c4cd8adcfa332ccf3c05f871e", size = 463400, upload-time = "2025-11-05T10:50:06.732Z" },
|
{ url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1736,11 +1736,11 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyfakefs"
|
name = "pyfakefs"
|
||||||
version = "6.1.1"
|
version = "6.1.5"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/43/84/843a50cfde48d6004cbf540b38b82a39737273cc76b51da6b456fea75de0/pyfakefs-6.1.1.tar.gz", hash = "sha256:1c166fdba85f3f288f89b2a410e05712914d1f7ea77b920e960fe0cbbea1294d", size = 226032, upload-time = "2026-02-09T19:44:19.539Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/61/87/fe3f1fbbf18480b57e6b195d4d416e01d8e55bf88743982ccb3a8845c2a2/pyfakefs-6.1.5.tar.gz", hash = "sha256:d70fb1c622a1d5c729462d31bb58eead99c1830986bc049bf8975c480a49d19b", size = 226814, upload-time = "2026-03-15T19:05:18.025Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/a5/e2/1d74c7663aa38e405c25a30c26e8a1b92c06f8947118b9617042f4290ade/pyfakefs-6.1.1-py3-none-any.whl", hash = "sha256:e2c30fd0b7736ba03785bbc20b86de2312623cf7a11a7de334042ab0de23d46f", size = 239630, upload-time = "2026-02-09T19:44:18.093Z" },
|
{ url = "https://files.pythonhosted.org/packages/e0/d8/a60fb94ab2b5a9bf0e38d6e93667904d4e844d8b7e9cfb5ef0304d68da6b/pyfakefs-6.1.5-py3-none-any.whl", hash = "sha256:2c482f36bad7d1f7516d58d17818fb0dbe397a3372ec5274869386a9b7cd4883", size = 239885, upload-time = "2026-03-15T19:05:16.488Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1754,11 +1754,11 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyjwt"
|
name = "pyjwt"
|
||||||
version = "2.11.0"
|
version = "2.12.1"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/5c/5a/b46fa56bf322901eee5b0454a34343cdbdae202cd421775a8ee4e42fd519/pyjwt-2.11.0.tar.gz", hash = "sha256:35f95c1f0fbe5d5ba6e43f00271c275f7a1a4db1dab27bf708073b75318ea623", size = 98019, upload-time = "2026-01-30T19:59:55.694Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/c2/27/a3b6e5bf6ff856d2509292e95c8f57f0df7017cf5394921fc4e4ef40308a/pyjwt-2.12.1.tar.gz", hash = "sha256:c74a7a2adf861c04d002db713dd85f84beb242228e671280bf709d765b03672b", size = 102564, upload-time = "2026-03-13T19:27:37.25Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl", hash = "sha256:94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469", size = 28224, upload-time = "2026-01-30T19:59:54.539Z" },
|
{ url = "https://files.pythonhosted.org/packages/e5/7a/8dd906bd22e79e47397a61742927f6747fe93242ef86645ee9092e610244/pyjwt-2.12.1-py3-none-any.whl", hash = "sha256:28ca37c070cad8ba8cd9790cd940535d40274d22f80ab87f3ac6a713e6e8454c", size = 29726, upload-time = "2026-03-13T19:27:35.677Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1992,16 +1992,16 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "responses"
|
name = "responses"
|
||||||
version = "0.25.8"
|
version = "0.26.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "pyyaml" },
|
{ name = "pyyaml" },
|
||||||
{ name = "requests" },
|
{ name = "requests" },
|
||||||
{ name = "urllib3" },
|
{ name = "urllib3" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/0e/95/89c054ad70bfef6da605338b009b2e283485835351a9935c7bfbfaca7ffc/responses-0.25.8.tar.gz", hash = "sha256:9374d047a575c8f781b94454db5cab590b6029505f488d12899ddb10a4af1cf4", size = 79320, upload-time = "2025-08-08T19:01:46.709Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/9f/b4/b7e040379838cc71bf5aabdb26998dfbe5ee73904c92c1c161faf5de8866/responses-0.26.0.tar.gz", hash = "sha256:c7f6923e6343ef3682816ba421c006626777893cb0d5e1434f674b649bac9eb4", size = 81303, upload-time = "2026-02-19T14:38:05.574Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/1c/4c/cc276ce57e572c102d9542d383b2cfd551276581dc60004cb94fe8774c11/responses-0.25.8-py3-none-any.whl", hash = "sha256:0c710af92def29c8352ceadff0c3fe340ace27cf5af1bbe46fb71275bcd2831c", size = 34769, upload-time = "2025-08-08T19:01:45.018Z" },
|
{ url = "https://files.pythonhosted.org/packages/ce/04/7f73d05b556da048923e31a0cc878f03be7c5425ed1f268082255c75d872/responses-0.26.0-py3-none-any.whl", hash = "sha256:03ec4409088cd5c66b71ecbbbd27fe2c58ddfad801c66203457b3e6a04868c37", size = 35099, upload-time = "2026-02-19T14:38:03.847Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2072,27 +2072,27 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruff"
|
name = "ruff"
|
||||||
version = "0.15.1"
|
version = "0.15.6"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/04/dc/4e6ac71b511b141cf626357a3946679abeba4cf67bc7cc5a17920f31e10d/ruff-0.15.1.tar.gz", hash = "sha256:c590fe13fb57c97141ae975c03a1aedb3d3156030cabd740d6ff0b0d601e203f", size = 4540855, upload-time = "2026-02-12T23:09:09.998Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/51/df/f8629c19c5318601d3121e230f74cbee7a3732339c52b21daa2b82ef9c7d/ruff-0.15.6.tar.gz", hash = "sha256:8394c7bb153a4e3811a4ecdacd4a8e6a4fa8097028119160dffecdcdf9b56ae4", size = 4597916, upload-time = "2026-03-12T23:05:47.51Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/23/bf/e6e4324238c17f9d9120a9d60aa99a7daaa21204c07fcd84e2ef03bb5fd1/ruff-0.15.1-py3-none-linux_armv6l.whl", hash = "sha256:b101ed7cf4615bda6ffe65bdb59f964e9f4a0d3f85cbf0e54f0ab76d7b90228a", size = 10367819, upload-time = "2026-02-12T23:09:03.598Z" },
|
{ url = "https://files.pythonhosted.org/packages/9e/2f/4e03a7e5ce99b517e98d3b4951f411de2b0fa8348d39cf446671adcce9a2/ruff-0.15.6-py3-none-linux_armv6l.whl", hash = "sha256:7c98c3b16407b2cf3d0f2b80c80187384bc92c6774d85fefa913ecd941256fff", size = 10508953, upload-time = "2026-03-12T23:05:17.246Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b3/ea/c8f89d32e7912269d38c58f3649e453ac32c528f93bb7f4219258be2e7ed/ruff-0.15.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:939c995e9277e63ea632cc8d3fae17aa758526f49a9a850d2e7e758bfef46602", size = 10798618, upload-time = "2026-02-12T23:09:22.928Z" },
|
{ url = "https://files.pythonhosted.org/packages/70/60/55bcdc3e9f80bcf39edf0cd272da6fa511a3d94d5a0dd9e0adf76ceebdb4/ruff-0.15.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ee7dcfaad8b282a284df4aa6ddc2741b3f4a18b0555d626805555a820ea181c3", size = 10942257, upload-time = "2026-03-12T23:05:23.076Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/5e/0f/1d0d88bc862624247d82c20c10d4c0f6bb2f346559d8af281674cf327f15/ruff-0.15.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1d83466455fdefe60b8d9c8df81d3c1bbb2115cede53549d3b522ce2bc703899", size = 10148518, upload-time = "2026-02-12T23:08:58.339Z" },
|
{ url = "https://files.pythonhosted.org/packages/e7/f9/005c29bd1726c0f492bfa215e95154cf480574140cb5f867c797c18c790b/ruff-0.15.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3bd9967851a25f038fc8b9ae88a7fbd1b609f30349231dffaa37b6804923c4bb", size = 10322683, upload-time = "2026-03-12T23:05:33.738Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f5/c8/291c49cefaa4a9248e986256df2ade7add79388fe179e0691be06fae6f37/ruff-0.15.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9457e3c3291024866222b96108ab2d8265b477e5b1534c7ddb1810904858d16", size = 10518811, upload-time = "2026-02-12T23:09:31.865Z" },
|
{ url = "https://files.pythonhosted.org/packages/5f/74/2f861f5fd7cbb2146bddb5501450300ce41562da36d21868c69b7a828169/ruff-0.15.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13f4594b04e42cd24a41da653886b04d2ff87adbf57497ed4f728b0e8a4866f8", size = 10660986, upload-time = "2026-03-12T23:05:53.245Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/c3/1a/f5707440e5ae43ffa5365cac8bbb91e9665f4a883f560893829cf16a606b/ruff-0.15.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92c92b003e9d4f7fbd33b1867bb15a1b785b1735069108dfc23821ba045b29bc", size = 10196169, upload-time = "2026-02-12T23:09:17.306Z" },
|
{ url = "https://files.pythonhosted.org/packages/c1/a1/309f2364a424eccb763cdafc49df843c282609f47fe53aa83f38272389e0/ruff-0.15.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e2ed8aea2f3fe57886d3f00ea5b8aae5bf68d5e195f487f037a955ff9fbaac9e", size = 10332177, upload-time = "2026-03-12T23:05:56.145Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/2a/ff/26ddc8c4da04c8fd3ee65a89c9fb99eaa5c30394269d424461467be2271f/ruff-0.15.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fe5c41ab43e3a06778844c586251eb5a510f67125427625f9eb2b9526535779", size = 10990491, upload-time = "2026-02-12T23:09:25.503Z" },
|
{ url = "https://files.pythonhosted.org/packages/30/41/7ebf1d32658b4bab20f8ac80972fb19cd4e2c6b78552be263a680edc55ac/ruff-0.15.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70789d3e7830b848b548aae96766431c0dc01a6c78c13381f423bf7076c66d15", size = 11170783, upload-time = "2026-03-12T23:06:01.742Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/fc/00/50920cb385b89413f7cdb4bb9bc8fc59c1b0f30028d8bccc294189a54955/ruff-0.15.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66a6dd6df4d80dc382c6484f8ce1bcceb55c32e9f27a8b94c32f6c7331bf14fb", size = 11843280, upload-time = "2026-02-12T23:09:19.88Z" },
|
{ url = "https://files.pythonhosted.org/packages/76/be/6d488f6adca047df82cd62c304638bcb00821c36bd4881cfca221561fdfc/ruff-0.15.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:542aaf1de3154cea088ced5a819ce872611256ffe2498e750bbae5247a8114e9", size = 12044201, upload-time = "2026-03-12T23:05:28.697Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/5d/6d/2f5cad8380caf5632a15460c323ae326f1e1a2b5b90a6ee7519017a017ca/ruff-0.15.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a4a42cbb8af0bda9bcd7606b064d7c0bc311a88d141d02f78920be6acb5aa83", size = 11274336, upload-time = "2026-02-12T23:09:14.907Z" },
|
{ url = "https://files.pythonhosted.org/packages/71/68/e6f125df4af7e6d0b498f8d373274794bc5156b324e8ab4bf5c1b4fc0ec7/ruff-0.15.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c22e6f02c16cfac3888aa636e9eba857254d15bbacc9906c9689fdecb1953ab", size = 11421561, upload-time = "2026-03-12T23:05:31.236Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/a3/1d/5f56cae1d6c40b8a318513599b35ea4b075d7dc1cd1d04449578c29d1d75/ruff-0.15.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ab064052c31dddada35079901592dfba2e05f5b1e43af3954aafcbc1096a5b2", size = 11137288, upload-time = "2026-02-12T23:09:07.475Z" },
|
{ url = "https://files.pythonhosted.org/packages/f1/9f/f85ef5fd01a52e0b472b26dc1b4bd228b8f6f0435975442ffa4741278703/ruff-0.15.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98893c4c0aadc8e448cfa315bd0cc343a5323d740fe5f28ef8a3f9e21b381f7e", size = 11310928, upload-time = "2026-03-12T23:05:45.288Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/cd/20/6f8d7d8f768c93b0382b33b9306b3b999918816da46537d5a61635514635/ruff-0.15.1-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:5631c940fe9fe91f817a4c2ea4e81f47bee3ca4aa646134a24374f3c19ad9454", size = 11070681, upload-time = "2026-02-12T23:08:55.43Z" },
|
{ url = "https://files.pythonhosted.org/packages/8c/26/b75f8c421f5654304b89471ed384ae8c7f42b4dff58fa6ce1626d7f2b59a/ruff-0.15.6-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:70d263770d234912374493e8cc1e7385c5d49376e41dfa51c5c3453169dc581c", size = 11235186, upload-time = "2026-03-12T23:05:50.677Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/9a/67/d640ac76069f64cdea59dba02af2e00b1fa30e2103c7f8d049c0cff4cafd/ruff-0.15.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:68138a4ba184b4691ccdc39f7795c66b3c68160c586519e7e8444cf5a53e1b4c", size = 10486401, upload-time = "2026-02-12T23:09:27.927Z" },
|
{ url = "https://files.pythonhosted.org/packages/fc/d4/d5a6d065962ff7a68a86c9b4f5500f7d101a0792078de636526c0edd40da/ruff-0.15.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:55a1ad63c5a6e54b1f21b7514dfadc0c7fb40093fa22e95143cf3f64ebdcd512", size = 10635231, upload-time = "2026-03-12T23:05:37.044Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/65/3d/e1429f64a3ff89297497916b88c32a5cc88eeca7e9c787072d0e7f1d3e1e/ruff-0.15.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:518f9af03bfc33c03bdb4cb63fabc935341bb7f54af500f92ac309ecfbba6330", size = 10197452, upload-time = "2026-02-12T23:09:12.147Z" },
|
{ url = "https://files.pythonhosted.org/packages/d6/56/7c3acf3d50910375349016cf33de24be021532042afbed87942858992491/ruff-0.15.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8dc473ba093c5ec238bb1e7429ee676dca24643c471e11fbaa8a857925b061c0", size = 10340357, upload-time = "2026-03-12T23:06:04.748Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/78/83/e2c3bade17dad63bf1e1c2ffaf11490603b760be149e1419b07049b36ef2/ruff-0.15.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:da79f4d6a826caaea95de0237a67e33b81e6ec2e25fc7e1993a4015dffca7c61", size = 10693900, upload-time = "2026-02-12T23:09:34.418Z" },
|
{ url = "https://files.pythonhosted.org/packages/06/54/6faa39e9c1033ff6a3b6e76b5df536931cd30caf64988e112bbf91ef5ce5/ruff-0.15.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:85b042377c2a5561131767974617006f99f7e13c63c111b998f29fc1e58a4cfb", size = 10860583, upload-time = "2026-03-12T23:05:58.978Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/a1/27/fdc0e11a813e6338e0706e8b39bb7a1d61ea5b36873b351acee7e524a72a/ruff-0.15.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3dd86dccb83cd7d4dcfac303ffc277e6048600dfc22e38158afa208e8bf94a1f", size = 11227302, upload-time = "2026-02-12T23:09:36.536Z" },
|
{ url = "https://files.pythonhosted.org/packages/cb/1e/509a201b843b4dfb0b32acdedf68d951d3377988cae43949ba4c4133a96a/ruff-0.15.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cef49e30bc5a86a6a92098a7fbf6e467a234d90b63305d6f3ec01225a9d092e0", size = 11410976, upload-time = "2026-03-12T23:05:39.955Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f6/58/ac864a75067dcbd3b95be5ab4eb2b601d7fbc3d3d736a27e391a4f92a5c1/ruff-0.15.1-py3-none-win32.whl", hash = "sha256:660975d9cb49b5d5278b12b03bb9951d554543a90b74ed5d366b20e2c57c2098", size = 10462555, upload-time = "2026-02-12T23:09:29.899Z" },
|
{ url = "https://files.pythonhosted.org/packages/6c/25/3fc9114abf979a41673ce877c08016f8e660ad6cf508c3957f537d2e9fa9/ruff-0.15.6-py3-none-win32.whl", hash = "sha256:bbf67d39832404812a2d23020dda68fee7f18ce15654e96fb1d3ad21a5fe436c", size = 10616872, upload-time = "2026-03-12T23:05:42.451Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/e0/5e/d4ccc8a27ecdb78116feac4935dfc39d1304536f4296168f91ed3ec00cd2/ruff-0.15.1-py3-none-win_amd64.whl", hash = "sha256:c820fef9dd5d4172a6570e5721704a96c6679b80cf7be41659ed439653f62336", size = 11599956, upload-time = "2026-02-12T23:09:01.157Z" },
|
{ url = "https://files.pythonhosted.org/packages/89/7a/09ece68445ceac348df06e08bf75db72d0e8427765b96c9c0ffabc1be1d9/ruff-0.15.6-py3-none-win_amd64.whl", hash = "sha256:aee25bc84c2f1007ecb5037dff75cef00414fdf17c23f07dc13e577883dca406", size = 11787271, upload-time = "2026-03-12T23:05:20.168Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/2a/07/5bda6a85b220c64c65686bc85bd0bbb23b29c62b3a9f9433fa55f17cda93/ruff-0.15.1-py3-none-win_arm64.whl", hash = "sha256:5ff7d5f0f88567850f45081fac8f4ec212be8d0b963e385c3f7d0d2eb4899416", size = 10874604, upload-time = "2026-02-12T23:09:05.515Z" },
|
{ url = "https://files.pythonhosted.org/packages/7f/d0/578c47dd68152ddddddf31cd7fc67dc30b7cdf639a86275fda821b0d9d98/ruff-0.15.6-py3-none-win_arm64.whl", hash = "sha256:c34de3dd0b0ba203be50ae70f5910b17188556630e2178fd7d79fc030eb0d837", size = 11060497, upload-time = "2026-03-12T23:05:25.968Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2109,15 +2109,15 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sentry-sdk"
|
name = "sentry-sdk"
|
||||||
version = "2.53.0"
|
version = "2.54.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "certifi" },
|
{ name = "certifi" },
|
||||||
{ name = "urllib3" },
|
{ name = "urllib3" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/d3/06/66c8b705179bc54087845f28fd1b72f83751b6e9a195628e2e9af9926505/sentry_sdk-2.53.0.tar.gz", hash = "sha256:6520ef2c4acd823f28efc55e43eb6ce2e6d9f954a95a3aa96b6fd14871e92b77", size = 412369, upload-time = "2026-02-16T11:11:14.743Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/c8/e9/2e3a46c304e7fa21eaa70612f60354e32699c7102eb961f67448e222ad7c/sentry_sdk-2.54.0.tar.gz", hash = "sha256:2620c2575128d009b11b20f7feb81e4e4e8ae08ec1d36cbc845705060b45cc1b", size = 413813, upload-time = "2026-03-02T15:12:41.355Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/47/d4/2fdf854bc3b9c7f55219678f812600a20a138af2dd847d99004994eada8f/sentry_sdk-2.53.0-py2.py3-none-any.whl", hash = "sha256:46e1ed8d84355ae54406c924f6b290c3d61f4048625989a723fd622aab838899", size = 437908, upload-time = "2026-02-16T11:11:13.227Z" },
|
{ url = "https://files.pythonhosted.org/packages/53/39/be412cc86bc6247b8f69e9383d7950711bd86f8d0a4a4b0fe8fad685bc21/sentry_sdk-2.54.0-py2.py3-none-any.whl", hash = "sha256:fd74e0e281dcda63afff095d23ebcd6e97006102cdc8e78a29f19ecdf796a0de", size = 439198, upload-time = "2026-03-02T15:12:39.546Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2271,11 +2271,11 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "whitenoise"
|
name = "whitenoise"
|
||||||
version = "6.11.0"
|
version = "6.12.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/15/95/8c81ec6b6ebcbf8aca2de7603070ccf37dbb873b03f20708e0f7c1664bc6/whitenoise-6.11.0.tar.gz", hash = "sha256:0f5bfce6061ae6611cd9396a8231e088722e4fc67bc13a111be74c738d99375f", size = 26432, upload-time = "2025-09-18T09:16:10.995Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/cb/2a/55b3f3a4ec326cd077c1c3defeee656b9298372a69229134d930151acd01/whitenoise-6.12.0.tar.gz", hash = "sha256:f723ebb76a112e98816ff80fcea0a6c9b8ecde835f8ddda25df7a30a3c2db6ad", size = 26841, upload-time = "2026-02-27T00:05:42.028Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/6c/e9/4366332f9295fe0647d7d3251ce18f5615fbcb12d02c79a26f8dba9221b3/whitenoise-6.11.0-py3-none-any.whl", hash = "sha256:b2aeb45950597236f53b5342b3121c5de69c8da0109362aee506ce88e022d258", size = 20197, upload-time = "2025-09-18T09:16:09.754Z" },
|
{ url = "https://files.pythonhosted.org/packages/db/eb/d5583a11486211f3ebd4b385545ae787f32363d453c19fffd81106c9c138/whitenoise-6.12.0-py3-none-any.whl", hash = "sha256:fc5e8c572e33ebf24795b47b6a7da8da3c00cff2349f5b04c02f28d0cc5a3cc2", size = 20302, upload-time = "2026-02-27T00:05:40.086Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
FROM node:20-alpine AS frontend-deps
|
FROM node:20-alpine AS frontend-deps
|
||||||
|
|
||||||
|
USER node
|
||||||
|
|
||||||
WORKDIR /home/frontend/
|
WORKDIR /home/frontend/
|
||||||
|
|
||||||
COPY ./src/frontend/package.json ./package.json
|
COPY ./src/frontend/package.json ./package.json
|
||||||
@@ -8,7 +10,7 @@ COPY ./src/frontend/package-lock.json ./package-lock.json
|
|||||||
RUN npm ci
|
RUN npm ci
|
||||||
|
|
||||||
COPY .dockerignore ./.dockerignore
|
COPY .dockerignore ./.dockerignore
|
||||||
COPY ./src/frontend/ .
|
COPY --chown=node:node ./src/frontend/ .
|
||||||
|
|
||||||
### ---- Front-end builder image ----
|
### ---- Front-end builder image ----
|
||||||
FROM frontend-deps AS meet
|
FROM frontend-deps AS meet
|
||||||
@@ -17,6 +19,8 @@ WORKDIR /home/frontend
|
|||||||
|
|
||||||
FROM frontend-deps AS meet-dev
|
FROM frontend-deps AS meet-dev
|
||||||
|
|
||||||
|
USER node
|
||||||
|
|
||||||
WORKDIR /home/frontend
|
WORKDIR /home/frontend
|
||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|||||||
Generated
+19
-15
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "meet",
|
"name": "meet",
|
||||||
"version": "1.10.0",
|
"version": "1.12.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "meet",
|
"name": "meet",
|
||||||
"version": "1.10.0",
|
"version": "1.12.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource-variable/material-symbols-outlined": "5.2.34",
|
"@fontsource-variable/material-symbols-outlined": "5.2.34",
|
||||||
"@fontsource/material-icons-outlined": "5.2.6",
|
"@fontsource/material-icons-outlined": "5.2.6",
|
||||||
@@ -6269,10 +6269,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dompurify": {
|
"node_modules/dompurify": {
|
||||||
"version": "3.3.1",
|
"version": "3.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.2.tgz",
|
||||||
"integrity": "sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==",
|
"integrity": "sha512-6obghkliLdmKa56xdbLOpUZ43pAR6xFy1uOrxBaIDjT+yaRuuybLjGS9eVBoSR/UPU5fq3OXClEHLJNGvbxKpQ==",
|
||||||
"license": "(MPL-2.0 OR Apache-2.0)",
|
"license": "(MPL-2.0 OR Apache-2.0)",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@types/trusted-types": "^2.0.7"
|
"@types/trusted-types": "^2.0.7"
|
||||||
}
|
}
|
||||||
@@ -7158,10 +7161,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/flatted": {
|
"node_modules/flatted": {
|
||||||
"version": "3.3.1",
|
"version": "3.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
|
||||||
"integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
|
"integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/for-each": {
|
"node_modules/for-each": {
|
||||||
"version": "0.3.3",
|
"version": "0.3.3",
|
||||||
@@ -7628,9 +7632,9 @@
|
|||||||
"integrity": "sha512-Rf4YVNYpKjZ6ASAmibcwTNciQ5Co5Ztq6iZPEykHpkoflnD/K5ryE/rHehFsTm4NJj8nKDhbi3eKBWGogmNnkg=="
|
"integrity": "sha512-Rf4YVNYpKjZ6ASAmibcwTNciQ5Co5Ztq6iZPEykHpkoflnD/K5ryE/rHehFsTm4NJj8nKDhbi3eKBWGogmNnkg=="
|
||||||
},
|
},
|
||||||
"node_modules/hono": {
|
"node_modules/hono": {
|
||||||
"version": "4.12.2",
|
"version": "4.12.8",
|
||||||
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.2.tgz",
|
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.8.tgz",
|
||||||
"integrity": "sha512-gJnaDHXKDayjt8ue0n8Gs0A007yKXj4Xzb8+cNjZeYsSzzwKc0Lr+OZgYwVfB0pHfUs17EPoLvrOsEaJ9mj+Tg==",
|
"integrity": "sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -11107,9 +11111,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici": {
|
"node_modules/undici": {
|
||||||
"version": "6.23.0",
|
"version": "6.24.1",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-6.24.1.tgz",
|
||||||
"integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==",
|
"integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.17"
|
"node": ">=18.17"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "meet",
|
"name": "meet",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.10.0",
|
"version": "1.12.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "panda codegen && vite",
|
"dev": "panda codegen && vite",
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 8.9 KiB |
@@ -15,7 +15,19 @@ export const fetchApi = async <T = Record<string, unknown>>(
|
|||||||
...options?.headers,
|
...options?.headers,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
const result = await response.json()
|
|
||||||
|
let result: T
|
||||||
|
if (response.status === 204) {
|
||||||
|
result = undefined as T
|
||||||
|
} else {
|
||||||
|
const contentType = response.headers.get('content-type') ?? ''
|
||||||
|
if (!contentType.includes('application/json')) {
|
||||||
|
result = undefined as T
|
||||||
|
} else {
|
||||||
|
result = (await response.json()) as T
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new ApiError(response.status, result)
|
throw new ApiError(response.status, result)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,4 +5,5 @@ export const keys = {
|
|||||||
requestEntry: 'requestEntry',
|
requestEntry: 'requestEntry',
|
||||||
waitingParticipants: 'waitingParticipants',
|
waitingParticipants: 'waitingParticipants',
|
||||||
roomCreationCallback: 'roomCreationCallback',
|
roomCreationCallback: 'roomCreationCallback',
|
||||||
|
files: 'files',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,13 @@ export interface ApiConfig {
|
|||||||
expiration_days?: number
|
expiration_days?: number
|
||||||
max_duration?: number
|
max_duration?: number
|
||||||
}
|
}
|
||||||
|
background_image: {
|
||||||
|
upload_is_enabled: boolean
|
||||||
|
max_size: number
|
||||||
|
max_count_by_user: number
|
||||||
|
allowed_extensions: string[]
|
||||||
|
allowed_mimetypes: string[]
|
||||||
|
}
|
||||||
subtitle: {
|
subtitle: {
|
||||||
enabled: boolean
|
enabled: boolean
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
import { fetchApi } from '@/api/fetchApi'
|
||||||
|
import { useMutation } from '@tanstack/react-query'
|
||||||
|
import { ApiFileItem } from '@/features/files/api/types.ts'
|
||||||
|
import { keys } from '@/api/queryKeys.ts'
|
||||||
|
import { queryClient } from '@/api/queryClient.ts'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload a file, using XHR so we can report on progress through a handler.
|
||||||
|
*
|
||||||
|
* @param url The URL to PUT the file to.
|
||||||
|
* @param file The file to upload.
|
||||||
|
* @param progressHandler A handler that receives progress updates as a single integer `0 <= x <= 100`.
|
||||||
|
*/
|
||||||
|
export const uploadFile = (
|
||||||
|
url: string,
|
||||||
|
file: File,
|
||||||
|
progressHandler: (progress: number) => void
|
||||||
|
) =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
const xhr = new XMLHttpRequest()
|
||||||
|
xhr.open('PUT', url)
|
||||||
|
xhr.setRequestHeader('X-amz-acl', 'private')
|
||||||
|
xhr.setRequestHeader('Content-Type', file.type)
|
||||||
|
|
||||||
|
xhr.addEventListener('error', reject)
|
||||||
|
xhr.addEventListener('abort', reject)
|
||||||
|
|
||||||
|
xhr.addEventListener('readystatechange', () => {
|
||||||
|
if (xhr.readyState === 4) {
|
||||||
|
if (xhr.status === 200) {
|
||||||
|
// Make sure to always set the progress to 100% when the upload is done.
|
||||||
|
// Because 'progress' event listener is not called when the file size is 0.
|
||||||
|
progressHandler(100)
|
||||||
|
return resolve(true)
|
||||||
|
}
|
||||||
|
reject(new Error(`Failed to perform the upload on ${url}.`))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
xhr.upload.addEventListener('progress', (progressEvent) => {
|
||||||
|
if (progressEvent.lengthComputable) {
|
||||||
|
progressHandler(
|
||||||
|
Math.floor((progressEvent.loaded / progressEvent.total) * 100)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
xhr.send(file)
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asynchronously creates a new file and uploads it to the server.
|
||||||
|
*
|
||||||
|
* @param {object} params - The parameters for the file creation and upload process.
|
||||||
|
* @param {File} params.file - The file object to be uploaded.
|
||||||
|
* @param {function} params.onProgress - A callback function that receives the upload progress as a number (0 to 100).
|
||||||
|
* @returns {Promise<ApiFileItem>} A promise that resolves when the file has been successfully uploaded and the server process is completed.
|
||||||
|
*/
|
||||||
|
export const createFile = async ({
|
||||||
|
file,
|
||||||
|
onProgress,
|
||||||
|
}: {
|
||||||
|
file: File
|
||||||
|
onProgress: (progress: number) => void
|
||||||
|
}): Promise<ApiFileItem> => {
|
||||||
|
const res = await fetchApi<ApiFileItem>(`/files/`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({ filename: file.name, type: 'background_image' }),
|
||||||
|
})
|
||||||
|
if (res.upload_state !== 'pending') {
|
||||||
|
throw new Error('State should be pending right after creation')
|
||||||
|
}
|
||||||
|
const policy = res.policy
|
||||||
|
await uploadFile(policy, file, onProgress)
|
||||||
|
const createdFile = await fetchApi<ApiFileItem>(
|
||||||
|
`/files/${res.id}/upload-ended/`,
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// We invalidate the files query to make sure the new file is immediately available.
|
||||||
|
await queryClient.invalidateQueries({
|
||||||
|
queryKey: [keys.files],
|
||||||
|
})
|
||||||
|
return createdFile
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useCreateFile = () => {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: createFile,
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { fetchApi } from '@/api/fetchApi'
|
||||||
|
import { useMutation, useQueryClient } from '@tanstack/react-query'
|
||||||
|
import { keys } from '@/api/queryKeys.ts'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a file specified by its unique identifier.
|
||||||
|
*
|
||||||
|
* @param {Object} params - The parameters required for deleting the file.
|
||||||
|
* @param {string} params.fileId - The unique identifier of the file to be deleted.
|
||||||
|
* @returns {Promise<void>} A promise that resolves when the file is successfully deleted.
|
||||||
|
*/
|
||||||
|
export const deleteFile = async ({
|
||||||
|
fileId,
|
||||||
|
}: {
|
||||||
|
fileId: string
|
||||||
|
}): Promise<void> => {
|
||||||
|
await fetchApi<void>(`/files/${fileId}/`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useDeleteFile = () => {
|
||||||
|
const queryClient = useQueryClient()
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: deleteFile,
|
||||||
|
onSuccess: async () => {
|
||||||
|
await queryClient.invalidateQueries({
|
||||||
|
queryKey: [keys.files],
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
import { fetchApi } from '@/api/fetchApi'
|
||||||
|
import { keepPreviousData, useQuery } from '@tanstack/react-query'
|
||||||
|
import { keys } from '@/api/queryKeys'
|
||||||
|
import {
|
||||||
|
ApiFileItem,
|
||||||
|
ApiFileType,
|
||||||
|
ApiFileUploadState,
|
||||||
|
} from '@/features/files/api/types.ts'
|
||||||
|
import { useUser } from '@/features/auth'
|
||||||
|
import { useConfig } from '@/api/useConfig.ts'
|
||||||
|
|
||||||
|
type ListFilesResponse = {
|
||||||
|
count: number
|
||||||
|
next: string | null
|
||||||
|
previous: string | null
|
||||||
|
results: ApiFileItem[]
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListFilesFilters = {
|
||||||
|
is_creator_me?: boolean
|
||||||
|
type?: ApiFileType
|
||||||
|
upload_state?: ApiFileUploadState
|
||||||
|
is_deleted?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ListFilesParams = {
|
||||||
|
filters?: ListFilesFilters
|
||||||
|
pagination: {
|
||||||
|
page: number
|
||||||
|
pageSize: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const listMyFiles = async ({
|
||||||
|
filters = {},
|
||||||
|
pagination: { page, pageSize },
|
||||||
|
}: ListFilesParams): Promise<ListFilesResponse> => {
|
||||||
|
const query = new URLSearchParams()
|
||||||
|
query.append('page', page.toString())
|
||||||
|
query.append('page_size', pageSize.toString())
|
||||||
|
if (filters?.is_creator_me ?? true) {
|
||||||
|
query.append('is_creator_me', 'true')
|
||||||
|
}
|
||||||
|
if (filters?.type) {
|
||||||
|
query.append('type', filters.type)
|
||||||
|
}
|
||||||
|
if (filters?.upload_state) {
|
||||||
|
query.append('upload_state', filters.upload_state)
|
||||||
|
}
|
||||||
|
if (typeof filters?.is_deleted === 'boolean') {
|
||||||
|
query.append('is_deleted', filters.is_deleted ? 'true' : 'false')
|
||||||
|
}
|
||||||
|
|
||||||
|
return fetchApi<ListFilesResponse>(`/files?${query.toString()}`, {
|
||||||
|
method: 'GET',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useListMyFiles = (params: Parameters<typeof listMyFiles>[0]) => {
|
||||||
|
const { isLoggedIn } = useUser()
|
||||||
|
const { data: appConfig } = useConfig()
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [keys.files, params],
|
||||||
|
queryFn: () => listMyFiles(params),
|
||||||
|
refetchOnMount: 'always',
|
||||||
|
placeholderData: keepPreviousData,
|
||||||
|
enabled:
|
||||||
|
isLoggedIn && appConfig?.background_image?.upload_is_enabled === true,
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
export type ApiFileCreator = {
|
||||||
|
id: string // UUID
|
||||||
|
full_name: string | null
|
||||||
|
short_name: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ApiFileType = 'background_image'
|
||||||
|
export type ApiFileUploadState = 'pending' | 'ready'
|
||||||
|
|
||||||
|
export type ApiFileItem = {
|
||||||
|
id: string // UUID
|
||||||
|
created_at: string // ISO datetime string
|
||||||
|
updated_at: string // ISO datetime string
|
||||||
|
title: string
|
||||||
|
type: ApiFileType
|
||||||
|
creator: ApiFileCreator
|
||||||
|
deleted_at: string | null
|
||||||
|
hard_deleted_at: string | null
|
||||||
|
filename: string
|
||||||
|
upload_state: ApiFileUploadState
|
||||||
|
mimetype: string // e.g. "image/png"
|
||||||
|
size: number // file size in bytes
|
||||||
|
description: string | null
|
||||||
|
} & (
|
||||||
|
| {
|
||||||
|
upload_state: 'ready'
|
||||||
|
url: string
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
upload_state: 'pending'
|
||||||
|
policy: string
|
||||||
|
url: null
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -215,8 +215,8 @@ export const Conference = ({
|
|||||||
audio={userConfig.audioEnabled}
|
audio={userConfig.audioEnabled}
|
||||||
video={
|
video={
|
||||||
userConfig.videoEnabled && {
|
userConfig.videoEnabled && {
|
||||||
processor: BackgroundProcessorFactory.deserializeProcessor(
|
processor: BackgroundProcessorFactory.fromProcessorConfig(
|
||||||
userConfig.processorSerialized
|
userConfig.processorConfig
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ import { css } from '@/styled-system/css'
|
|||||||
import { Screen } from '@/layout/Screen'
|
import { Screen } from '@/layout/Screen'
|
||||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import {
|
import {
|
||||||
createLocalVideoTrack,
|
|
||||||
createLocalAudioTrack,
|
createLocalAudioTrack,
|
||||||
|
createLocalVideoTrack,
|
||||||
LocalAudioTrack,
|
LocalAudioTrack,
|
||||||
LocalVideoTrack,
|
LocalVideoTrack,
|
||||||
Track,
|
Track,
|
||||||
} from 'livekit-client'
|
} from 'livekit-client'
|
||||||
import { H } from '@/primitives/H'
|
import { H } from '@/primitives/H'
|
||||||
import { Field } from '@/primitives/Field'
|
import { Field } from '@/primitives/Field'
|
||||||
import { Button, Dialog, Text, Form } from '@/primitives'
|
import { Button, Dialog, Form, Text } from '@/primitives'
|
||||||
import { VStack } from '@/styled-system/jsx'
|
import { VStack } from '@/styled-system/jsx'
|
||||||
import { Heading } from 'react-aria-components'
|
import { Heading } from 'react-aria-components'
|
||||||
import { RiImageCircleAiFill } from '@remixicon/react'
|
import { RiImageCircleAiFill } from '@remixicon/react'
|
||||||
@@ -44,8 +44,7 @@ const onError = (e: Error) => console.error('ERROR', e)
|
|||||||
|
|
||||||
const Effects = ({
|
const Effects = ({
|
||||||
videoTrack,
|
videoTrack,
|
||||||
onSubmit,
|
}: Pick<EffectsConfigurationProps, 'videoTrack'>) => {
|
||||||
}: Pick<EffectsConfigurationProps, 'videoTrack' | 'onSubmit'>) => {
|
|
||||||
const { t } = useTranslation('rooms', { keyPrefix: 'join.effects' })
|
const { t } = useTranslation('rooms', { keyPrefix: 'join.effects' })
|
||||||
const [isDialogOpen, setIsDialogOpen] = useState(false)
|
const [isDialogOpen, setIsDialogOpen] = useState(false)
|
||||||
const openDialog = () => setIsDialogOpen(true)
|
const openDialog = () => setIsDialogOpen(true)
|
||||||
@@ -81,7 +80,7 @@ const Effects = ({
|
|||||||
>
|
>
|
||||||
{t('subTitle')}
|
{t('subTitle')}
|
||||||
</Text>
|
</Text>
|
||||||
<EffectsConfiguration videoTrack={videoTrack} onSubmit={onSubmit} />
|
<EffectsConfiguration videoTrack={videoTrack} />
|
||||||
</Dialog>
|
</Dialog>
|
||||||
<Button
|
<Button
|
||||||
variant="whiteCircle"
|
variant="whiteCircle"
|
||||||
@@ -111,7 +110,7 @@ export const Join = ({
|
|||||||
audioDeviceId,
|
audioDeviceId,
|
||||||
audioOutputDeviceId,
|
audioOutputDeviceId,
|
||||||
videoDeviceId,
|
videoDeviceId,
|
||||||
processorSerialized,
|
processorConfig,
|
||||||
username,
|
username,
|
||||||
},
|
},
|
||||||
saveAudioInputEnabled,
|
saveAudioInputEnabled,
|
||||||
@@ -120,7 +119,6 @@ export const Join = ({
|
|||||||
saveAudioInputDeviceId,
|
saveAudioInputDeviceId,
|
||||||
saveVideoInputDeviceId,
|
saveVideoInputDeviceId,
|
||||||
saveUsername,
|
saveUsername,
|
||||||
saveProcessorSerialized,
|
|
||||||
} = usePersistentUserChoices()
|
} = usePersistentUserChoices()
|
||||||
|
|
||||||
const initialUserChoices = useRef<LocalUserChoices | null>(null)
|
const initialUserChoices = useRef<LocalUserChoices | null>(null)
|
||||||
@@ -132,7 +130,7 @@ export const Join = ({
|
|||||||
audioDeviceId,
|
audioDeviceId,
|
||||||
audioOutputDeviceId,
|
audioOutputDeviceId,
|
||||||
videoDeviceId,
|
videoDeviceId,
|
||||||
processorSerialized,
|
processorConfig,
|
||||||
username,
|
username,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,8 +144,8 @@ export const Join = ({
|
|||||||
video: !!initialUserChoices.current &&
|
video: !!initialUserChoices.current &&
|
||||||
initialUserChoices.current?.videoEnabled && {
|
initialUserChoices.current?.videoEnabled && {
|
||||||
deviceId: initialUserChoices.current.videoDeviceId,
|
deviceId: initialUserChoices.current.videoDeviceId,
|
||||||
processor: BackgroundProcessorFactory.deserializeProcessor(
|
processor: BackgroundProcessorFactory.fromProcessorConfig(
|
||||||
initialUserChoices.current.processorSerialized
|
initialUserChoices.current.processorConfig
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -186,9 +184,7 @@ export const Join = ({
|
|||||||
const track = await createLocalVideoTrack({
|
const track = await createLocalVideoTrack({
|
||||||
deviceId: { exact: videoDeviceId },
|
deviceId: { exact: videoDeviceId },
|
||||||
processor:
|
processor:
|
||||||
BackgroundProcessorFactory.deserializeProcessor(
|
BackgroundProcessorFactory.fromProcessorConfig(processorConfig),
|
||||||
processorSerialized
|
|
||||||
),
|
|
||||||
})
|
})
|
||||||
setDynamicVideoTrack(track)
|
setDynamicVideoTrack(track)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -207,7 +203,7 @@ export const Join = ({
|
|||||||
}, [
|
}, [
|
||||||
videoEnabled,
|
videoEnabled,
|
||||||
videoDeviceId,
|
videoDeviceId,
|
||||||
processorSerialized,
|
processorConfig,
|
||||||
previewVideoTrack,
|
previewVideoTrack,
|
||||||
dynamicVideoTrack,
|
dynamicVideoTrack,
|
||||||
])
|
])
|
||||||
@@ -690,12 +686,7 @@ export const Join = ({
|
|||||||
zIndex: '1',
|
zIndex: '1',
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<Effects
|
<Effects videoTrack={videoTrack} />
|
||||||
videoTrack={videoTrack}
|
|
||||||
onSubmit={(processor) =>
|
|
||||||
saveProcessorSerialized(processor?.serialize())
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ import { FullScreenShareWarning } from './FullScreenShareWarning'
|
|||||||
import { ParticipantName } from './ParticipantName'
|
import { ParticipantName } from './ParticipantName'
|
||||||
import { getParticipantName } from '@/features/rooms/utils/getParticipantName'
|
import { getParticipantName } from '@/features/rooms/utils/getParticipantName'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { getShortcutDescriptorById } from '@/features/shortcuts/catalog'
|
||||||
|
import { formatShortcutLabel } from '@/features/shortcuts/formatLabels'
|
||||||
import { KeyboardShortcutHint } from './KeyboardShortcutHint'
|
import { KeyboardShortcutHint } from './KeyboardShortcutHint'
|
||||||
|
|
||||||
export function TrackRefContextIfNeeded(
|
export function TrackRefContextIfNeeded(
|
||||||
@@ -237,7 +239,13 @@ export const ParticipantTile: (
|
|||||||
)}
|
)}
|
||||||
</ParticipantContextIfNeeded>
|
</ParticipantContextIfNeeded>
|
||||||
</TrackRefContextIfNeeded>
|
</TrackRefContextIfNeeded>
|
||||||
<KeyboardShortcutHint>{t('toolbarHint')}</KeyboardShortcutHint>
|
<KeyboardShortcutHint>
|
||||||
|
{t('toolbarHint', {
|
||||||
|
shortcut: formatShortcutLabel(
|
||||||
|
getShortcutDescriptorById('open-shortcuts')?.shortcut
|
||||||
|
),
|
||||||
|
})}
|
||||||
|
</KeyboardShortcutHint>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -149,11 +149,12 @@ export const SidePanel = () => {
|
|||||||
activeSubPanelId,
|
activeSubPanelId,
|
||||||
} = useSidePanel()
|
} = useSidePanel()
|
||||||
const { t } = useTranslation('rooms', { keyPrefix: 'sidePanel' })
|
const { t } = useTranslation('rooms', { keyPrefix: 'sidePanel' })
|
||||||
|
const title = t(`heading.${activeSubPanelId || activePanelId}`)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledSidePanel
|
<StyledSidePanel
|
||||||
title={t(`heading.${activeSubPanelId || activePanelId}`)}
|
title={title}
|
||||||
ariaLabel={t('ariaLabel')}
|
ariaLabel={t('ariaLabel', { title })}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
layoutStore.activePanelId = null
|
layoutStore.activePanelId = null
|
||||||
layoutStore.activeSubPanelId = null
|
layoutStore.activeSubPanelId = null
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ const ToolButton = ({
|
|||||||
<div>
|
<div>
|
||||||
<Text
|
<Text
|
||||||
margin={false}
|
margin={false}
|
||||||
as="h3"
|
as="h2"
|
||||||
className={css({
|
className={css({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
gap: 0.25,
|
gap: 0.25,
|
||||||
|
|||||||
+16
-27
@@ -11,11 +11,7 @@ import {
|
|||||||
TIMEOUT_TICK,
|
TIMEOUT_TICK,
|
||||||
timerWorkerScript,
|
timerWorkerScript,
|
||||||
} from './TimerWorker'
|
} from './TimerWorker'
|
||||||
import {
|
import { BackgroundProcessorInterface, ProcessorConfig, ProcessorType } from '.'
|
||||||
BackgroundProcessorInterface,
|
|
||||||
BackgroundOptions,
|
|
||||||
ProcessorType,
|
|
||||||
} from '.'
|
|
||||||
|
|
||||||
const PROCESSING_WIDTH = 256
|
const PROCESSING_WIDTH = 256
|
||||||
const PROCESSING_HEIGHT = 144
|
const PROCESSING_HEIGHT = 144
|
||||||
@@ -33,7 +29,7 @@ const DEFAULT_BLUR = '10'
|
|||||||
* MediaStreamTrackProcessor.
|
* MediaStreamTrackProcessor.
|
||||||
*/
|
*/
|
||||||
export class BackgroundCustomProcessor implements BackgroundProcessorInterface {
|
export class BackgroundCustomProcessor implements BackgroundProcessorInterface {
|
||||||
options: BackgroundOptions
|
options: ProcessorConfig
|
||||||
name: string
|
name: string
|
||||||
processedTrack?: MediaStreamTrack | undefined
|
processedTrack?: MediaStreamTrack | undefined
|
||||||
|
|
||||||
@@ -64,15 +60,10 @@ export class BackgroundCustomProcessor implements BackgroundProcessorInterface {
|
|||||||
type: ProcessorType
|
type: ProcessorType
|
||||||
virtualBackgroundImage?: HTMLImageElement
|
virtualBackgroundImage?: HTMLImageElement
|
||||||
|
|
||||||
constructor(opts: BackgroundOptions) {
|
constructor(opts: ProcessorConfig) {
|
||||||
this.name = 'blur'
|
this.name = 'blur'
|
||||||
this.options = opts
|
this.options = opts
|
||||||
|
this.type = opts.type
|
||||||
if (this.options.blurRadius) {
|
|
||||||
this.type = ProcessorType.BLUR
|
|
||||||
} else {
|
|
||||||
this.type = ProcessorType.VIRTUAL
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static get isSupported() {
|
static get isSupported() {
|
||||||
@@ -107,6 +98,12 @@ export class BackgroundCustomProcessor implements BackgroundProcessorInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_initVirtualBackgroundImage() {
|
_initVirtualBackgroundImage() {
|
||||||
|
if (this.options.type !== 'virtual') {
|
||||||
|
throw new Error(
|
||||||
|
'Virtual background is only supported for virtual background'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const needsUpdate =
|
const needsUpdate =
|
||||||
this.options.imagePath &&
|
this.options.imagePath &&
|
||||||
this.virtualBackgroundImage &&
|
this.virtualBackgroundImage &&
|
||||||
@@ -118,7 +115,7 @@ export class BackgroundCustomProcessor implements BackgroundProcessorInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(opts: BackgroundOptions): Promise<void> {
|
async update(opts: ProcessorConfig): Promise<void> {
|
||||||
this.options = opts
|
this.options = opts
|
||||||
this._initVirtualBackgroundImage()
|
this._initVirtualBackgroundImage()
|
||||||
}
|
}
|
||||||
@@ -187,7 +184,7 @@ export class BackgroundCustomProcessor implements BackgroundProcessorInterface {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
PROCESSING_WIDTH,
|
PROCESSING_WIDTH,
|
||||||
PROCESSING_WIDTH
|
PROCESSING_HEIGHT
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,6 +209,9 @@ export class BackgroundCustomProcessor implements BackgroundProcessorInterface {
|
|||||||
* TODO: future improvement with WebGL.
|
* TODO: future improvement with WebGL.
|
||||||
*/
|
*/
|
||||||
async blur() {
|
async blur() {
|
||||||
|
if (this.options.type !== 'blur') {
|
||||||
|
throw new Error('Blurring is only supported for blur background')
|
||||||
|
}
|
||||||
const mask = this.imageSegmenterResult!.categoryMask!.getAsUint8Array()
|
const mask = this.imageSegmenterResult!.categoryMask!.getAsUint8Array()
|
||||||
for (let i = 0; i < mask.length; ++i) {
|
for (let i = 0; i < mask.length; ++i) {
|
||||||
this.segmentationMask!.data[i * 4 + 3] = 255 - mask[i]
|
this.segmentationMask!.data[i * 4 + 3] = 255 - mask[i]
|
||||||
@@ -293,7 +293,7 @@ export class BackgroundCustomProcessor implements BackgroundProcessorInterface {
|
|||||||
await this.sizeSource()
|
await this.sizeSource()
|
||||||
await this.segment()
|
await this.segment()
|
||||||
|
|
||||||
if (this.options.blurRadius) {
|
if (this.options.type === 'blur') {
|
||||||
await this.blur()
|
await this.blur()
|
||||||
} else {
|
} else {
|
||||||
await this.drawVirtualBackground()
|
await this.drawVirtualBackground()
|
||||||
@@ -354,15 +354,4 @@ export class BackgroundCustomProcessor implements BackgroundProcessorInterface {
|
|||||||
this.timerWorker?.terminate()
|
this.timerWorker?.terminate()
|
||||||
this.imageSegmenter?.close()
|
this.imageSegmenter?.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
clone() {
|
|
||||||
return new BackgroundCustomProcessor(this.options)
|
|
||||||
}
|
|
||||||
|
|
||||||
serialize() {
|
|
||||||
return {
|
|
||||||
type: this.type,
|
|
||||||
options: this.options,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -332,15 +332,4 @@ export class FaceLandmarksProcessor implements TrackProcessor<Track.Kind> {
|
|||||||
this.timerWorker?.terminate()
|
this.timerWorker?.terminate()
|
||||||
this.faceLandmarker?.close()
|
this.faceLandmarker?.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
clone() {
|
|
||||||
return new FaceLandmarksProcessor(this.options)
|
|
||||||
}
|
|
||||||
|
|
||||||
serialize() {
|
|
||||||
return {
|
|
||||||
type: this.type,
|
|
||||||
options: this.options,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-32
@@ -1,28 +1,23 @@
|
|||||||
import { ProcessorOptions, Track } from 'livekit-client'
|
import { ProcessorOptions, Track } from 'livekit-client'
|
||||||
import {
|
import {
|
||||||
BackgroundBlur,
|
BackgroundBlur,
|
||||||
BackgroundTransformer,
|
|
||||||
ProcessorWrapper,
|
ProcessorWrapper,
|
||||||
VirtualBackground,
|
VirtualBackground,
|
||||||
} from '@livekit/track-processors'
|
} from '@livekit/track-processors'
|
||||||
import {
|
import { ProcessorConfig, BackgroundProcessorInterface, ProcessorType } from '.'
|
||||||
BackgroundOptions,
|
|
||||||
BackgroundProcessorInterface,
|
|
||||||
ProcessorType,
|
|
||||||
} from '.'
|
|
||||||
|
|
||||||
export class UnifiedBackgroundTrackProcessor implements BackgroundProcessorInterface {
|
export class UnifiedBackgroundTrackProcessor implements BackgroundProcessorInterface {
|
||||||
processor: ProcessorWrapper<BackgroundOptions>
|
processor: ProcessorWrapper<{ imagePath?: string; blurRadius?: number }>
|
||||||
opts: BackgroundOptions
|
opts: ProcessorConfig
|
||||||
processorType: ProcessorType
|
processorType: ProcessorType
|
||||||
|
|
||||||
constructor(opts: BackgroundOptions) {
|
constructor(opts: ProcessorConfig) {
|
||||||
this.opts = opts
|
this.opts = opts
|
||||||
|
|
||||||
if (opts.imagePath) {
|
if (opts.type === 'virtual') {
|
||||||
this.processorType = ProcessorType.VIRTUAL
|
this.processorType = ProcessorType.VIRTUAL
|
||||||
this.processor = VirtualBackground(opts.imagePath)
|
this.processor = VirtualBackground(opts.imagePath)
|
||||||
} else if (opts.blurRadius !== undefined) {
|
} else if (opts.type === 'blur') {
|
||||||
this.processorType = ProcessorType.BLUR
|
this.processorType = ProcessorType.BLUR
|
||||||
this.processor = BackgroundBlur(opts.blurRadius)
|
this.processor = BackgroundBlur(opts.blurRadius)
|
||||||
} else {
|
} else {
|
||||||
@@ -44,24 +39,23 @@ export class UnifiedBackgroundTrackProcessor implements BackgroundProcessorInter
|
|||||||
return this.processor.destroy()
|
return this.processor.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(opts: BackgroundOptions): Promise<void> {
|
async update(opts: ProcessorConfig): Promise<void> {
|
||||||
const newProcessorType = opts.imagePath
|
this.opts = opts
|
||||||
? ProcessorType.VIRTUAL
|
|
||||||
: ProcessorType.BLUR
|
const newProcessorType =
|
||||||
|
opts.type === 'virtual' ? ProcessorType.VIRTUAL : ProcessorType.BLUR
|
||||||
|
|
||||||
let processedOpts = opts
|
|
||||||
if (newProcessorType !== this.processorType) {
|
if (newProcessorType !== this.processorType) {
|
||||||
this.processorType = newProcessorType
|
this.processorType = newProcessorType
|
||||||
if (newProcessorType === ProcessorType.VIRTUAL) {
|
if (newProcessorType === ProcessorType.VIRTUAL) {
|
||||||
this.processor.name = 'virtual-background'
|
this.processor.name = 'virtual-background'
|
||||||
processedOpts = { ...opts, blurRadius: undefined }
|
|
||||||
} else {
|
} else {
|
||||||
this.processor.name = 'background-blur'
|
this.processor.name = 'background-blur'
|
||||||
processedOpts = { ...opts, imagePath: undefined }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await this.processor.updateTransformerOptions(processedOpts)
|
await this.processor.updateTransformerOptions(
|
||||||
this.opts = processedOpts
|
opts as { imagePath?: string; blurRadius?: number }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
get name() {
|
get name() {
|
||||||
@@ -73,17 +67,6 @@ export class UnifiedBackgroundTrackProcessor implements BackgroundProcessorInter
|
|||||||
}
|
}
|
||||||
|
|
||||||
get options() {
|
get options() {
|
||||||
return (this.processor.transformer as BackgroundTransformer).options
|
return this.opts
|
||||||
}
|
|
||||||
|
|
||||||
clone() {
|
|
||||||
return new UnifiedBackgroundTrackProcessor(this.options || this.opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
serialize() {
|
|
||||||
return {
|
|
||||||
type: this.processorType,
|
|
||||||
options: this.options,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,23 +2,7 @@ import { ProcessorWrapper } from '@livekit/track-processors'
|
|||||||
import { Track, TrackProcessor } from 'livekit-client'
|
import { Track, TrackProcessor } from 'livekit-client'
|
||||||
import { BackgroundCustomProcessor } from './BackgroundCustomProcessor'
|
import { BackgroundCustomProcessor } from './BackgroundCustomProcessor'
|
||||||
import { UnifiedBackgroundTrackProcessor } from './UnifiedBackgroundTrackProcessor'
|
import { UnifiedBackgroundTrackProcessor } from './UnifiedBackgroundTrackProcessor'
|
||||||
|
import { FaceLandmarksOptions } from './FaceLandmarksProcessor'
|
||||||
export type BackgroundOptions = {
|
|
||||||
blurRadius?: number
|
|
||||||
imagePath?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ProcessorSerialized {
|
|
||||||
type: ProcessorType
|
|
||||||
options: BackgroundOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BackgroundProcessorInterface extends TrackProcessor<Track.Kind> {
|
|
||||||
update(opts: BackgroundOptions): Promise<void>
|
|
||||||
options: BackgroundOptions
|
|
||||||
clone(): BackgroundProcessorInterface
|
|
||||||
serialize(): ProcessorSerialized
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum ProcessorType {
|
export enum ProcessorType {
|
||||||
BLUR = 'blur',
|
BLUR = 'blur',
|
||||||
@@ -26,6 +10,16 @@ export enum ProcessorType {
|
|||||||
FACE_LANDMARKS = 'faceLandmarks',
|
FACE_LANDMARKS = 'faceLandmarks',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ProcessorConfig =
|
||||||
|
| { type: ProcessorType.BLUR; blurRadius: number }
|
||||||
|
| { type: ProcessorType.VIRTUAL; imagePath: string; fileId?: string }
|
||||||
|
| ({ type: ProcessorType.FACE_LANDMARKS } & FaceLandmarksOptions)
|
||||||
|
|
||||||
|
export interface BackgroundProcessorInterface extends TrackProcessor<Track.Kind> {
|
||||||
|
update(opts: ProcessorConfig): Promise<void>
|
||||||
|
options: ProcessorConfig
|
||||||
|
}
|
||||||
|
|
||||||
export class BackgroundProcessorFactory {
|
export class BackgroundProcessorFactory {
|
||||||
static hasModernApiSupport() {
|
static hasModernApiSupport() {
|
||||||
return ProcessorWrapper.hasModernApiSupport
|
return ProcessorWrapper.hasModernApiSupport
|
||||||
@@ -36,28 +30,27 @@ export class BackgroundProcessorFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static getProcessor(
|
static getProcessor(
|
||||||
type: ProcessorType,
|
config: ProcessorConfig
|
||||||
opts: BackgroundOptions
|
|
||||||
): BackgroundProcessorInterface | undefined {
|
): BackgroundProcessorInterface | undefined {
|
||||||
const isBlur = type === ProcessorType.BLUR
|
const isBlur = config.type === ProcessorType.BLUR
|
||||||
const isVirtual = type === ProcessorType.VIRTUAL
|
const isVirtual = config.type === ProcessorType.VIRTUAL
|
||||||
|
|
||||||
if (!isBlur && !isVirtual) return undefined
|
if (!isBlur && !isVirtual) return undefined
|
||||||
|
|
||||||
if (ProcessorWrapper.isSupported) {
|
if (ProcessorWrapper.isSupported) {
|
||||||
return new UnifiedBackgroundTrackProcessor(opts)
|
return new UnifiedBackgroundTrackProcessor(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BackgroundCustomProcessor.isSupported) {
|
if (BackgroundCustomProcessor.isSupported) {
|
||||||
return new BackgroundCustomProcessor(opts)
|
return new BackgroundCustomProcessor(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
static deserializeProcessor(data?: ProcessorSerialized) {
|
static fromProcessorConfig(data?: ProcessorConfig) {
|
||||||
if (data?.type) {
|
if (data) {
|
||||||
return BackgroundProcessorFactory.getProcessor(data?.type, data?.options)
|
return BackgroundProcessorFactory.getProcessor(data)
|
||||||
}
|
}
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,10 +69,10 @@ const SelectDevicePermissions = <T extends string | number>({
|
|||||||
iconComponent={iconComponent}
|
iconComponent={iconComponent}
|
||||||
placeholder={items.length === 0 ? t('loading') : t('select')}
|
placeholder={items.length === 0 ? t('loading') : t('select')}
|
||||||
selectedKey={selectedKey}
|
selectedKey={selectedKey}
|
||||||
onSelectionChange={(key) => {
|
onSelectionChange={async (key) => {
|
||||||
if (key === selectedKey) return
|
if (key === selectedKey) return
|
||||||
|
await setActiveMediaDevice(key as string)
|
||||||
onSubmit?.(key as string)
|
onSubmit?.(key as string)
|
||||||
setActiveMediaDevice(key as string)
|
|
||||||
}}
|
}}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
|||||||
+2
-2
@@ -82,8 +82,8 @@ export const VideoDeviceControl = ({
|
|||||||
*
|
*
|
||||||
* See https://github.com/numerique-gouv/meet/pull/309#issuecomment-2622404121
|
* See https://github.com/numerique-gouv/meet/pull/309#issuecomment-2622404121
|
||||||
*/
|
*/
|
||||||
const processor = BackgroundProcessorFactory.deserializeProcessor(
|
const processor = BackgroundProcessorFactory.fromProcessorConfig(
|
||||||
userChoices.processorSerialized
|
userChoices.processorConfig
|
||||||
)
|
)
|
||||||
|
|
||||||
const toggle = trackProps.toggle as (
|
const toggle = trackProps.toggle as (
|
||||||
|
|||||||
@@ -2,14 +2,12 @@ import { useLocalParticipant } from '@livekit/components-react'
|
|||||||
import { LocalVideoTrack } from 'livekit-client'
|
import { LocalVideoTrack } from 'livekit-client'
|
||||||
import { css } from '@/styled-system/css'
|
import { css } from '@/styled-system/css'
|
||||||
import { EffectsConfiguration } from './EffectsConfiguration'
|
import { EffectsConfiguration } from './EffectsConfiguration'
|
||||||
import { usePersistentUserChoices } from '../../hooks/usePersistentUserChoices'
|
|
||||||
import { useCanPublishTrack } from '@/features/rooms/livekit/hooks/useCanPublishTrack'
|
import { useCanPublishTrack } from '@/features/rooms/livekit/hooks/useCanPublishTrack'
|
||||||
import { TrackSource } from '@livekit/protocol'
|
import { TrackSource } from '@livekit/protocol'
|
||||||
|
|
||||||
export const Effects = () => {
|
export const Effects = () => {
|
||||||
const { cameraTrack } = useLocalParticipant()
|
const { cameraTrack } = useLocalParticipant()
|
||||||
const localCameraTrack = cameraTrack?.track as LocalVideoTrack
|
const localCameraTrack = cameraTrack?.track as LocalVideoTrack
|
||||||
const { saveProcessorSerialized } = usePersistentUserChoices()
|
|
||||||
|
|
||||||
const canPublishCamera = useCanPublishTrack(TrackSource.CAMERA)
|
const canPublishCamera = useCanPublishTrack(TrackSource.CAMERA)
|
||||||
|
|
||||||
@@ -24,9 +22,6 @@ export const Effects = () => {
|
|||||||
isDisabled={!canPublishCamera}
|
isDisabled={!canPublishCamera}
|
||||||
videoTrack={localCameraTrack}
|
videoTrack={localCameraTrack}
|
||||||
layout="vertical"
|
layout="vertical"
|
||||||
onSubmit={(processor) =>
|
|
||||||
saveProcessorSerialized(processor?.serialize())
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
+705
-251
File diff suppressed because it is too large
Load Diff
@@ -27,7 +27,7 @@ export const FunnyEffects = ({
|
|||||||
showFrench: false,
|
showFrench: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return processor.serialize().options
|
return { ...processor.options }
|
||||||
}
|
}
|
||||||
|
|
||||||
const options = getOptions()
|
const options = getOptions()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useSnapshot } from 'valtio'
|
import { useSnapshot } from 'valtio'
|
||||||
import { userChoicesStore } from '@/stores/userChoices'
|
import { userChoicesStore } from '@/stores/userChoices'
|
||||||
import type { VideoResolution } from '@/stores/userChoices'
|
import type { VideoResolution } from '@/stores/userChoices'
|
||||||
import { ProcessorSerialized } from '@/features/rooms/livekit/components/blur'
|
import { ProcessorConfig } from '@/features/rooms/livekit/components/blur'
|
||||||
import type { VideoQuality } from 'livekit-client'
|
import type { VideoQuality } from 'livekit-client'
|
||||||
|
|
||||||
export function usePersistentUserChoices() {
|
export function usePersistentUserChoices() {
|
||||||
@@ -36,10 +36,8 @@ export function usePersistentUserChoices() {
|
|||||||
saveNoiseReductionEnabled: (enabled: boolean) => {
|
saveNoiseReductionEnabled: (enabled: boolean) => {
|
||||||
userChoicesStore.noiseReductionEnabled = enabled
|
userChoicesStore.noiseReductionEnabled = enabled
|
||||||
},
|
},
|
||||||
saveProcessorSerialized: (
|
saveProcessorConfig: (processorConfig: ProcessorConfig | undefined) => {
|
||||||
processorSerialized: ProcessorSerialized | undefined
|
userChoicesStore.processorConfig = processorConfig
|
||||||
) => {
|
|
||||||
userChoicesStore.processorSerialized = processorSerialized
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export const VideoTab = ({ id }: VideoTabProps) => {
|
|||||||
const {
|
const {
|
||||||
userChoices: {
|
userChoices: {
|
||||||
videoDeviceId,
|
videoDeviceId,
|
||||||
processorSerialized,
|
processorConfig,
|
||||||
videoPublishResolution,
|
videoPublishResolution,
|
||||||
videoSubscribeQuality,
|
videoSubscribeQuality,
|
||||||
},
|
},
|
||||||
@@ -78,7 +78,7 @@ export const VideoTab = ({ id }: VideoTabProps) => {
|
|||||||
resolution: VideoPresets[key].resolution,
|
resolution: VideoPresets[key].resolution,
|
||||||
deviceId: { exact: videoDeviceId },
|
deviceId: { exact: videoDeviceId },
|
||||||
processor:
|
processor:
|
||||||
BackgroundProcessorFactory.deserializeProcessor(processorSerialized),
|
BackgroundProcessorFactory.fromProcessorConfig(processorConfig),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,11 @@ import { useSnapshot } from 'valtio'
|
|||||||
import {
|
import {
|
||||||
accessibilityStore,
|
accessibilityStore,
|
||||||
type CaptionTextSize,
|
type CaptionTextSize,
|
||||||
|
type CaptionColor,
|
||||||
CAPTION_TEXT_SIZE_OPTIONS,
|
CAPTION_TEXT_SIZE_OPTIONS,
|
||||||
|
CAPTION_COLOR_OPTIONS,
|
||||||
} from '@/stores/accessibility'
|
} from '@/stores/accessibility'
|
||||||
|
import { useAreSubtitlesAvailable } from '../hooks/useAreSubtitlesAvailable'
|
||||||
|
|
||||||
export const CaptionsSettings = () => {
|
export const CaptionsSettings = () => {
|
||||||
const { t } = useTranslation('settings', {
|
const { t } = useTranslation('settings', {
|
||||||
@@ -24,6 +27,27 @@ export const CaptionsSettings = () => {
|
|||||||
[t]
|
[t]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const captionFontColorItems = useMemo(
|
||||||
|
() =>
|
||||||
|
CAPTION_COLOR_OPTIONS.map((color) => ({
|
||||||
|
value: color,
|
||||||
|
label: t(`fontColor.options.${color}`),
|
||||||
|
})),
|
||||||
|
[t]
|
||||||
|
)
|
||||||
|
|
||||||
|
const captionBackgroundColorItems = useMemo(
|
||||||
|
() =>
|
||||||
|
CAPTION_COLOR_OPTIONS.map((color) => ({
|
||||||
|
value: color,
|
||||||
|
label: t(`backgroundColor.options.${color}`),
|
||||||
|
})),
|
||||||
|
[t]
|
||||||
|
)
|
||||||
|
|
||||||
|
const areSubtitlesAvailable = useAreSubtitlesAvailable()
|
||||||
|
if (!areSubtitlesAvailable) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li>
|
<li>
|
||||||
<H
|
<H
|
||||||
@@ -34,16 +58,44 @@ export const CaptionsSettings = () => {
|
|||||||
>
|
>
|
||||||
{t('heading')}
|
{t('heading')}
|
||||||
</H>
|
</H>
|
||||||
<Field
|
<div
|
||||||
type="select"
|
className={css({
|
||||||
label={t('textSize.label')}
|
display: 'flex',
|
||||||
items={captionTextSizeItems}
|
flexDirection: 'column',
|
||||||
selectedKey={snap.captionTextSize}
|
gap: '0.75rem',
|
||||||
onSelectionChange={(key) => {
|
})}
|
||||||
accessibilityStore.captionTextSize = key as CaptionTextSize
|
>
|
||||||
}}
|
<Field
|
||||||
wrapperProps={{ noMargin: true, fullWidth: true }}
|
type="select"
|
||||||
/>
|
label={t('textSize.label')}
|
||||||
|
items={captionTextSizeItems}
|
||||||
|
selectedKey={snap.captionTextSize}
|
||||||
|
onSelectionChange={(key) => {
|
||||||
|
accessibilityStore.captionTextSize = key as CaptionTextSize
|
||||||
|
}}
|
||||||
|
wrapperProps={{ noMargin: true, fullWidth: true }}
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
type="select"
|
||||||
|
label={t('fontColor.label')}
|
||||||
|
items={captionFontColorItems}
|
||||||
|
selectedKey={snap.captionFontColor}
|
||||||
|
onSelectionChange={(key) => {
|
||||||
|
accessibilityStore.captionFontColor = key as CaptionColor
|
||||||
|
}}
|
||||||
|
wrapperProps={{ noMargin: true, fullWidth: true }}
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
type="select"
|
||||||
|
label={t('backgroundColor.label')}
|
||||||
|
items={captionBackgroundColorItems}
|
||||||
|
selectedKey={snap.captionBackgroundColor}
|
||||||
|
onSelectionChange={(key) => {
|
||||||
|
accessibilityStore.captionBackgroundColor = key as CaptionColor
|
||||||
|
}}
|
||||||
|
wrapperProps={{ noMargin: true, fullWidth: true }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import { useSnapshot } from 'valtio'
|
|||||||
import {
|
import {
|
||||||
accessibilityStore,
|
accessibilityStore,
|
||||||
CAPTION_TEXT_SIZE_OPTIONS,
|
CAPTION_TEXT_SIZE_OPTIONS,
|
||||||
|
CAPTION_FONT_COLOR_VALUES,
|
||||||
|
CAPTION_BACKGROUND_COLOR_VALUES,
|
||||||
type CaptionTextSize,
|
type CaptionTextSize,
|
||||||
} from '@/stores/accessibility'
|
} from '@/stores/accessibility'
|
||||||
|
|
||||||
@@ -92,10 +94,14 @@ const useTranscriptionState = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Transcription = ({ row }: { row: TranscriptionRow }) => {
|
const Transcription = ({ row }: { row: TranscriptionRow }) => {
|
||||||
const { captionTextSize } = useSnapshot(accessibilityStore)
|
const { captionTextSize, captionFontColor, captionBackgroundColor } =
|
||||||
|
useSnapshot(accessibilityStore)
|
||||||
const participantColor = getParticipantColor(row.participant)
|
const participantColor = getParticipantColor(row.participant)
|
||||||
const participantName = getParticipantName(row.participant)
|
const participantName = getParticipantName(row.participant)
|
||||||
const { fontSize, lineHeight } = CAPTION_FONT_SIZES[captionTextSize]
|
const { fontSize, lineHeight } = CAPTION_FONT_SIZES[captionTextSize]
|
||||||
|
const fontColor = CAPTION_FONT_COLOR_VALUES[captionFontColor]
|
||||||
|
const backgroundColor =
|
||||||
|
CAPTION_BACKGROUND_COLOR_VALUES[captionBackgroundColor]
|
||||||
|
|
||||||
const getDisplayText = (row: TranscriptionRow): string => {
|
const getDisplayText = (row: TranscriptionRow): string => {
|
||||||
return row.segments
|
return row.segments
|
||||||
@@ -128,9 +134,9 @@ const Transcription = ({ row }: { row: TranscriptionRow }) => {
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={css({
|
className={css({
|
||||||
color: 'white',
|
|
||||||
width: '100%',
|
width: '100%',
|
||||||
})}
|
})}
|
||||||
|
style={{ color: fontColor }}
|
||||||
>
|
>
|
||||||
<Text variant="h3" margin={false}>
|
<Text variant="h3" margin={false}>
|
||||||
{participantName}
|
{participantName}
|
||||||
@@ -138,8 +144,10 @@ const Transcription = ({ row }: { row: TranscriptionRow }) => {
|
|||||||
<p
|
<p
|
||||||
className={css({
|
className={css({
|
||||||
fontWeight: '400',
|
fontWeight: '400',
|
||||||
|
borderRadius: '4px',
|
||||||
|
padding: '0.125rem 0.25rem',
|
||||||
})}
|
})}
|
||||||
style={{ fontSize, lineHeight }}
|
style={{ fontSize, lineHeight, backgroundColor }}
|
||||||
>
|
>
|
||||||
{displayText}
|
{displayText}
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -273,17 +273,40 @@
|
|||||||
"title": "Virtueller Hintergrund",
|
"title": "Virtueller Hintergrund",
|
||||||
"selectedLabel": "Hintergrund angewendet:",
|
"selectedLabel": "Hintergrund angewendet:",
|
||||||
"apply": "Ersetze deinen Hintergrund:",
|
"apply": "Ersetze deinen Hintergrund:",
|
||||||
"descriptions": {
|
"personal": {
|
||||||
"0": "Gerilltes Holzmöbel",
|
"title": "Meine Hintergründe",
|
||||||
"1": "Besprechungsraum",
|
"selectFileTooltip": "Wähle ein Bild aus, das als persönlicher Hintergrund verwendet werden soll",
|
||||||
"2": "Loft mit schwarzer Glaswand",
|
"notLoggedInWarning": "Du bist nicht angemeldet, der persönliche Hintergrund wird nicht von einem Meeting zum anderen gespeichert.",
|
||||||
"3": "Esszimmer",
|
"warningUploadDisabled": "Persönliche Hintergründe werden derzeit nicht von einem Meeting zum anderen gespeichert.",
|
||||||
"4": "Holzregale",
|
"uploadLimitReached": "Du kannst keine weiteren persönlichen Hintergründe hinzufügen.",
|
||||||
"5": "Holztreppe",
|
"uploadInProgress": "Datei wird hochgeladen…",
|
||||||
"6": "Graue Bibliothek",
|
"errors": {
|
||||||
"7": "Kaffeetheke"
|
"close": "Schließen",
|
||||||
|
"file_too_large": {
|
||||||
|
"title": "Datei zu groß",
|
||||||
|
"description": "Die Datei ist zu groß. Bitte wähle eine Datei mit weniger als {{maxSize, number}} MB."
|
||||||
|
},
|
||||||
|
"invalid_file_type": {
|
||||||
|
"title": "Ungültiger Dateityp",
|
||||||
|
"description": "Der Dateityp wird nicht unterstützt. Bitte wähle eine {{allowedExtension}}-Datei."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"presets": {
|
||||||
|
"title": "Vorschläge",
|
||||||
|
"descriptions": {
|
||||||
|
"0": "Gerilltes Holzmöbel",
|
||||||
|
"1": "Besprechungsraum",
|
||||||
|
"2": "Loft mit schwarzer Glaswand",
|
||||||
|
"3": "Esszimmer",
|
||||||
|
"4": "Holzregale",
|
||||||
|
"5": "Holztreppe",
|
||||||
|
"6": "Graue Bibliothek",
|
||||||
|
"7": "Kaffeetheke"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"faceLandmarks": {
|
"faceLandmarks": {
|
||||||
"title": "Visuelle Effekte",
|
"title": "Visuelle Effekte",
|
||||||
"glasses": {
|
"glasses": {
|
||||||
@@ -297,7 +320,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sidePanel": {
|
"sidePanel": {
|
||||||
"ariaLabel": "Seitenleiste",
|
"ariaLabel": "Seitenleiste - {{title}}",
|
||||||
"backToTools": "Zurück zu den Meeting-Tools",
|
"backToTools": "Zurück zu den Meeting-Tools",
|
||||||
"heading": {
|
"heading": {
|
||||||
"participants": "Teilnehmende",
|
"participants": "Teilnehmende",
|
||||||
@@ -332,11 +355,11 @@
|
|||||||
"tools": {
|
"tools": {
|
||||||
"transcript": {
|
"transcript": {
|
||||||
"title": "Transkribieren",
|
"title": "Transkribieren",
|
||||||
"body": "Das Gespräch aufzeichnen."
|
"body": "Wandelt Meetings in Text um."
|
||||||
},
|
},
|
||||||
"screenRecording": {
|
"screenRecording": {
|
||||||
"title": "Aufzeichnen",
|
"title": "Aufnehmen",
|
||||||
"body": "Das Meeting aufzeichnen."
|
"body": "Speichert Meetings als Video."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -597,7 +620,7 @@
|
|||||||
},
|
},
|
||||||
"participantTileFocus": {
|
"participantTileFocus": {
|
||||||
"containerLabel": "Optionen für {{name}}",
|
"containerLabel": "Optionen für {{name}}",
|
||||||
"toolbarHint": "Ctrl+Shift+/: Direkt auf die Tastenkürzel zugreifen.",
|
"toolbarHint": "{{shortcut}}: Direkt auf die Tastenkürzel zugreifen.",
|
||||||
"pin": {
|
"pin": {
|
||||||
"enable": "Anheften",
|
"enable": "Anheften",
|
||||||
"disable": "Lösen"
|
"disable": "Lösen"
|
||||||
|
|||||||
@@ -126,6 +126,34 @@
|
|||||||
"medium": "Mittel",
|
"medium": "Mittel",
|
||||||
"large": "Groß"
|
"large": "Groß"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"fontColor": {
|
||||||
|
"label": "Schriftfarbe",
|
||||||
|
"options": {
|
||||||
|
"default": "Standard",
|
||||||
|
"white": "Weiß",
|
||||||
|
"black": "Schwarz",
|
||||||
|
"blue": "Blau",
|
||||||
|
"green": "Grün",
|
||||||
|
"red": "Rot",
|
||||||
|
"yellow": "Gelb",
|
||||||
|
"cyan": "Cyan",
|
||||||
|
"magenta": "Magenta"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"backgroundColor": {
|
||||||
|
"label": "Hintergrundfarbe",
|
||||||
|
"options": {
|
||||||
|
"default": "Standard",
|
||||||
|
"white": "Weiß",
|
||||||
|
"black": "Schwarz",
|
||||||
|
"blue": "Blau",
|
||||||
|
"green": "Grün",
|
||||||
|
"red": "Rot",
|
||||||
|
"yellow": "Gelb",
|
||||||
|
"cyan": "Cyan",
|
||||||
|
"magenta": "Magenta"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -270,18 +270,40 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"virtual": {
|
"virtual": {
|
||||||
"title": "Virtual background",
|
"title": "Virtual backgrounds",
|
||||||
"selectedLabel": "Background applied:",
|
"selectedLabel": "Background applied:",
|
||||||
"apply": "Replace your background:",
|
"apply": "Replace your background:",
|
||||||
"descriptions": {
|
"personal": {
|
||||||
"0": "Fluted wooden furniture",
|
"title": "My backgrounds",
|
||||||
"1": "Meeting room",
|
"selectFileTooltip": "Select an image file to use as a personal background",
|
||||||
"2": "Loft with black glass partition",
|
"notLoggedInWarning": "You are not logged-in, personal backgrounds won't be saved from one meeting to the other.",
|
||||||
"3": "Dining room",
|
"warningUploadDisabled": "Personal backgrounds are currently not saved from one meeting to the other.",
|
||||||
"4": "Wooden shelves",
|
"uploadLimitReached": "You cannot upload more personal backgrounds.",
|
||||||
"5": "Wooden staircase",
|
"uploadInProgress": "Image is being uploaded…",
|
||||||
"6": "Gray library",
|
"errors": {
|
||||||
"7": "Coffee counter"
|
"close": "Close",
|
||||||
|
"file_too_large": {
|
||||||
|
"title": "File too large",
|
||||||
|
"description": "The file is too large. Please choose a file smaller than {{maxSize, number}} MB."
|
||||||
|
},
|
||||||
|
"invalid_file_type": {
|
||||||
|
"title": "Invalid file type",
|
||||||
|
"description": "The file type is not supported. Please choose a {{allowedExtension, list(type: 'disjunction')}} file."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"presets": {
|
||||||
|
"title": "Suggestions",
|
||||||
|
"descriptions": {
|
||||||
|
"0": "Fluted wooden furniture",
|
||||||
|
"1": "Meeting room",
|
||||||
|
"2": "Loft with black glass partition",
|
||||||
|
"3": "Dining room",
|
||||||
|
"4": "Wooden shelves",
|
||||||
|
"5": "Wooden staircase",
|
||||||
|
"6": "Gray library",
|
||||||
|
"7": "Coffee counter"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"faceLandmarks": {
|
"faceLandmarks": {
|
||||||
@@ -297,7 +319,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sidePanel": {
|
"sidePanel": {
|
||||||
"ariaLabel": "Sidepanel",
|
"ariaLabel": "Sidepanel - {{title}}",
|
||||||
"backToTools": "Back to meeting tools",
|
"backToTools": "Back to meeting tools",
|
||||||
"heading": {
|
"heading": {
|
||||||
"participants": "Participants",
|
"participants": "Participants",
|
||||||
@@ -332,11 +354,11 @@
|
|||||||
"tools": {
|
"tools": {
|
||||||
"transcript": {
|
"transcript": {
|
||||||
"title": "Transcribe",
|
"title": "Transcribe",
|
||||||
"body": "Record the conversation."
|
"body": "Turn meetings into text."
|
||||||
},
|
},
|
||||||
"screenRecording": {
|
"screenRecording": {
|
||||||
"title": "Record",
|
"title": "Record",
|
||||||
"body": "Record the meeting."
|
"body": "Save meetings as video."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -597,7 +619,7 @@
|
|||||||
},
|
},
|
||||||
"participantTileFocus": {
|
"participantTileFocus": {
|
||||||
"containerLabel": "Options for {{name}}",
|
"containerLabel": "Options for {{name}}",
|
||||||
"toolbarHint": "Ctrl+Shift+/: access shortcuts directly.",
|
"toolbarHint": "{{shortcut}}: access shortcuts directly.",
|
||||||
"pin": {
|
"pin": {
|
||||||
"enable": "Pin",
|
"enable": "Pin",
|
||||||
"disable": "Unpin"
|
"disable": "Unpin"
|
||||||
|
|||||||
@@ -126,6 +126,34 @@
|
|||||||
"medium": "Medium",
|
"medium": "Medium",
|
||||||
"large": "Large"
|
"large": "Large"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"fontColor": {
|
||||||
|
"label": "Font color",
|
||||||
|
"options": {
|
||||||
|
"default": "Default",
|
||||||
|
"white": "White",
|
||||||
|
"black": "Black",
|
||||||
|
"blue": "Blue",
|
||||||
|
"green": "Green",
|
||||||
|
"red": "Red",
|
||||||
|
"yellow": "Yellow",
|
||||||
|
"cyan": "Cyan",
|
||||||
|
"magenta": "Magenta"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"backgroundColor": {
|
||||||
|
"label": "Background color",
|
||||||
|
"options": {
|
||||||
|
"default": "Default",
|
||||||
|
"white": "White",
|
||||||
|
"black": "Black",
|
||||||
|
"blue": "Blue",
|
||||||
|
"green": "Green",
|
||||||
|
"red": "Red",
|
||||||
|
"yellow": "Yellow",
|
||||||
|
"cyan": "Cyan",
|
||||||
|
"magenta": "Magenta"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -270,18 +270,40 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"virtual": {
|
"virtual": {
|
||||||
"title": "Arrière-plan virtuel",
|
"title": "Arrière-plans virtuels",
|
||||||
"selectedLabel": "Arrière-plan appliqué :",
|
"selectedLabel": "Arrière-plan appliqué :",
|
||||||
"apply": "Remplacer votre arrière plan :",
|
"apply": "Remplacer votre arrière plan :",
|
||||||
"descriptions": {
|
"personal": {
|
||||||
"0": "Meuble cannelé en bois",
|
"title": "Mes arrière-plans",
|
||||||
"1": "Salle de réunion",
|
"selectFileTooltip": "Sélectionnez une image à utiliser comme arrière-plan",
|
||||||
"2": "Loft avec verrière noire",
|
"notLoggedInWarning": "Vous n'êtes pas connecté, l'arrière-plan personnel ne sera pas sauvegardé d'une réunion à l'autre.",
|
||||||
"3": "Salle à manger",
|
"warningUploadDisabled": "Les arrière-plans personnels ne sont actuellement pas sauvegardés d'une réunion à l'autre.",
|
||||||
"4": "Étagères en bois",
|
"uploadLimitReached": "Vous ne pouvez pas ajouter plus d'arrière-plans personnels.",
|
||||||
"5": "Escalier en bois",
|
"uploadInProgress": "Image en cours d'envoi…",
|
||||||
"6": "Bibliothèque grise",
|
"errors": {
|
||||||
"7": "Comptoir de café"
|
"close": "Fermer",
|
||||||
|
"file_too_large": {
|
||||||
|
"title": "Fichier trop volumineux",
|
||||||
|
"description": "Le fichier est trop volumineux. Veuillez choisir un fichier de moins de {{maxSize, number}} Mo."
|
||||||
|
},
|
||||||
|
"invalid_file_type": {
|
||||||
|
"title": "Type de fichier non valide",
|
||||||
|
"description": "Le type de fichier n'est pas pris en charge. Veuillez choisir un fichier {{allowedExtension}}."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"presets": {
|
||||||
|
"title": "Suggestions",
|
||||||
|
"descriptions": {
|
||||||
|
"0": "Meuble cannelé en bois",
|
||||||
|
"1": "Salle de réunion",
|
||||||
|
"2": "Loft avec verrière noire",
|
||||||
|
"3": "Salle à manger",
|
||||||
|
"4": "Étagères en bois",
|
||||||
|
"5": "Escalier en bois",
|
||||||
|
"6": "Bibliothèque grise",
|
||||||
|
"7": "Comptoir de café"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"faceLandmarks": {
|
"faceLandmarks": {
|
||||||
@@ -297,7 +319,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sidePanel": {
|
"sidePanel": {
|
||||||
"ariaLabel": "Panneau latéral",
|
"ariaLabel": "Panneau latéral - {{title}}",
|
||||||
"backToTools": "Retour aux outils de réunion",
|
"backToTools": "Retour aux outils de réunion",
|
||||||
"heading": {
|
"heading": {
|
||||||
"participants": "Participants",
|
"participants": "Participants",
|
||||||
@@ -332,11 +354,11 @@
|
|||||||
"tools": {
|
"tools": {
|
||||||
"transcript": {
|
"transcript": {
|
||||||
"title": "Transcrire",
|
"title": "Transcrire",
|
||||||
"body": "Enregistrer la conversation."
|
"body": "Transcrire la réunion."
|
||||||
},
|
},
|
||||||
"screenRecording": {
|
"screenRecording": {
|
||||||
"title": "Enregistrer",
|
"title": "Enregistrer",
|
||||||
"body": "Enregistrer la réunion."
|
"body": "Enregistrer la réunion en vidéo."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -597,7 +619,7 @@
|
|||||||
},
|
},
|
||||||
"participantTileFocus": {
|
"participantTileFocus": {
|
||||||
"containerLabel": "Options pour {{name}}",
|
"containerLabel": "Options pour {{name}}",
|
||||||
"toolbarHint": "Ctrl+Shift+/ : accéder directement aux raccourcis.",
|
"toolbarHint": "{{shortcut}} : accéder directement aux raccourcis.",
|
||||||
"pin": {
|
"pin": {
|
||||||
"enable": "Épingler",
|
"enable": "Épingler",
|
||||||
"disable": "Annuler l'épinglage"
|
"disable": "Annuler l'épinglage"
|
||||||
|
|||||||
@@ -126,6 +126,34 @@
|
|||||||
"medium": "Moyen",
|
"medium": "Moyen",
|
||||||
"large": "Grand"
|
"large": "Grand"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"fontColor": {
|
||||||
|
"label": "Couleur du texte",
|
||||||
|
"options": {
|
||||||
|
"default": "Par défaut",
|
||||||
|
"white": "Blanc",
|
||||||
|
"black": "Noir",
|
||||||
|
"blue": "Bleu",
|
||||||
|
"green": "Vert",
|
||||||
|
"red": "Rouge",
|
||||||
|
"yellow": "Jaune",
|
||||||
|
"cyan": "Cyan",
|
||||||
|
"magenta": "Magenta"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"backgroundColor": {
|
||||||
|
"label": "Couleur de fond",
|
||||||
|
"options": {
|
||||||
|
"default": "Par défaut",
|
||||||
|
"white": "Blanc",
|
||||||
|
"black": "Noir",
|
||||||
|
"blue": "Bleu",
|
||||||
|
"green": "Vert",
|
||||||
|
"red": "Rouge",
|
||||||
|
"yellow": "Jaune",
|
||||||
|
"cyan": "Cyan",
|
||||||
|
"magenta": "Magenta"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -273,15 +273,37 @@
|
|||||||
"title": "Virtuele achtergrond",
|
"title": "Virtuele achtergrond",
|
||||||
"selectedLabel": "Achtergrond toegepast:",
|
"selectedLabel": "Achtergrond toegepast:",
|
||||||
"apply": "Vervang je achtergrond:",
|
"apply": "Vervang je achtergrond:",
|
||||||
"descriptions": {
|
"personal": {
|
||||||
"0": "Geprofileerd houten meubel",
|
"title": "Mijn achtergronden",
|
||||||
"1": "Vergaderruimte",
|
"selectFileTooltip": "Selecteer een afbeeldingsbestand om te gebruiken als persoonlijke achtergrond",
|
||||||
"2": "Loft met zwarte glaswand",
|
"notLoggedInWarning": "U bent niet ingelogd, persoonlijke achtergronden worden niet opgeslagen van de ene vergadering naar de andere.",
|
||||||
"3": "Eetkamer",
|
"warningUploadDisabled": "Persoonlijke achtergronden worden momenteel niet opgeslagen van de ene vergadering naar de andere.",
|
||||||
"4": "Houten planken",
|
"uploadLimitReached": "U kunt geen persoonlijke achtergronden meer uploaden.",
|
||||||
"5": "Houten trap",
|
"uploadInProgress": "Afbeelding wordt geüpload…",
|
||||||
"6": "Grijze bibliotheek",
|
"errors": {
|
||||||
"7": "Koffiebar"
|
"close": "Sluiten",
|
||||||
|
"file_too_large": {
|
||||||
|
"title": "Bestand te groot",
|
||||||
|
"description": "Het bestand is te groot. Kies een bestand kleiner dan {{maxSize, number}} MB."
|
||||||
|
},
|
||||||
|
"invalid_file_type": {
|
||||||
|
"title": "Ongeldig bestandstype",
|
||||||
|
"description": "Het bestandstype wordt niet ondersteund. Kies een {{allowedExtension, list(type: 'disjunction')}} bestand."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"presets": {
|
||||||
|
"title": "Suggesties",
|
||||||
|
"descriptions": {
|
||||||
|
"0": "Geprofileerd houten meubel",
|
||||||
|
"1": "Vergaderruimte",
|
||||||
|
"2": "Loft met zwarte glaswand",
|
||||||
|
"3": "Eetkamer",
|
||||||
|
"4": "Houten planken",
|
||||||
|
"5": "Houten trap",
|
||||||
|
"6": "Grijze bibliotheek",
|
||||||
|
"7": "Koffiebar"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"faceLandmarks": {
|
"faceLandmarks": {
|
||||||
@@ -297,7 +319,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sidePanel": {
|
"sidePanel": {
|
||||||
"ariaLabel": "Zijbalk",
|
"ariaLabel": "Zijbalk - {{title}}",
|
||||||
"backToTools": "Terug naar vergadertools",
|
"backToTools": "Terug naar vergadertools",
|
||||||
"heading": {
|
"heading": {
|
||||||
"participants": "Deelnemers",
|
"participants": "Deelnemers",
|
||||||
@@ -332,11 +354,11 @@
|
|||||||
"tools": {
|
"tools": {
|
||||||
"transcript": {
|
"transcript": {
|
||||||
"title": "Transcriberen",
|
"title": "Transcriberen",
|
||||||
"body": "Het gesprek opnemen."
|
"body": "Zet vergaderingen om in tekst."
|
||||||
},
|
},
|
||||||
"screenRecording": {
|
"screenRecording": {
|
||||||
"title": "Opnemen",
|
"title": "Opnemen",
|
||||||
"body": "De vergadering opnemen."
|
"body": "Sla vergaderingen op als video."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -597,7 +619,7 @@
|
|||||||
},
|
},
|
||||||
"participantTileFocus": {
|
"participantTileFocus": {
|
||||||
"containerLabel": "Opties voor {{name}}",
|
"containerLabel": "Opties voor {{name}}",
|
||||||
"toolbarHint": "Ctrl+Shift+/: direct toegang tot de sneltoetsen.",
|
"toolbarHint": "{{shortcut}}: direct toegang tot de sneltoetsen.",
|
||||||
"pin": {
|
"pin": {
|
||||||
"enable": "Pinnen",
|
"enable": "Pinnen",
|
||||||
"disable": "Losmaken"
|
"disable": "Losmaken"
|
||||||
|
|||||||
@@ -126,6 +126,34 @@
|
|||||||
"medium": "Gemiddeld",
|
"medium": "Gemiddeld",
|
||||||
"large": "Groot"
|
"large": "Groot"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"fontColor": {
|
||||||
|
"label": "Tekstkleur",
|
||||||
|
"options": {
|
||||||
|
"default": "Standaard",
|
||||||
|
"white": "Wit",
|
||||||
|
"black": "Zwart",
|
||||||
|
"blue": "Blauw",
|
||||||
|
"green": "Groen",
|
||||||
|
"red": "Rood",
|
||||||
|
"yellow": "Geel",
|
||||||
|
"cyan": "Cyaan",
|
||||||
|
"magenta": "Magenta"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"backgroundColor": {
|
||||||
|
"label": "Achtergrondkleur",
|
||||||
|
"options": {
|
||||||
|
"default": "Standaard",
|
||||||
|
"white": "Wit",
|
||||||
|
"black": "Zwart",
|
||||||
|
"blue": "Blauw",
|
||||||
|
"green": "Groen",
|
||||||
|
"red": "Rood",
|
||||||
|
"yellow": "Geel",
|
||||||
|
"cyan": "Cyaan",
|
||||||
|
"magenta": "Magenta"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -20,7 +20,11 @@ export const Spinner = ({
|
|||||||
const r = 14 - strokeWidth
|
const r = 14 - strokeWidth
|
||||||
const c = 2 * r * Math.PI
|
const c = 2 * r * Math.PI
|
||||||
return (
|
return (
|
||||||
<ProgressBar aria-label="Loading..." value={30}>
|
<ProgressBar
|
||||||
|
aria-label="Loading..."
|
||||||
|
value={30}
|
||||||
|
style={{ height: size, width: size }}
|
||||||
|
>
|
||||||
{({ percentage }) => (
|
{({ percentage }) => (
|
||||||
<div
|
<div
|
||||||
className={css({
|
className={css({
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ export const text = cva({
|
|||||||
textStyle: 'body',
|
textStyle: 'body',
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
},
|
},
|
||||||
|
bodyXsMedium: {
|
||||||
|
textStyle: 'body',
|
||||||
|
fontWeight: 'medium',
|
||||||
|
},
|
||||||
body: {
|
body: {
|
||||||
textStyle: 'body',
|
textStyle: 'body',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -10,14 +10,65 @@ export const CAPTION_TEXT_SIZE_OPTIONS: CaptionTextSize[] = [
|
|||||||
'large',
|
'large',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
export type CaptionColor =
|
||||||
|
| 'default'
|
||||||
|
| 'white'
|
||||||
|
| 'black'
|
||||||
|
| 'blue'
|
||||||
|
| 'green'
|
||||||
|
| 'red'
|
||||||
|
| 'yellow'
|
||||||
|
| 'cyan'
|
||||||
|
| 'magenta'
|
||||||
|
|
||||||
|
export const CAPTION_COLOR_OPTIONS: CaptionColor[] = [
|
||||||
|
'default',
|
||||||
|
'white',
|
||||||
|
'black',
|
||||||
|
'blue',
|
||||||
|
'green',
|
||||||
|
'red',
|
||||||
|
'yellow',
|
||||||
|
'cyan',
|
||||||
|
'magenta',
|
||||||
|
]
|
||||||
|
|
||||||
|
export const CAPTION_FONT_COLOR_VALUES: Record<CaptionColor, string> = {
|
||||||
|
default: '#FFFFFF',
|
||||||
|
white: '#FFFFFF',
|
||||||
|
black: '#000000',
|
||||||
|
blue: '#0000FF',
|
||||||
|
green: '#00FF00',
|
||||||
|
red: '#FF0000',
|
||||||
|
yellow: '#FFFF00',
|
||||||
|
cyan: '#00FFFF',
|
||||||
|
magenta: '#FF00FF',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CAPTION_BACKGROUND_COLOR_VALUES: Record<CaptionColor, string> = {
|
||||||
|
default: 'rgba(0, 0, 0, 0.75)',
|
||||||
|
black: 'rgba(0, 0, 0, 0.75)',
|
||||||
|
white: 'rgba(255, 255, 255, 0.75)',
|
||||||
|
blue: 'rgba(0, 0, 255, 0.75)',
|
||||||
|
green: 'rgba(0, 255, 0, 0.75)',
|
||||||
|
red: 'rgba(255, 0, 0, 0.75)',
|
||||||
|
yellow: 'rgba(255, 255, 0, 0.75)',
|
||||||
|
cyan: 'rgba(0, 255, 255, 0.75)',
|
||||||
|
magenta: 'rgba(255, 0, 255, 0.75)',
|
||||||
|
}
|
||||||
|
|
||||||
type AccessibilityState = {
|
type AccessibilityState = {
|
||||||
announceReactions: boolean
|
announceReactions: boolean
|
||||||
captionTextSize: CaptionTextSize
|
captionTextSize: CaptionTextSize
|
||||||
|
captionFontColor: CaptionColor
|
||||||
|
captionBackgroundColor: CaptionColor
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_STATE: AccessibilityState = {
|
const DEFAULT_STATE: AccessibilityState = {
|
||||||
announceReactions: false,
|
announceReactions: false,
|
||||||
captionTextSize: 'medium',
|
captionTextSize: 'medium',
|
||||||
|
captionFontColor: 'default',
|
||||||
|
captionBackgroundColor: 'default',
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAccessibilityState(): AccessibilityState {
|
function getAccessibilityState(): AccessibilityState {
|
||||||
@@ -25,10 +76,21 @@ function getAccessibilityState(): AccessibilityState {
|
|||||||
const stored = localStorage.getItem(STORAGE_KEYS.ACCESSIBILITY)
|
const stored = localStorage.getItem(STORAGE_KEYS.ACCESSIBILITY)
|
||||||
if (stored) {
|
if (stored) {
|
||||||
const parsed = JSON.parse(stored)
|
const parsed = JSON.parse(stored)
|
||||||
const validCaptionSizes = CAPTION_TEXT_SIZE_OPTIONS
|
const captionTextSize = CAPTION_TEXT_SIZE_OPTIONS.includes(
|
||||||
const captionTextSize = validCaptionSizes.includes(parsed.captionTextSize)
|
parsed.captionTextSize
|
||||||
|
)
|
||||||
? parsed.captionTextSize
|
? parsed.captionTextSize
|
||||||
: DEFAULT_STATE.captionTextSize
|
: DEFAULT_STATE.captionTextSize
|
||||||
|
const captionFontColor = CAPTION_COLOR_OPTIONS.includes(
|
||||||
|
parsed.captionFontColor
|
||||||
|
)
|
||||||
|
? parsed.captionFontColor
|
||||||
|
: DEFAULT_STATE.captionFontColor
|
||||||
|
const captionBackgroundColor = CAPTION_COLOR_OPTIONS.includes(
|
||||||
|
parsed.captionBackgroundColor
|
||||||
|
)
|
||||||
|
? parsed.captionBackgroundColor
|
||||||
|
: DEFAULT_STATE.captionBackgroundColor
|
||||||
return {
|
return {
|
||||||
...DEFAULT_STATE,
|
...DEFAULT_STATE,
|
||||||
...parsed,
|
...parsed,
|
||||||
@@ -37,6 +99,8 @@ function getAccessibilityState(): AccessibilityState {
|
|||||||
? parsed.announceReactions
|
? parsed.announceReactions
|
||||||
: DEFAULT_STATE.announceReactions,
|
: DEFAULT_STATE.announceReactions,
|
||||||
captionTextSize,
|
captionTextSize,
|
||||||
|
captionFontColor,
|
||||||
|
captionBackgroundColor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
import { proxy, subscribe } from 'valtio'
|
import { proxy, subscribe } from 'valtio'
|
||||||
import { ProcessorSerialized } from '@/features/rooms/livekit/components/blur'
|
import {
|
||||||
|
ProcessorConfig,
|
||||||
|
ProcessorType,
|
||||||
|
} from '@/features/rooms/livekit/components/blur'
|
||||||
import {
|
import {
|
||||||
loadUserChoices,
|
loadUserChoices,
|
||||||
saveUserChoices,
|
|
||||||
LocalUserChoices as LocalUserChoicesLK,
|
LocalUserChoices as LocalUserChoicesLK,
|
||||||
|
saveUserChoices,
|
||||||
} from '@livekit/components-core'
|
} from '@livekit/components-core'
|
||||||
import { VideoQuality } from 'livekit-client'
|
import { VideoQuality } from 'livekit-client'
|
||||||
|
|
||||||
export type VideoResolution = 'h720' | 'h360' | 'h180'
|
export type VideoResolution = 'h720' | 'h360' | 'h180'
|
||||||
|
|
||||||
export type LocalUserChoices = LocalUserChoicesLK & {
|
export type LocalUserChoices = LocalUserChoicesLK & {
|
||||||
processorSerialized?: ProcessorSerialized
|
processorConfig?: ProcessorConfig
|
||||||
noiseReductionEnabled?: boolean
|
noiseReductionEnabled?: boolean
|
||||||
audioOutputDeviceId?: string
|
audioOutputDeviceId?: string
|
||||||
videoPublishResolution?: VideoResolution
|
videoPublishResolution?: VideoResolution
|
||||||
@@ -28,7 +31,33 @@ function getUserChoicesState(): LocalUserChoices {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const userChoicesStore = proxy<LocalUserChoices>(getUserChoicesState())
|
export const userChoicesStore = proxy<LocalUserChoices>(getUserChoicesState())
|
||||||
|
|
||||||
subscribe(userChoicesStore, () => {
|
subscribe(userChoicesStore, () => {
|
||||||
saveUserChoices(userChoicesStore, false)
|
saveUserChoices(userChoicesStore, false)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// we run some logic on store loading to check if the processor config is still valid
|
||||||
|
if (userChoicesStore.processorConfig?.type === ProcessorType.VIRTUAL) {
|
||||||
|
if (userChoicesStore.processorConfig.imagePath.startsWith('blob:')) {
|
||||||
|
// this happens when a not authenticated user had changed their background image
|
||||||
|
// we restore clear the processor config to avoid displaying a black screen.
|
||||||
|
userChoicesStore.processorConfig = undefined
|
||||||
|
} else if (userChoicesStore.processorConfig.fileId) {
|
||||||
|
// Checking if the image is still available / accessible
|
||||||
|
await fetch(userChoicesStore.processorConfig.imagePath, {
|
||||||
|
// We bypass the cache to ensure we have access
|
||||||
|
cache: 'reload',
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
// if we cannot fetch the image (likely a 401 from the backend because
|
||||||
|
// the user is not logged in anymore, etc.),
|
||||||
|
// we clear the processor config to avoid displaying a black screen.
|
||||||
|
// This can happen when the user logs out for instance, etc.
|
||||||
|
if (!response.ok) {
|
||||||
|
userChoicesStore.processorConfig = undefined
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
userChoicesStore.processorConfig = undefined
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -95,3 +95,14 @@ html:has(.lk-video-conference) {
|
|||||||
U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
|
U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
|
||||||
U+2212, U+2215, U+FEFF, U+FFFD;
|
U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hoverGroup .hoverGroupChild {
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hoverGroup:hover .hoverGroupChild,
|
||||||
|
.hoverGroup:focus-within .hoverGroupChild {
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,6 +14,14 @@ export default defineConfig(({ mode }) => {
|
|||||||
port: parseInt(env.VITE_PORT) || 3000,
|
port: parseInt(env.VITE_PORT) || 3000,
|
||||||
host: env.VITE_HOST ?? 'localhost',
|
host: env.VITE_HOST ?? 'localhost',
|
||||||
allowedHosts: ['.nip.io'],
|
allowedHosts: ['.nip.io'],
|
||||||
|
// In a local dev setup, we proxy the media server ourselves to avoid CORS issues
|
||||||
|
proxy: {
|
||||||
|
'/media': {
|
||||||
|
target: 'http://localhost:8083',
|
||||||
|
changeOrigin: true,
|
||||||
|
secure: false
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
.podSecurityContext: &podSecurityContext
|
||||||
|
runAsUser: 1000
|
||||||
|
runAsGroup: 1000
|
||||||
|
fsGroup: 1000
|
||||||
|
fsGroupChangePolicy: "OnRootMismatch"
|
||||||
|
runAsNonRoot: true
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
|
||||||
|
.securityContext: &securityContext
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
podSecurityContext: *podSecurityContext
|
||||||
|
securityContext: *securityContext
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "128Mi"
|
||||||
|
|
||||||
|
backend:
|
||||||
|
podSecurityContext: *podSecurityContext
|
||||||
|
securityContext: *securityContext
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "600Mi"
|
||||||
|
|
||||||
|
summary:
|
||||||
|
podSecurityContext: *podSecurityContext
|
||||||
|
securityContext: *securityContext
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "128Mi"
|
||||||
|
|
||||||
|
celeryTranscribe:
|
||||||
|
podSecurityContext: *podSecurityContext
|
||||||
|
securityContext: *securityContext
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "500Mi"
|
||||||
|
|
||||||
|
celerySummarize:
|
||||||
|
podSecurityContext: *podSecurityContext
|
||||||
|
securityContext: *securityContext
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "128Mi"
|
||||||
|
|
||||||
|
agents:
|
||||||
|
podSecurityContext: *podSecurityContext
|
||||||
|
securityContext: *securityContext
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "256Mi"
|
||||||
@@ -23,6 +23,18 @@ egress:
|
|||||||
endpoint: http://minio:9000
|
endpoint: http://minio:9000
|
||||||
force_path_style: true
|
force_path_style: true
|
||||||
|
|
||||||
|
podSecurityContext:
|
||||||
|
fsGroup: 1000
|
||||||
|
fsGroupChangePolicy: "OnRootMismatch"
|
||||||
|
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
|
||||||
loadBalancer:
|
loadBalancer:
|
||||||
type: nginx
|
type: nginx
|
||||||
annotations:
|
annotations:
|
||||||
@@ -40,4 +52,7 @@ autoscaling:
|
|||||||
maxReplicas: 5
|
maxReplicas: 5
|
||||||
|
|
||||||
nodeSelector: {}
|
nodeSelector: {}
|
||||||
resources: {}
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 5000m
|
||||||
|
memory: 1024Mi
|
||||||
@@ -28,6 +28,16 @@ livekit:
|
|||||||
urls:
|
urls:
|
||||||
- https://meet.127.0.0.1.nip.io/api/v1.0/rooms/webhooks-livekit/
|
- https://meet.127.0.0.1.nip.io/api/v1.0/rooms/webhooks-livekit/
|
||||||
|
|
||||||
|
podSecurityContext:
|
||||||
|
fsGroup: 2000
|
||||||
|
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
|
||||||
loadBalancer:
|
loadBalancer:
|
||||||
type: nginx
|
type: nginx
|
||||||
|
|||||||
@@ -1,3 +1,29 @@
|
|||||||
|
_summaryEnvVars: &summaryEnvVars
|
||||||
|
APP_NAME: summary-microservice
|
||||||
|
APP_API_TOKEN: password
|
||||||
|
AWS_STORAGE_BUCKET_NAME: meet-media-storage
|
||||||
|
AWS_S3_ENDPOINT_URL: http://minio.meet.svc.cluster.local:9000/
|
||||||
|
AWS_S3_ACCESS_KEY_ID: meet
|
||||||
|
AWS_S3_SECRET_ACCESS_KEY: password
|
||||||
|
AWS_S3_SECURE_ACCESS: False
|
||||||
|
WHISPERX_API_KEY: your-secret-value
|
||||||
|
WHISPERX_BASE_URL: https://configure-your-url.com
|
||||||
|
WHISPERX_ASR_MODEL: large-v2
|
||||||
|
WHISPERX_DEFAULT_LANGUAGE: fr
|
||||||
|
LLM_BASE_URL: https://configure-your-url.com
|
||||||
|
LLM_API_KEY: your-secret-value
|
||||||
|
LLM_MODEL: meta-llama/Llama-3.1-8B-Instruct
|
||||||
|
WEBHOOK_API_TOKEN: password
|
||||||
|
WEBHOOK_URL: https://www.mock-impress.com/webhook/
|
||||||
|
CELERY_BROKER_URL: redis://default:pass@redis-master:6379/1
|
||||||
|
CELERY_RESULT_BACKEND: redis://default:pass@redis-master:6379/1
|
||||||
|
TASK_TRACKER_REDIS_URL: redis://default:pass@redis-master:6379/1
|
||||||
|
|
||||||
|
_summaryImage: &summaryImage
|
||||||
|
repository: localhost:5001/meet-summary
|
||||||
|
pullPolicy: Always
|
||||||
|
tag: "latest"
|
||||||
|
|
||||||
image:
|
image:
|
||||||
repository: localhost:5001/meet-backend
|
repository: localhost:5001/meet-backend
|
||||||
pullPolicy: Always
|
pullPolicy: Always
|
||||||
@@ -136,72 +162,21 @@ ingressWebhook:
|
|||||||
posthog:
|
posthog:
|
||||||
ingress:
|
ingress:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
ingressAssets:
|
ingressAssets:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
summary:
|
summary:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
|
image: *summaryImage
|
||||||
envVars:
|
envVars:
|
||||||
APP_NAME: summary-microservice
|
<<: *summaryEnvVars
|
||||||
APP_API_TOKEN: password
|
|
||||||
AWS_STORAGE_BUCKET_NAME: meet-media-storage
|
|
||||||
AWS_S3_ENDPOINT_URL: minio.meet.svc.cluster.local:9000
|
|
||||||
AWS_S3_ACCESS_KEY_ID: meet
|
|
||||||
AWS_S3_SECRET_ACCESS_KEY: password
|
|
||||||
AWS_S3_SECURE_ACCESS: False
|
|
||||||
WHISPERX_API_KEY: your-secret-value
|
|
||||||
WHISPERX_BASE_URL: https://configure-your-url.com
|
|
||||||
WHISPERX_ASR_MODEL: large-v2
|
|
||||||
LLM_BASE_URL: https://configure-your-url.com
|
|
||||||
LLM_API_KEY: your-secret-value
|
|
||||||
LLM_MODEL: meta-llama/Llama-3.1-8B-Instruct
|
|
||||||
WEBHOOK_API_TOKEN: password
|
|
||||||
WEBHOOK_URL: https://www.mock-impress.com/webhook/
|
|
||||||
CELERY_BROKER_URL: redis://default:pass@redis-master:6379/1
|
|
||||||
CELERY_RESULT_BACKEND: redis://default:pass@redis-master:6379/1
|
|
||||||
|
|
||||||
image:
|
|
||||||
repository: localhost:5001/meet-summary
|
|
||||||
pullPolicy: Always
|
|
||||||
tag: "latest"
|
|
||||||
|
|
||||||
command:
|
|
||||||
- "uvicorn"
|
|
||||||
- "summary.main:app"
|
|
||||||
- "--host"
|
|
||||||
- "0.0.0.0"
|
|
||||||
- "--port"
|
|
||||||
- "8000"
|
|
||||||
- "--reload"
|
|
||||||
|
|
||||||
celeryTranscribe:
|
celeryTranscribe:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
|
image: *summaryImage
|
||||||
envVars:
|
envVars:
|
||||||
APP_NAME: summary-microservice
|
<<: *summaryEnvVars
|
||||||
APP_API_TOKEN: password
|
|
||||||
AWS_STORAGE_BUCKET_NAME: meet-media-storage
|
|
||||||
AWS_S3_ENDPOINT_URL: minio.meet.svc.cluster.local:9000
|
|
||||||
AWS_S3_ACCESS_KEY_ID: meet
|
|
||||||
AWS_S3_SECRET_ACCESS_KEY: password
|
|
||||||
AWS_S3_SECURE_ACCESS: False
|
|
||||||
WHISPERX_API_KEY: your-secret-value
|
|
||||||
WHISPERX_BASE_URL: https://configure-your-url.com
|
|
||||||
WHISPERX_ASR_MODEL: large-v2
|
|
||||||
LLM_BASE_URL: https://configure-your-url.com
|
|
||||||
LLM_API_KEY: your-secret-value
|
|
||||||
LLM_MODEL: meta-llama/Llama-3.1-8B-Instruct
|
|
||||||
WEBHOOK_API_TOKEN: password
|
|
||||||
WEBHOOK_URL: https://www.mock-impress.com/webhook/
|
|
||||||
CELERY_BROKER_URL: redis://default:pass@redis-master:6379/1
|
|
||||||
CELERY_RESULT_BACKEND: redis://default:pass@redis-master:6379/1
|
|
||||||
TASK_TRACKER_REDIS_URL: redis://default:pass@redis-master:6379/1
|
|
||||||
|
|
||||||
image:
|
|
||||||
repository: localhost:5001/meet-summary
|
|
||||||
pullPolicy: Always
|
|
||||||
tag: "latest"
|
|
||||||
|
|
||||||
command:
|
command:
|
||||||
- "celery"
|
- "celery"
|
||||||
- "-A"
|
- "-A"
|
||||||
@@ -213,31 +188,9 @@ celeryTranscribe:
|
|||||||
|
|
||||||
celerySummarize:
|
celerySummarize:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
|
image: *summaryImage
|
||||||
envVars:
|
envVars:
|
||||||
APP_NAME: summary-microservice
|
<<: *summaryEnvVars
|
||||||
APP_API_TOKEN: password
|
|
||||||
AWS_STORAGE_BUCKET_NAME: meet-media-storage
|
|
||||||
AWS_S3_ENDPOINT_URL: minio.meet.svc.cluster.local:9000
|
|
||||||
AWS_S3_ACCESS_KEY_ID: meet
|
|
||||||
AWS_S3_SECRET_ACCESS_KEY: password
|
|
||||||
AWS_S3_SECURE_ACCESS: False
|
|
||||||
WHISPERX_API_KEY: your-secret-value
|
|
||||||
WHISPERX_BASE_URL: https://configure-your-url.com
|
|
||||||
WHISPERX_ASR_MODEL: large-v2
|
|
||||||
LLM_BASE_URL: https://configure-your-url.com
|
|
||||||
LLM_API_KEY: your-secret-value
|
|
||||||
LLM_MODEL: meta-llama/Llama-3.1-8B-Instruct
|
|
||||||
WEBHOOK_API_TOKEN: password
|
|
||||||
WEBHOOK_URL: https://www.mock-impress.com/webhook/
|
|
||||||
CELERY_BROKER_URL: redis://default:pass@redis-master:6379/1
|
|
||||||
CELERY_RESULT_BACKEND: redis://default:pass@redis-master:6379/1
|
|
||||||
TASK_TRACKER_REDIS_URL: redis://default:pass@redis-master:6379/1
|
|
||||||
|
|
||||||
image:
|
|
||||||
repository: localhost:5001/meet-summary
|
|
||||||
pullPolicy: Always
|
|
||||||
tag: "latest"
|
|
||||||
|
|
||||||
command:
|
command:
|
||||||
- "celery"
|
- "celery"
|
||||||
- "-A"
|
- "-A"
|
||||||
|
|||||||
@@ -26,6 +26,18 @@ egress:
|
|||||||
endpoint: http://minio:9000
|
endpoint: http://minio:9000
|
||||||
force_path_style: true
|
force_path_style: true
|
||||||
|
|
||||||
|
podSecurityContext:
|
||||||
|
fsGroup: 1000
|
||||||
|
fsGroupChangePolicy: "OnRootMismatch"
|
||||||
|
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
|
||||||
loadBalancer:
|
loadBalancer:
|
||||||
type: nginx
|
type: nginx
|
||||||
annotations:
|
annotations:
|
||||||
@@ -43,4 +55,7 @@ autoscaling:
|
|||||||
maxReplicas: 5
|
maxReplicas: 5
|
||||||
|
|
||||||
nodeSelector: {}
|
nodeSelector: {}
|
||||||
resources: {}
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 5000m
|
||||||
|
memory: 1024Mi
|
||||||
@@ -28,6 +28,16 @@ livekit:
|
|||||||
urls:
|
urls:
|
||||||
- https://meet.127.0.0.1.nip.io/api/v1.0/rooms/webhooks-livekit/
|
- https://meet.127.0.0.1.nip.io/api/v1.0/rooms/webhooks-livekit/
|
||||||
|
|
||||||
|
podSecurityContext:
|
||||||
|
fsGroup: 2000
|
||||||
|
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
|
||||||
loadBalancer:
|
loadBalancer:
|
||||||
type: nginx
|
type: nginx
|
||||||
@@ -47,4 +57,4 @@ autoscaling:
|
|||||||
targetCPUUtilizationPercentage: 60
|
targetCPUUtilizationPercentage: 60
|
||||||
|
|
||||||
nodeSelector: {}
|
nodeSelector: {}
|
||||||
resources: {}
|
resources: {}
|
||||||
@@ -1,3 +1,29 @@
|
|||||||
|
_summaryEnvVars: &summaryEnvVars
|
||||||
|
APP_NAME: summary-microservice
|
||||||
|
APP_API_TOKEN: password
|
||||||
|
AWS_STORAGE_BUCKET_NAME: meet-media-storage
|
||||||
|
AWS_S3_ENDPOINT_URL: http://minio.meet.svc.cluster.local:9000/
|
||||||
|
AWS_S3_ACCESS_KEY_ID: meet
|
||||||
|
AWS_S3_SECRET_ACCESS_KEY: password
|
||||||
|
AWS_S3_SECURE_ACCESS: False
|
||||||
|
WHISPERX_API_KEY: your-secret-value
|
||||||
|
WHISPERX_BASE_URL: https://configure-your-url.com
|
||||||
|
WHISPERX_ASR_MODEL: large-v2
|
||||||
|
WHISPERX_DEFAULT_LANGUAGE: fr
|
||||||
|
LLM_BASE_URL: https://configure-your-url.com
|
||||||
|
LLM_API_KEY: your-secret-value
|
||||||
|
LLM_MODEL: meta-llama/Llama-3.1-8B-Instruct
|
||||||
|
WEBHOOK_API_TOKEN: password
|
||||||
|
WEBHOOK_URL: https://www.mock-impress.com/webhook/
|
||||||
|
CELERY_BROKER_URL: redis://default:pass@redis-master:6379/1
|
||||||
|
CELERY_RESULT_BACKEND: redis://default:pass@redis-master:6379/1
|
||||||
|
TASK_TRACKER_REDIS_URL: redis://default:pass@redis-master:6379/1
|
||||||
|
|
||||||
|
_summaryImage: &summaryImage
|
||||||
|
repository: localhost:5001/meet-summary
|
||||||
|
pullPolicy: Always
|
||||||
|
tag: "latest"
|
||||||
|
|
||||||
image:
|
image:
|
||||||
repository: localhost:5001/meet-backend
|
repository: localhost:5001/meet-backend
|
||||||
pullPolicy: Always
|
pullPolicy: Always
|
||||||
@@ -86,7 +112,6 @@ backend:
|
|||||||
CELERY_ENABLED: True
|
CELERY_ENABLED: True
|
||||||
CELERY_BROKER_URL: redis://default:pass@redis-master:6379/1
|
CELERY_BROKER_URL: redis://default:pass@redis-master:6379/1
|
||||||
|
|
||||||
|
|
||||||
migrate:
|
migrate:
|
||||||
command:
|
command:
|
||||||
- "/bin/sh"
|
- "/bin/sh"
|
||||||
@@ -154,75 +179,21 @@ ingressWebhook:
|
|||||||
posthog:
|
posthog:
|
||||||
ingress:
|
ingress:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
ingressAssets:
|
ingressAssets:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
summary:
|
summary:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
|
image: *summaryImage
|
||||||
envVars:
|
envVars:
|
||||||
APP_NAME: summary-microservice
|
<<: *summaryEnvVars
|
||||||
APP_API_TOKEN: password
|
|
||||||
AWS_STORAGE_BUCKET_NAME: meet-media-storage
|
|
||||||
AWS_S3_ENDPOINT_URL: http://minio.meet.svc.cluster.local:9000/
|
|
||||||
AWS_S3_ACCESS_KEY_ID: meet
|
|
||||||
AWS_S3_SECRET_ACCESS_KEY: password
|
|
||||||
AWS_S3_SECURE_ACCESS: False
|
|
||||||
WHISPERX_API_KEY: your-secret-value
|
|
||||||
WHISPERX_BASE_URL: https://configure-your-url.com
|
|
||||||
WHISPERX_ASR_MODEL: large-v2
|
|
||||||
WHISPERX_DEFAULT_LANGUAGE: fr
|
|
||||||
LLM_BASE_URL: https://configure-your-url.com
|
|
||||||
LLM_API_KEY: your-secret-value
|
|
||||||
LLM_MODEL: meta-llama/Llama-3.1-8B-Instruct
|
|
||||||
WEBHOOK_API_TOKEN: password
|
|
||||||
WEBHOOK_URL: https://www.mock-impress.com/webhook/
|
|
||||||
CELERY_BROKER_URL: redis://default:pass@redis-master:6379/1
|
|
||||||
CELERY_RESULT_BACKEND: redis://default:pass@redis-master:6379/1
|
|
||||||
TASK_TRACKER_REDIS_URL: redis://default:pass@redis-master:6379/1
|
|
||||||
|
|
||||||
image:
|
|
||||||
repository: localhost:5001/meet-summary
|
|
||||||
pullPolicy: Always
|
|
||||||
tag: "latest"
|
|
||||||
|
|
||||||
command:
|
|
||||||
- "uvicorn"
|
|
||||||
- "summary.main:app"
|
|
||||||
- "--host"
|
|
||||||
- "0.0.0.0"
|
|
||||||
- "--port"
|
|
||||||
- "8000"
|
|
||||||
- "--reload"
|
|
||||||
|
|
||||||
celeryTranscribe:
|
celeryTranscribe:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
|
image: *summaryImage
|
||||||
envVars:
|
envVars:
|
||||||
APP_NAME: summary-microservice
|
<<: *summaryEnvVars
|
||||||
APP_API_TOKEN: password
|
|
||||||
AWS_STORAGE_BUCKET_NAME: meet-media-storage
|
|
||||||
AWS_S3_ENDPOINT_URL: http://minio.meet.svc.cluster.local:9000/
|
|
||||||
AWS_S3_ACCESS_KEY_ID: meet
|
|
||||||
AWS_S3_SECRET_ACCESS_KEY: password
|
|
||||||
AWS_S3_SECURE_ACCESS: False
|
|
||||||
WHISPERX_API_KEY: your-secret-value
|
|
||||||
WHISPERX_BASE_URL: https://configure-your-url.com
|
|
||||||
WHISPERX_ASR_MODEL: large-v2
|
|
||||||
WHISPERX_DEFAULT_LANGUAGE: fr
|
|
||||||
LLM_BASE_URL: https://configure-your-url.com
|
|
||||||
LLM_API_KEY: your-secret-value
|
|
||||||
LLM_MODEL: meta-llama/Llama-3.1-8B-Instruct
|
|
||||||
WEBHOOK_API_TOKEN: password
|
|
||||||
WEBHOOK_URL: https://www.mock-impress.com/webhook/
|
|
||||||
CELERY_BROKER_URL: redis://default:pass@redis-master:6379/1
|
|
||||||
CELERY_RESULT_BACKEND: redis://default:pass@redis-master:6379/1
|
|
||||||
TASK_TRACKER_REDIS_URL: redis://default:pass@redis-master:6379/1
|
|
||||||
|
|
||||||
image:
|
|
||||||
repository: localhost:5001/meet-summary
|
|
||||||
pullPolicy: Always
|
|
||||||
tag: "latest"
|
|
||||||
|
|
||||||
command:
|
command:
|
||||||
- "celery"
|
- "celery"
|
||||||
- "-A"
|
- "-A"
|
||||||
@@ -235,32 +206,9 @@ celeryTranscribe:
|
|||||||
|
|
||||||
celerySummarize:
|
celerySummarize:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
|
image: *summaryImage
|
||||||
envVars:
|
envVars:
|
||||||
APP_NAME: summary-microservice
|
<<: *summaryEnvVars
|
||||||
APP_API_TOKEN: password
|
|
||||||
AWS_STORAGE_BUCKET_NAME: meet-media-storage
|
|
||||||
AWS_S3_ENDPOINT_URL: http://minio.meet.svc.cluster.local:9000/
|
|
||||||
AWS_S3_ACCESS_KEY_ID: meet
|
|
||||||
AWS_S3_SECRET_ACCESS_KEY: password
|
|
||||||
AWS_S3_SECURE_ACCESS: False
|
|
||||||
WHISPERX_API_KEY: your-secret-value
|
|
||||||
WHISPERX_BASE_URL: https://configure-your-url.com
|
|
||||||
WHISPERX_ASR_MODEL: large-v2
|
|
||||||
WHISPERX_DEFAULT_LANGUAGE: fr
|
|
||||||
LLM_BASE_URL: https://configure-your-url.com
|
|
||||||
LLM_API_KEY: your-secret-value
|
|
||||||
LLM_MODEL: meta-llama/Llama-3.1-8B-Instruct
|
|
||||||
WEBHOOK_API_TOKEN: password
|
|
||||||
WEBHOOK_URL: https://www.mock-impress.com/webhook/
|
|
||||||
CELERY_BROKER_URL: redis://default:pass@redis-master:6379/1
|
|
||||||
CELERY_RESULT_BACKEND: redis://default:pass@redis-master:6379/1
|
|
||||||
TASK_TRACKER_REDIS_URL: redis://default:pass@redis-master:6379/1
|
|
||||||
|
|
||||||
image:
|
|
||||||
repository: localhost:5001/meet-summary
|
|
||||||
pullPolicy: Always
|
|
||||||
tag: "latest"
|
|
||||||
|
|
||||||
command:
|
command:
|
||||||
- "celery"
|
- "celery"
|
||||||
- "-A"
|
- "-A"
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
replicaCount: 1
|
|
||||||
terminationGracePeriodSeconds: 18000
|
|
||||||
|
|
||||||
egress:
|
|
||||||
log_level: debug
|
|
||||||
ws_url: ws://livekit-livekit-server:80
|
|
||||||
insecure: true
|
|
||||||
enable_chrome_sandbox: true
|
|
||||||
{{- with .Values.livekit.keys }}
|
|
||||||
{{- range $key, $value := . }}
|
|
||||||
api_key: {{ $key }}
|
|
||||||
api_secret: {{ $value }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
redis:
|
|
||||||
address: redis-master:6379
|
|
||||||
password: pass
|
|
||||||
s3:
|
|
||||||
access_key: meet
|
|
||||||
secret: password
|
|
||||||
region: local
|
|
||||||
bucket: meet-media-storage
|
|
||||||
endpoint: http://minio:9000
|
|
||||||
force_path_style: true
|
|
||||||
|
|
||||||
loadBalancer:
|
|
||||||
type: nginx
|
|
||||||
annotations:
|
|
||||||
nginx.ingress.kubernetes.io/rewrite-target: /
|
|
||||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
|
||||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
|
||||||
tls:
|
|
||||||
- hosts:
|
|
||||||
- livekit-egress.127.0.0.1.nip.io
|
|
||||||
secretName: livekit-egress-dinum-cert
|
|
||||||
|
|
||||||
autoscaling:
|
|
||||||
enabled: false
|
|
||||||
minReplicas: 1
|
|
||||||
maxReplicas: 5
|
|
||||||
|
|
||||||
nodeSelector: {}
|
|
||||||
resources: {}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
replicaCount: 1
|
|
||||||
terminationGracePeriodSeconds: 18000
|
|
||||||
|
|
||||||
image:
|
|
||||||
repository: localhost:5001/meet-livekit
|
|
||||||
pullPolicy: Always
|
|
||||||
tag: "latest"
|
|
||||||
|
|
||||||
livekit:
|
|
||||||
log_level: debug
|
|
||||||
rtc:
|
|
||||||
use_external_ip: false
|
|
||||||
port_range_start: 50000
|
|
||||||
port_range_end: 60000
|
|
||||||
tcp_port: 7881
|
|
||||||
redis:
|
|
||||||
address: redis-master:6379
|
|
||||||
password: pass
|
|
||||||
keys:
|
|
||||||
turn:
|
|
||||||
enabled: true
|
|
||||||
udp_port: 443
|
|
||||||
domain: livekit.127.0.0.1.nip.io
|
|
||||||
loadBalancerAnnotations: {}
|
|
||||||
|
|
||||||
webhook:
|
|
||||||
api_key:
|
|
||||||
urls:
|
|
||||||
- https://meet.127.0.0.1.nip.io/api/v1.0/rooms/webhooks-livekit/
|
|
||||||
|
|
||||||
loadBalancer:
|
|
||||||
type: nginx
|
|
||||||
annotations:
|
|
||||||
nginx.ingress.kubernetes.io/rewrite-target: /
|
|
||||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
|
||||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
|
||||||
tls:
|
|
||||||
- hosts:
|
|
||||||
- livekit.127.0.0.1.nip.io
|
|
||||||
secretName: livekit-dinum-cert
|
|
||||||
|
|
||||||
autoscaling:
|
|
||||||
enabled: false
|
|
||||||
minReplicas: 1
|
|
||||||
maxReplicas: 5
|
|
||||||
targetCPUUtilizationPercentage: 60
|
|
||||||
|
|
||||||
nodeSelector: {}
|
|
||||||
resources: {}
|
|
||||||
@@ -1,290 +0,0 @@
|
|||||||
secrets:
|
|
||||||
- name: oidcLogin
|
|
||||||
itemId: a25effec-eaea-4ce1-9ed8-3a3cc1c734db
|
|
||||||
field: username
|
|
||||||
podVariable: OIDC_RP_CLIENT_ID
|
|
||||||
clusterSecretStore: bitwarden-login-meet
|
|
||||||
- name: oidcPass
|
|
||||||
itemId: a25effec-eaea-4ce1-9ed8-3a3cc1c734db
|
|
||||||
field: password
|
|
||||||
podVariable: OIDC_RP_CLIENT_SECRET
|
|
||||||
clusterSecretStore: bitwarden-login-meet
|
|
||||||
- name: brevoApiKey
|
|
||||||
itemId: 99107889-6124-4436-97cc-a5193f28443f
|
|
||||||
field: password
|
|
||||||
podVariable: BREVO_API_KEY
|
|
||||||
clusterSecretStore: bitwarden-login-meet
|
|
||||||
image:
|
|
||||||
repository: localhost:5001/meet-backend
|
|
||||||
pullPolicy: Always
|
|
||||||
tag: "latest"
|
|
||||||
|
|
||||||
backend:
|
|
||||||
replicas: 1
|
|
||||||
envVars:
|
|
||||||
DJANGO_CSRF_TRUSTED_ORIGINS: https://meet.127.0.0.1.nip.io,http://meet.127.0.0.1.nip.io
|
|
||||||
DJANGO_CONFIGURATION: Production
|
|
||||||
DJANGO_ALLOWED_HOSTS: meet.127.0.0.1.nip.io
|
|
||||||
DJANGO_SECRET_KEY: {{ .Values.djangoSecretKey }}
|
|
||||||
DJANGO_SETTINGS_MODULE: meet.settings
|
|
||||||
DJANGO_SILENCED_SYSTEM_CHECKS: security.W004, security.W008
|
|
||||||
DJANGO_SUPERUSER_PASSWORD: admin
|
|
||||||
DJANGO_EMAIL_HOST: "mailcatcher"
|
|
||||||
DJANGO_EMAIL_PORT: 1025
|
|
||||||
DJANGO_EMAIL_USE_SSL: False
|
|
||||||
DJANGO_EMAIL_BRAND_NAME: "La Suite Numérique"
|
|
||||||
DJANGO_EMAIL_SUPPORT_EMAIL: "test@yopmail.com"
|
|
||||||
DJANGO_EMAIL_LOGO_IMG: https://meet.127.0.0.1.nip.io/assets/logo-suite-numerique.png
|
|
||||||
DJANGO_EMAIL_DOMAIN: meet.127.0.0.1.nip.io
|
|
||||||
DJANGO_EMAIL_APP_BASE_URL: https://meet.127.0.0.1.nip.io
|
|
||||||
OIDC_OP_JWKS_ENDPOINT: https://fca.integ01.dev-agentconnect.fr/api/v2/jwks
|
|
||||||
OIDC_OP_AUTHORIZATION_ENDPOINT: https://fca.integ01.dev-agentconnect.fr/api/v2/authorize
|
|
||||||
OIDC_OP_TOKEN_ENDPOINT: https://fca.integ01.dev-agentconnect.fr/api/v2/token
|
|
||||||
OIDC_OP_USER_ENDPOINT: https://fca.integ01.dev-agentconnect.fr/api/v2/userinfo
|
|
||||||
OIDC_OP_LOGOUT_ENDPOINT: https://fca.integ01.dev-agentconnect.fr/api/v2/session/end
|
|
||||||
OIDC_RP_CLIENT_ID:
|
|
||||||
secretKeyRef:
|
|
||||||
name: backend
|
|
||||||
key: OIDC_RP_CLIENT_ID
|
|
||||||
OIDC_RP_CLIENT_SECRET:
|
|
||||||
secretKeyRef:
|
|
||||||
name: backend
|
|
||||||
key: OIDC_RP_CLIENT_SECRET
|
|
||||||
OIDC_RP_SIGN_ALGO: RS256
|
|
||||||
OIDC_RP_SCOPES: "openid email given_name usual_name"
|
|
||||||
OIDC_REDIRECT_ALLOWED_HOSTS: https://meet.127.0.0.1.nip.io
|
|
||||||
OIDC_AUTH_REQUEST_EXTRA_PARAMS: "{'acr_values': 'eidas1'}"
|
|
||||||
LOGIN_REDIRECT_URL: https://meet.127.0.0.1.nip.io
|
|
||||||
LOGIN_REDIRECT_URL_FAILURE: https://meet.127.0.0.1.nip.io
|
|
||||||
LOGOUT_REDIRECT_URL: https://meet.127.0.0.1.nip.io
|
|
||||||
DB_HOST: postgres
|
|
||||||
DB_NAME: meet
|
|
||||||
DB_USER: dinum
|
|
||||||
DB_PASSWORD: pass
|
|
||||||
DB_PORT: 5432
|
|
||||||
REDIS_URL: redis://default:pass@redis-master:6379/1
|
|
||||||
STORAGES_STATICFILES_BACKEND: django.contrib.staticfiles.storage.StaticFilesStorage
|
|
||||||
{{- with .Values.livekit.keys }}
|
|
||||||
{{- range $key, $value := . }}
|
|
||||||
LIVEKIT_API_SECRET: {{ $value }}
|
|
||||||
LIVEKIT_API_KEY: {{ $key }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
LIVEKIT_API_URL: https://livekit.127.0.0.1.nip.io/
|
|
||||||
LIVEKIT_WEBHOOK_EVENTS_FILTER_REGEX: "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
|
|
||||||
ALLOW_UNREGISTERED_ROOMS: False
|
|
||||||
FRONTEND_SILENCE_LIVEKIT_DEBUG: False
|
|
||||||
FRONTEND_SUPPORT: "{'id': '58ea6697-8eba-4492-bc59-ad6562585041'}"
|
|
||||||
AWS_S3_ENDPOINT_URL: http://minio.meet.svc.cluster.local:9000
|
|
||||||
AWS_S3_ACCESS_KEY_ID: meet
|
|
||||||
AWS_S3_SECRET_ACCESS_KEY: password
|
|
||||||
AWS_STORAGE_BUCKET_NAME: meet-media-storage
|
|
||||||
AWS_S3_REGION_NAME: local
|
|
||||||
MEDIA_BASE_URL: https://meet.127.0.0.1.nip.io
|
|
||||||
RECORDING_ENABLE: True
|
|
||||||
RECORDING_STORAGE_EVENT_ENABLE: True
|
|
||||||
RECORDING_STORAGE_EVENT_TOKEN: password
|
|
||||||
SUMMARY_SERVICE_ENDPOINT: http://meet-summary:80/api/v1/tasks/
|
|
||||||
SUMMARY_SERVICE_API_TOKEN: password
|
|
||||||
RECORDING_DOWNLOAD_BASE_URL: https://meet.127.0.0.1.nip.io/recording
|
|
||||||
SIGNUP_NEW_USER_TO_MARKETING_EMAIL: True
|
|
||||||
BREVO_API_KEY:
|
|
||||||
secretKeyRef:
|
|
||||||
name: backend
|
|
||||||
key: BREVO_API_KEY
|
|
||||||
BREVO_API_CONTACT_LIST_IDS: 8
|
|
||||||
ROOM_TELEPHONY_ENABLED: True
|
|
||||||
SSL_CERT_FILE: /app/.venv/lib/python3.13/site-packages/certifi/cacert.pem
|
|
||||||
|
|
||||||
|
|
||||||
migrate:
|
|
||||||
command:
|
|
||||||
- "/bin/sh"
|
|
||||||
- "-c"
|
|
||||||
- |
|
|
||||||
python manage.py migrate --no-input
|
|
||||||
restartPolicy: Never
|
|
||||||
|
|
||||||
command:
|
|
||||||
- "gunicorn"
|
|
||||||
- "-c"
|
|
||||||
- "/usr/local/etc/gunicorn/meet.py"
|
|
||||||
- "meet.wsgi:application"
|
|
||||||
- "--reload"
|
|
||||||
|
|
||||||
createsuperuser:
|
|
||||||
command:
|
|
||||||
- "/bin/sh"
|
|
||||||
- "-c"
|
|
||||||
- |
|
|
||||||
python manage.py createsuperuser --email admin@example.com --password admin
|
|
||||||
restartPolicy: Never
|
|
||||||
|
|
||||||
# Extra volume mounts to manage our local custom CA and avoid to set ssl_verify: false
|
|
||||||
extraVolumeMounts:
|
|
||||||
- name: certs
|
|
||||||
mountPath: /app/.venv/lib/python3.13/site-packages/certifi/cacert.pem
|
|
||||||
subPath: cacert.pem
|
|
||||||
|
|
||||||
# Extra volumes to manage our local custom CA and avoid to set ssl_verify: false
|
|
||||||
extraVolumes:
|
|
||||||
- name: certs
|
|
||||||
configMap:
|
|
||||||
name: certifi
|
|
||||||
items:
|
|
||||||
- key: cacert.pem
|
|
||||||
path: cacert.pem
|
|
||||||
|
|
||||||
frontend:
|
|
||||||
envVars:
|
|
||||||
VITE_APP_TITLE: "LaSuite Meet"
|
|
||||||
VITE_PORT: 8080
|
|
||||||
VITE_HOST: 0.0.0.0
|
|
||||||
VITE_API_BASE_URL: https://meet.127.0.0.1.nip.io/
|
|
||||||
|
|
||||||
replicas: 1
|
|
||||||
|
|
||||||
image:
|
|
||||||
repository: localhost:5001/meet-frontend
|
|
||||||
pullPolicy: Always
|
|
||||||
tag: "latest"
|
|
||||||
|
|
||||||
ingress:
|
|
||||||
enabled: true
|
|
||||||
host: meet.127.0.0.1.nip.io
|
|
||||||
|
|
||||||
ingressAdmin:
|
|
||||||
enabled: true
|
|
||||||
host: meet.127.0.0.1.nip.io
|
|
||||||
|
|
||||||
ingressWebhook:
|
|
||||||
enabled: true
|
|
||||||
host: meet.127.0.0.1.nip.io
|
|
||||||
|
|
||||||
posthog:
|
|
||||||
ingress:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
ingressAssets:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
summary:
|
|
||||||
replicas: 1
|
|
||||||
envVars:
|
|
||||||
APP_NAME: summary-microservice
|
|
||||||
APP_API_TOKEN: password
|
|
||||||
AWS_STORAGE_BUCKET_NAME: meet-media-storage
|
|
||||||
AWS_S3_ENDPOINT_URL: minio.meet.svc.cluster.local:9000
|
|
||||||
AWS_S3_ACCESS_KEY_ID: meet
|
|
||||||
AWS_S3_SECRET_ACCESS_KEY: password
|
|
||||||
AWS_S3_SECURE_ACCESS: False
|
|
||||||
WHISPERX_API_KEY: your-secret-value
|
|
||||||
WHISPERX_BASE_URL: https://configure-your-url.com
|
|
||||||
WHISPERX_ASR_MODEL: large-v2
|
|
||||||
LLM_BASE_URL: https://configure-your-url.com
|
|
||||||
LLM_API_KEY: your-secret-value
|
|
||||||
LLM_MODEL: meta-llama/Llama-3.1-8B-Instruct
|
|
||||||
WEBHOOK_API_TOKEN: password
|
|
||||||
WEBHOOK_URL: https://www.mock-impress.com/webhook/
|
|
||||||
CELERY_BROKER_URL: redis://default:pass@redis-master:6379/1
|
|
||||||
CELERY_RESULT_BACKEND: redis://default:pass@redis-master:6379/1
|
|
||||||
|
|
||||||
image:
|
|
||||||
repository: localhost:5001/meet-summary
|
|
||||||
pullPolicy: Always
|
|
||||||
tag: "latest"
|
|
||||||
|
|
||||||
command:
|
|
||||||
- "uvicorn"
|
|
||||||
- "summary.main:app"
|
|
||||||
- "--host"
|
|
||||||
- "0.0.0.0"
|
|
||||||
- "--port"
|
|
||||||
- "8000"
|
|
||||||
- "--reload"
|
|
||||||
|
|
||||||
celeryTranscribe:
|
|
||||||
replicas: 1
|
|
||||||
envVars:
|
|
||||||
APP_NAME: summary-microservice
|
|
||||||
APP_API_TOKEN: password
|
|
||||||
AWS_STORAGE_BUCKET_NAME: meet-media-storage
|
|
||||||
AWS_S3_ENDPOINT_URL: minio.meet.svc.cluster.local:9000
|
|
||||||
AWS_S3_ACCESS_KEY_ID: meet
|
|
||||||
AWS_S3_SECRET_ACCESS_KEY: password
|
|
||||||
AWS_S3_SECURE_ACCESS: False
|
|
||||||
WHISPERX_API_KEY: your-secret-value
|
|
||||||
WHISPERX_BASE_URL: https://configure-your-url.com
|
|
||||||
WHISPERX_ASR_MODEL: large-v2
|
|
||||||
LLM_BASE_URL: https://configure-your-url.com
|
|
||||||
LLM_API_KEY: your-secret-value
|
|
||||||
LLM_MODEL: meta-llama/Llama-3.1-8B-Instruct
|
|
||||||
WEBHOOK_API_TOKEN: password
|
|
||||||
WEBHOOK_URL: https://www.mock-impress.com/webhook/
|
|
||||||
CELERY_BROKER_URL: redis://default:pass@redis-master:6379/1
|
|
||||||
CELERY_RESULT_BACKEND: redis://default:pass@redis-master:6379/1
|
|
||||||
TASK_TRACKER_REDIS_URL: redis://default:pass@redis-master:6379/1
|
|
||||||
|
|
||||||
image:
|
|
||||||
repository: localhost:5001/meet-summary
|
|
||||||
pullPolicy: Always
|
|
||||||
tag: "latest"
|
|
||||||
|
|
||||||
command:
|
|
||||||
- "celery"
|
|
||||||
- "-A"
|
|
||||||
- "summary.core.celery_worker"
|
|
||||||
- "worker"
|
|
||||||
- "--pool=solo"
|
|
||||||
- "--loglevel=info"
|
|
||||||
- "-Q transcribe-queue"
|
|
||||||
|
|
||||||
celerySummarize:
|
|
||||||
replicas: 1
|
|
||||||
envVars:
|
|
||||||
APP_NAME: summary-microservice
|
|
||||||
APP_API_TOKEN: password
|
|
||||||
AWS_STORAGE_BUCKET_NAME: meet-media-storage
|
|
||||||
AWS_S3_ENDPOINT_URL: minio.meet.svc.cluster.local:9000
|
|
||||||
AWS_S3_ACCESS_KEY_ID: meet
|
|
||||||
AWS_S3_SECRET_ACCESS_KEY: password
|
|
||||||
AWS_S3_SECURE_ACCESS: False
|
|
||||||
WHISPERX_API_KEY: your-secret-value
|
|
||||||
WHISPERX_BASE_URL: https://configure-your-url.com
|
|
||||||
WHISPERX_ASR_MODEL: large-v2
|
|
||||||
LLM_BASE_URL: https://configure-your-url.com
|
|
||||||
LLM_API_KEY: your-secret-value
|
|
||||||
LLM_MODEL: meta-llama/Llama-3.1-8B-Instruct
|
|
||||||
WEBHOOK_API_TOKEN: password
|
|
||||||
WEBHOOK_URL: https://www.mock-impress.com/webhook/
|
|
||||||
CELERY_BROKER_URL: redis://default:pass@redis-master:6379/1
|
|
||||||
CELERY_RESULT_BACKEND: redis://default:pass@redis-master:6379/1
|
|
||||||
TASK_TRACKER_REDIS_URL: redis://default:pass@redis-master:6379/1
|
|
||||||
|
|
||||||
image:
|
|
||||||
repository: localhost:5001/meet-summary
|
|
||||||
pullPolicy: Always
|
|
||||||
tag: "latest"
|
|
||||||
|
|
||||||
command:
|
|
||||||
- "celery"
|
|
||||||
- "-A"
|
|
||||||
- "summary.core.celery_worker"
|
|
||||||
- "worker"
|
|
||||||
- "--pool=solo"
|
|
||||||
- "--loglevel=info"
|
|
||||||
- "-Q summarize-queue"
|
|
||||||
|
|
||||||
ingressMedia:
|
|
||||||
enabled: true
|
|
||||||
host: meet.127.0.0.1.nip.io
|
|
||||||
|
|
||||||
annotations:
|
|
||||||
nginx.ingress.kubernetes.io/auth-url: https://meet.127.0.0.1.nip.io/api/v1.0/recordings/media-auth/
|
|
||||||
nginx.ingress.kubernetes.io/auth-response-headers: "Authorization, X-Amz-Date, X-Amz-Content-SHA256"
|
|
||||||
nginx.ingress.kubernetes.io/upstream-vhost: minio.meet.svc.cluster.local:9000
|
|
||||||
nginx.ingress.kubernetes.io/rewrite-target: /meet-media-storage/$1
|
|
||||||
|
|
||||||
serviceMedia:
|
|
||||||
host: minio.meet.svc.cluster.local
|
|
||||||
port: 9000
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
djangoSecretKey: 7K9mQ2xR8pL3vN6tY1sW4jH5cE0zF9bM2qA7uI3oP6rT1wErt12te12
|
|
||||||
livekit:
|
|
||||||
keys:
|
|
||||||
devkey: secret
|
|
||||||
webhook:
|
|
||||||
api_key: devkey
|
|
||||||
livekitApi:
|
|
||||||
key: devkey
|
|
||||||
secret: secret
|
|
||||||
|
|
||||||
@@ -7,10 +7,6 @@ environments:
|
|||||||
values:
|
values:
|
||||||
- version: 0.0.1
|
- version: 0.0.1
|
||||||
- env.d/dev-dinum/values.secrets.yaml
|
- env.d/dev-dinum/values.secrets.yaml
|
||||||
dev:
|
|
||||||
values:
|
|
||||||
- version: 0.0.1
|
|
||||||
- env.d/dev/values.secrets.yaml
|
|
||||||
|
|
||||||
---
|
---
|
||||||
repositories:
|
repositories:
|
||||||
@@ -41,6 +37,7 @@ releases:
|
|||||||
missingFileHandler: Warn
|
missingFileHandler: Warn
|
||||||
chart: ./meet
|
chart: ./meet
|
||||||
values:
|
values:
|
||||||
|
- env.d/common.yaml.gotmpl
|
||||||
- env.d/{{ .Environment.Name }}/values.meet.yaml.gotmpl
|
- env.d/{{ .Environment.Name }}/values.meet.yaml.gotmpl
|
||||||
- env.d/{{ .Environment.Name }}/values.secrets.yaml
|
- env.d/{{ .Environment.Name }}/values.secrets.yaml
|
||||||
secrets:
|
secrets:
|
||||||
@@ -52,6 +49,7 @@ releases:
|
|||||||
namespace: {{ .Namespace }}
|
namespace: {{ .Namespace }}
|
||||||
chart: livekit/livekit-server
|
chart: livekit/livekit-server
|
||||||
values:
|
values:
|
||||||
|
- env.d/common.yaml.gotmpl
|
||||||
- env.d/{{ .Environment.Name }}/values.livekit.yaml.gotmpl
|
- env.d/{{ .Environment.Name }}/values.livekit.yaml.gotmpl
|
||||||
- env.d/{{ .Environment.Name }}/values.secrets.yaml
|
- env.d/{{ .Environment.Name }}/values.secrets.yaml
|
||||||
secrets:
|
secrets:
|
||||||
@@ -63,6 +61,7 @@ releases:
|
|||||||
namespace: {{ .Namespace }}
|
namespace: {{ .Namespace }}
|
||||||
chart: livekit/egress
|
chart: livekit/egress
|
||||||
values:
|
values:
|
||||||
|
- env.d/common.yaml.gotmpl
|
||||||
- env.d/{{ .Environment.Name }}/values.egress.yaml.gotmpl
|
- env.d/{{ .Environment.Name }}/values.egress.yaml.gotmpl
|
||||||
- env.d/{{ .Environment.Name }}/values.secrets.yaml
|
- env.d/{{ .Environment.Name }}/values.secrets.yaml
|
||||||
secrets:
|
secrets:
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ spec:
|
|||||||
- name: {{ include "meet.secret.dockerconfigjson.name" (dict "fullname" (include "meet.fullname" .) "imageCredentials" $.Values.image.credentials) }}
|
- name: {{ include "meet.secret.dockerconfigjson.name" (dict "fullname" (include "meet.fullname" .) "imageCredentials" $.Values.image.credentials) }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
shareProcessNamespace: {{ .Values.agents.shareProcessNamespace }}
|
shareProcessNamespace: {{ .Values.agents.shareProcessNamespace }}
|
||||||
|
{{- with .Values.agents.podSecurityContext }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
containers:
|
containers:
|
||||||
{{- with .Values.agents.sidecars }}
|
{{- with .Values.agents.sidecars }}
|
||||||
{{- toYaml . | nindent 8 }}
|
{{- toYaml . | nindent 8 }}
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ spec:
|
|||||||
- name: {{ include "meet.secret.dockerconfigjson.name" (dict "fullname" (include "meet.fullname" .) "imageCredentials" $.Values.image.credentials) }}
|
- name: {{ include "meet.secret.dockerconfigjson.name" (dict "fullname" (include "meet.fullname" .) "imageCredentials" $.Values.image.credentials) }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
shareProcessNamespace: {{ .Values.backend.shareProcessNamespace }}
|
shareProcessNamespace: {{ .Values.backend.shareProcessNamespace }}
|
||||||
|
{{- with .Values.backend.podSecurityContext }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
containers:
|
containers:
|
||||||
{{- with .Values.backend.sidecars }}
|
{{- with .Values.backend.sidecars }}
|
||||||
{{- toYaml . | nindent 8 }}
|
{{- toYaml . | nindent 8 }}
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ spec:
|
|||||||
- name: {{ include "meet.secret.dockerconfigjson.name" (dict "fullname" (include "meet.fullname" .) "imageCredentials" $.Values.image.credentials) }}
|
- name: {{ include "meet.secret.dockerconfigjson.name" (dict "fullname" (include "meet.fullname" .) "imageCredentials" $.Values.image.credentials) }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
shareProcessNamespace: {{ .Values.backend.shareProcessNamespace }}
|
shareProcessNamespace: {{ .Values.backend.shareProcessNamespace }}
|
||||||
|
{{- with .Values.backend.podSecurityContext }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
containers:
|
containers:
|
||||||
{{- with .Values.backend.sidecars }}
|
{{- with .Values.backend.sidecars }}
|
||||||
{{- toYaml . | nindent 8 }}
|
{{- toYaml . | nindent 8 }}
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ spec:
|
|||||||
- name: {{ include "meet.secret.dockerconfigjson.name" (dict "fullname" (include "meet.fullname" .) "imageCredentials" $.Values.image.credentials) }}
|
- name: {{ include "meet.secret.dockerconfigjson.name" (dict "fullname" (include "meet.fullname" .) "imageCredentials" $.Values.image.credentials) }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
shareProcessNamespace: {{ .Values.backend.shareProcessNamespace }}
|
shareProcessNamespace: {{ .Values.backend.shareProcessNamespace }}
|
||||||
|
{{- with .Values.backend.podSecurityContext }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
containers:
|
containers:
|
||||||
{{- with .Values.backend.sidecars }}
|
{{- with .Values.backend.sidecars }}
|
||||||
{{- toYaml . | nindent 8 }}
|
{{- toYaml . | nindent 8 }}
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ spec:
|
|||||||
- name: {{ include "meet.secret.dockerconfigjson.name" (dict "fullname" (include "meet.fullname" .) "imageCredentials" $.Values.image.credentials) }}
|
- name: {{ include "meet.secret.dockerconfigjson.name" (dict "fullname" (include "meet.fullname" .) "imageCredentials" $.Values.image.credentials) }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
shareProcessNamespace: {{ .Values.celeryBackend.shareProcessNamespace }}
|
shareProcessNamespace: {{ .Values.celeryBackend.shareProcessNamespace }}
|
||||||
|
{{- with .Values.celeryBackend.podSecurityContext }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
containers:
|
containers:
|
||||||
{{- with .Values.celeryBackend.sidecars }}
|
{{- with .Values.celeryBackend.sidecars }}
|
||||||
{{- toYaml . | nindent 8 }}
|
{{- toYaml . | nindent 8 }}
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ spec:
|
|||||||
- name: {{ include "meet.secret.dockerconfigjson.name" (dict "fullname" (include "meet.fullname" .) "imageCredentials" $.Values.image.credentials) }}
|
- name: {{ include "meet.secret.dockerconfigjson.name" (dict "fullname" (include "meet.fullname" .) "imageCredentials" $.Values.image.credentials) }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
shareProcessNamespace: {{ .Values.celerySummarize.shareProcessNamespace }}
|
shareProcessNamespace: {{ .Values.celerySummarize.shareProcessNamespace }}
|
||||||
|
{{- with .Values.celerySummarize.podSecurityContext }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
containers:
|
containers:
|
||||||
{{- with .Values.celerySummarize.sidecars }}
|
{{- with .Values.celerySummarize.sidecars }}
|
||||||
{{- toYaml . | nindent 8 }}
|
{{- toYaml . | nindent 8 }}
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ spec:
|
|||||||
- name: {{ include "meet.secret.dockerconfigjson.name" (dict "fullname" (include "meet.fullname" .) "imageCredentials" $.Values.image.credentials) }}
|
- name: {{ include "meet.secret.dockerconfigjson.name" (dict "fullname" (include "meet.fullname" .) "imageCredentials" $.Values.image.credentials) }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
shareProcessNamespace: {{ .Values.celeryTranscribe.shareProcessNamespace }}
|
shareProcessNamespace: {{ .Values.celeryTranscribe.shareProcessNamespace }}
|
||||||
|
{{- with .Values.celeryTranscribe.podSecurityContext }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
containers:
|
containers:
|
||||||
{{- with .Values.celeryTranscribe.sidecars }}
|
{{- with .Values.celeryTranscribe.sidecars }}
|
||||||
{{- toYaml . | nindent 8 }}
|
{{- toYaml . | nindent 8 }}
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ spec:
|
|||||||
- name: {{ include "meet.secret.dockerconfigjson.name" (dict "fullname" (include "meet.fullname" .) "imageCredentials" $.Values.image.credentials) }}
|
- name: {{ include "meet.secret.dockerconfigjson.name" (dict "fullname" (include "meet.fullname" .) "imageCredentials" $.Values.image.credentials) }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
shareProcessNamespace: {{ .Values.frontend.shareProcessNamespace }}
|
shareProcessNamespace: {{ .Values.frontend.shareProcessNamespace }}
|
||||||
|
{{- with .Values.frontend.podSecurityContext }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
containers:
|
containers:
|
||||||
{{- with .Values.frontend.sidecars }}
|
{{- with .Values.frontend.sidecars }}
|
||||||
{{- toYaml . | nindent 8 }}
|
{{- toYaml . | nindent 8 }}
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ spec:
|
|||||||
- name: {{ include "meet.secret.dockerconfigjson.name" (dict "fullname" (include "meet.fullname" .) "imageCredentials" $.Values.image.credentials) }}
|
- name: {{ include "meet.secret.dockerconfigjson.name" (dict "fullname" (include "meet.fullname" .) "imageCredentials" $.Values.image.credentials) }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
shareProcessNamespace: {{ .Values.summary.shareProcessNamespace }}
|
shareProcessNamespace: {{ .Values.summary.shareProcessNamespace }}
|
||||||
|
{{- with .Values.summary.podSecurityContext }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
containers:
|
containers:
|
||||||
{{- with .Values.summary.sidecars }}
|
{{- with .Values.summary.sidecars }}
|
||||||
{{- toYaml . | nindent 8 }}
|
{{- toYaml . | nindent 8 }}
|
||||||
|
|||||||
@@ -216,9 +216,12 @@ backend:
|
|||||||
ttlSecondsAfterFinished: 30
|
ttlSecondsAfterFinished: 30
|
||||||
backoffLimit: 2
|
backoffLimit: 2
|
||||||
|
|
||||||
## @param backend.securityContext Configure backend Pod security context
|
## @param backend.securityContext Configure backend Container security context
|
||||||
securityContext: null
|
securityContext: null
|
||||||
|
|
||||||
|
## @param backend.podSecurityContext Configure backend Pod security context
|
||||||
|
podSecurityContext: null
|
||||||
|
|
||||||
## @param backend.envVars Configure backend container environment variables
|
## @param backend.envVars Configure backend container environment variables
|
||||||
## @extra backend.envVars.BY_VALUE Example environment variable by setting value directly
|
## @extra backend.envVars.BY_VALUE Example environment variable by setting value directly
|
||||||
## @extra backend.envVars.FROM_CONFIGMAP.configMapKeyRef.name Name of a ConfigMap when configuring env vars from a ConfigMap
|
## @extra backend.envVars.FROM_CONFIGMAP.configMapKeyRef.name Name of a ConfigMap when configuring env vars from a ConfigMap
|
||||||
@@ -359,9 +362,12 @@ frontend:
|
|||||||
## @param frontend.sidecars Add sidecars containers to frontend deployment
|
## @param frontend.sidecars Add sidecars containers to frontend deployment
|
||||||
sidecars: []
|
sidecars: []
|
||||||
|
|
||||||
## @param frontend.securityContext Configure frontend Pod security context
|
## @param frontend.securityContext Configure frontend Container security context
|
||||||
securityContext: null
|
securityContext: null
|
||||||
|
|
||||||
|
## @param frontend.podSecurityContext Configure frontend Pod security context
|
||||||
|
podSecurityContext: null
|
||||||
|
|
||||||
## @param frontend.envVars Configure frontend container environment variables
|
## @param frontend.envVars Configure frontend container environment variables
|
||||||
## @extra frontend.envVars.BY_VALUE Example environment variable by setting value directly
|
## @extra frontend.envVars.BY_VALUE Example environment variable by setting value directly
|
||||||
## @extra frontend.envVars.FROM_CONFIGMAP.configMapKeyRef.name Name of a ConfigMap when configuring env vars from a ConfigMap
|
## @extra frontend.envVars.FROM_CONFIGMAP.configMapKeyRef.name Name of a ConfigMap when configuring env vars from a ConfigMap
|
||||||
@@ -533,9 +539,12 @@ summary:
|
|||||||
## @param summary.migrateJobAnnotations Annotations for the migrate job
|
## @param summary.migrateJobAnnotations Annotations for the migrate job
|
||||||
migrateJobAnnotations: {}
|
migrateJobAnnotations: {}
|
||||||
|
|
||||||
## @param summary.securityContext Configure summary Pod security context
|
## @param summary.securityContext Configure summary Container security context
|
||||||
securityContext: null
|
securityContext: null
|
||||||
|
|
||||||
|
## @param summary.podSecurityContext Configure summary Pod security context
|
||||||
|
podSecurityContext: null
|
||||||
|
|
||||||
## @param summary.envVars Configure summary container environment variables
|
## @param summary.envVars Configure summary container environment variables
|
||||||
## @extra summary.envVars.BY_VALUE Example environment variable by setting value directly
|
## @extra summary.envVars.BY_VALUE Example environment variable by setting value directly
|
||||||
## @extra summary.envVars.FROM_CONFIGMAP.configMapKeyRef.name Name of a ConfigMap when configuring env vars from a ConfigMap
|
## @extra summary.envVars.FROM_CONFIGMAP.configMapKeyRef.name Name of a ConfigMap when configuring env vars from a ConfigMap
|
||||||
@@ -646,9 +655,12 @@ celeryBackend:
|
|||||||
## @param celeryBackend.migrateJobAnnotations Annotations for the migrate job
|
## @param celeryBackend.migrateJobAnnotations Annotations for the migrate job
|
||||||
migrateJobAnnotations: {}
|
migrateJobAnnotations: {}
|
||||||
|
|
||||||
## @param celeryBackend.securityContext Configure celeryBackend Pod security context
|
## @param celeryBackend.securityContext Configure celeryBackend Container security context
|
||||||
securityContext: null
|
securityContext: null
|
||||||
|
|
||||||
|
## @param celeryBackend.podSecurityContext Configure celeryBackend Pod security context
|
||||||
|
podSecurityContext: null
|
||||||
|
|
||||||
## @param celeryBackend.envVars Configure celeryBackend container environment variables
|
## @param celeryBackend.envVars Configure celeryBackend container environment variables
|
||||||
## @extra celeryBackend.envVars.BY_VALUE Example environment variable by setting value directly
|
## @extra celeryBackend.envVars.BY_VALUE Example environment variable by setting value directly
|
||||||
## @extra celeryBackend.envVars.FROM_CONFIGMAP.configMapKeyRef.name Name of a ConfigMap when configuring env vars from a ConfigMap
|
## @extra celeryBackend.envVars.FROM_CONFIGMAP.configMapKeyRef.name Name of a ConfigMap when configuring env vars from a ConfigMap
|
||||||
@@ -755,9 +767,12 @@ celeryTranscribe:
|
|||||||
## @param celeryTranscribe.migrateJobAnnotations Annotations for the migrate job
|
## @param celeryTranscribe.migrateJobAnnotations Annotations for the migrate job
|
||||||
migrateJobAnnotations: {}
|
migrateJobAnnotations: {}
|
||||||
|
|
||||||
## @param celeryTranscribe.securityContext Configure celeryTranscribe Pod security context
|
## @param celeryTranscribe.securityContext Configure celeryTranscribe Container security context
|
||||||
securityContext: null
|
securityContext: null
|
||||||
|
|
||||||
|
## @param celeryTranscribe.podSecurityContext Configure celeryTranscribe Pod security context
|
||||||
|
podSecurityContext: null
|
||||||
|
|
||||||
## @param celeryTranscribe.envVars Configure celeryTranscribe container environment variables
|
## @param celeryTranscribe.envVars Configure celeryTranscribe container environment variables
|
||||||
## @extra celeryTranscribe.envVars.BY_VALUE Example environment variable by setting value directly
|
## @extra celeryTranscribe.envVars.BY_VALUE Example environment variable by setting value directly
|
||||||
## @extra celeryTranscribe.envVars.FROM_CONFIGMAP.configMapKeyRef.name Name of a ConfigMap when configuring env vars from a ConfigMap
|
## @extra celeryTranscribe.envVars.FROM_CONFIGMAP.configMapKeyRef.name Name of a ConfigMap when configuring env vars from a ConfigMap
|
||||||
@@ -864,9 +879,12 @@ celerySummarize:
|
|||||||
## @param celerySummarize.migrateJobAnnotations Annotations for the migrate job
|
## @param celerySummarize.migrateJobAnnotations Annotations for the migrate job
|
||||||
migrateJobAnnotations: {}
|
migrateJobAnnotations: {}
|
||||||
|
|
||||||
## @param celerySummarize.securityContext Configure celerySummarize Pod security context
|
## @param celerySummarize.securityContext Configure celerySummarize Container security context
|
||||||
securityContext: null
|
securityContext: null
|
||||||
|
|
||||||
|
## @param celerySummarize.podSecurityContext Configure celerySummarize Pod security context
|
||||||
|
podSecurityContext: null
|
||||||
|
|
||||||
## @param celerySummarize.envVars Configure celerySummarize container environment variables
|
## @param celerySummarize.envVars Configure celerySummarize container environment variables
|
||||||
## @extra celerySummarize.envVars.BY_VALUE Example environment variable by setting value directly
|
## @extra celerySummarize.envVars.BY_VALUE Example environment variable by setting value directly
|
||||||
## @extra celerySummarize.envVars.FROM_CONFIGMAP.configMapKeyRef.name Name of a ConfigMap when configuring env vars from a ConfigMap
|
## @extra celerySummarize.envVars.FROM_CONFIGMAP.configMapKeyRef.name Name of a ConfigMap when configuring env vars from a ConfigMap
|
||||||
@@ -963,9 +981,12 @@ agents:
|
|||||||
## @param agents.sidecars Add sidecars containers to agents deployment
|
## @param agents.sidecars Add sidecars containers to agents deployment
|
||||||
sidecars: []
|
sidecars: []
|
||||||
|
|
||||||
## @param agents.securityContext Configure agents Pod security context
|
## @param agents.securityContext Configure agents Container security context
|
||||||
securityContext: null
|
securityContext: null
|
||||||
|
|
||||||
|
## @param agents.podSecurityContext Configure agents Pod security context
|
||||||
|
podSecurityContext: null
|
||||||
|
|
||||||
## @param agents.envVars Configure agents container environment variables
|
## @param agents.envVars Configure agents container environment variables
|
||||||
## @extra agents.envVars.BY_VALUE Example environment variable by setting value directly
|
## @extra agents.envVars.BY_VALUE Example environment variable by setting value directly
|
||||||
## @extra agents.envVars.FROM_CONFIGMAP.configMapKeyRef.name Name of a ConfigMap when configuring env vars from a ConfigMap
|
## @extra agents.envVars.FROM_CONFIGMAP.configMapKeyRef.name Name of a ConfigMap when configuring env vars from a ConfigMap
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
align="center"
|
align="center"
|
||||||
src="{{logo_img}}"
|
src="{{logo_img}}"
|
||||||
width="320px"
|
width="320px"
|
||||||
alt="{%trans 'Logo email' %}"
|
alt="{%trans 'Logo email' %} {{brandname}}"
|
||||||
/>
|
/>
|
||||||
</mj-column>
|
</mj-column>
|
||||||
</mj-section>
|
</mj-section>
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "mail_mjml",
|
"name": "mail_mjml",
|
||||||
"version": "1.10.0",
|
"version": "1.12.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "mail_mjml",
|
"name": "mail_mjml",
|
||||||
"version": "1.10.0",
|
"version": "1.12.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@html-to/text-cli": "0.5.4",
|
"@html-to/text-cli": "0.5.4",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mail_mjml",
|
"name": "mail_mjml",
|
||||||
"version": "1.10.0",
|
"version": "1.12.0",
|
||||||
"description": "An util to generate html and text django's templates from mjml templates",
|
"description": "An util to generate html and text django's templates from mjml templates",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "sdk",
|
"name": "sdk",
|
||||||
"version": "1.10.0",
|
"version": "1.12.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "sdk",
|
"name": "sdk",
|
||||||
"version": "1.10.0",
|
"version": "1.12.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"./library",
|
"./library",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sdk",
|
"name": "sdk",
|
||||||
"version": "1.10.0",
|
"version": "1.12.0",
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"description": "",
|
"description": "",
|
||||||
|
|||||||
@@ -1,28 +1,36 @@
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "summary"
|
name = "summary"
|
||||||
version = "1.10.0"
|
version = "1.12.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fastapi[standard]>=0.105.0",
|
"fastapi[standard]>=0.105.0",
|
||||||
"uvicorn>=0.24.0",
|
"uvicorn>=0.24.0",
|
||||||
"pydantic>=2.5.0",
|
"pydantic>=2.5.0",
|
||||||
"pydantic-settings>=2.1.0",
|
"pydantic-settings>=2.1.0",
|
||||||
"celery==5.5.3",
|
"celery==5.6.2",
|
||||||
"redis==5.2.1",
|
"redis==5.2.1",
|
||||||
"minio==7.2.18",
|
"minio==7.2.20",
|
||||||
"mutagen==1.47.0",
|
"mutagen==1.47.0",
|
||||||
"openai==2.7.1",
|
"openai==2.28.0",
|
||||||
"posthog==6.9.1",
|
"posthog==7.9.12",
|
||||||
"requests==2.32.5",
|
"requests==2.32.5",
|
||||||
"sentry-sdk[fastapi, celery]==2.43.0",
|
"sentry-sdk[fastapi, celery]==2.54.0",
|
||||||
"langfuse==3.10.6"
|
"langfuse==4.0.0"
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
dev = [
|
dev = [
|
||||||
"ruff==0.14.4",
|
"ruff==0.15.6",
|
||||||
|
"pytest==9.0.2",
|
||||||
|
"responses>=0.25.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[tool.pytest.ini_options]
|
||||||
|
markers = [
|
||||||
|
"api: Test the API",
|
||||||
|
]
|
||||||
|
testpaths = ["tests"]
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["setuptools>=61.0"]
|
requires = ["setuptools>=61.0"]
|
||||||
build-backend = "setuptools.build_meta"
|
build-backend = "setuptools.build_meta"
|
||||||
@@ -49,6 +57,7 @@ select = [
|
|||||||
"T20", # flake8-print
|
"T20", # flake8-print
|
||||||
"W", # pycodestyle warning
|
"W", # pycodestyle warning
|
||||||
]
|
]
|
||||||
|
ignore= ["PLR2004"]
|
||||||
|
|
||||||
[tool.ruff.lint.per-file-ignores]
|
[tool.ruff.lint.per-file-ignores]
|
||||||
"tests/*" = [
|
"tests/*" = [
|
||||||
|
|||||||
@@ -23,8 +23,7 @@ Einige Punkte, die wir Ihnen empfehlen zu überprüfen:
|
|||||||
|
|
||||||
""",
|
""",
|
||||||
download_header_template=(
|
download_header_template=(
|
||||||
"\n*Laden Sie Ihre Aufnahme herunter, "
|
"\n*[Laden Sie hier Ihre Aufnahme herunter (externer Link)]({download_link})*\n"
|
||||||
"indem Sie [diesem Link folgen]({download_link})*\n"
|
|
||||||
),
|
),
|
||||||
hallucination_replacement_text="[Text konnte nicht transkribiert werden]",
|
hallucination_replacement_text="[Text konnte nicht transkribiert werden]",
|
||||||
document_default_title="Transkription",
|
document_default_title="Transkription",
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ A few things we recommend you check:
|
|||||||
|
|
||||||
""",
|
""",
|
||||||
download_header_template=(
|
download_header_template=(
|
||||||
"\n*Download your recording by [following this link]({download_link})*\n"
|
"\n*[Download your recording (external link)]({download_link})*\n"
|
||||||
),
|
),
|
||||||
hallucination_replacement_text="[Unable to transcribe text]",
|
hallucination_replacement_text="[Unable to transcribe text]",
|
||||||
document_default_title="Transcription",
|
document_default_title="Transcription",
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Quelques points que nous vous conseillons de vérifier :
|
|||||||
|
|
||||||
""",
|
""",
|
||||||
download_header_template=(
|
download_header_template=(
|
||||||
"\n*Télécharger votre enregistrement en [suivant ce lien]({download_link})*\n"
|
"\n*[Télécharger votre enregistrement (lien externe)]({download_link})*\n"
|
||||||
),
|
),
|
||||||
hallucination_replacement_text="[Texte impossible à transcrire]",
|
hallucination_replacement_text="[Texte impossible à transcrire]",
|
||||||
document_default_title="Transcription",
|
document_default_title="Transcription",
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Een paar punten die wij u aanraden te controleren:
|
|||||||
|
|
||||||
""",
|
""",
|
||||||
download_header_template=(
|
download_header_template=(
|
||||||
"\n*Download uw opname door [deze link te volgen]({download_link})*\n"
|
"\n*[Download hier je opname (externe link)]({download_link})*\n"
|
||||||
),
|
),
|
||||||
hallucination_replacement_text="[Tekst kon niet worden getranscribeerd]",
|
hallucination_replacement_text="[Tekst kon niet worden getranscribeerd]",
|
||||||
document_default_title="Transcriptie",
|
document_default_title="Transcriptie",
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
"""Tests for the summary service."""
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
"""Tests for the API summary service."""
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user