Merge branch 'master' of https://github.com/inventree/InvenTree into matmair/issue11460
This commit is contained in:
commit
3dae0dec21
|
|
@ -13,5 +13,5 @@ runs:
|
|||
invoke export-records -f data.json
|
||||
python3 ./src/backend/InvenTree/manage.py flush --noinput
|
||||
invoke migrate
|
||||
invoke import-records -c -f data.json --force --strict
|
||||
invoke import-records -c -f data.json --force --strict
|
||||
invoke import-records -c -f data.json --strict
|
||||
invoke import-records -c -f data.json --strict
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
"""Script to check a data file exported using the 'export-records' command.
|
||||
|
||||
This script is intended to be used as part of the CI workflow,
|
||||
in conjunction with the "workflows/import_export.yaml" workflow.
|
||||
|
||||
In reads the exported data file, to ensure that:
|
||||
|
||||
- The file can be read and parsed as JSON
|
||||
- The file contains the expected metadata
|
||||
- The file contains the expected plugin configuration
|
||||
- The file contains the expected plugin database records
|
||||
|
||||
"""
|
||||
|
||||
PLUGIN_KEY = 'dummy_app_plugin'
|
||||
PLUGIN_SLUG = 'dummy-app-plugin'
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description='Check exported data file')
|
||||
parser.add_argument('datafile', help='Path to the exported data file (JSON)')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not os.path.isfile(args.datafile):
|
||||
print(f'Error: File not found: {args.datafile}')
|
||||
exit(1)
|
||||
|
||||
with open(args.datafile, encoding='utf-8') as f:
|
||||
try:
|
||||
data = json.load(f)
|
||||
print(f'Successfully loaded data from {args.datafile}')
|
||||
print(f'Number of records: {len(data)}')
|
||||
except json.JSONDecodeError as e:
|
||||
print(f'Error: Failed to parse JSON file: {e}')
|
||||
exit(1)
|
||||
|
||||
found_metadata = False
|
||||
found_installed_apps = False
|
||||
found_plugin_config = False
|
||||
plugin_data_records = {}
|
||||
|
||||
# Inspect the data and check that it has the expected structure and content.
|
||||
for entry in data:
|
||||
# Check metadata entry for expected values
|
||||
if entry.get('metadata', False):
|
||||
print('Found metadata entry')
|
||||
found_metadata = True
|
||||
|
||||
expected_apps = ['InvenTree', 'allauth', 'dbbackup', PLUGIN_KEY]
|
||||
|
||||
apps = entry.get('installed_apps', [])
|
||||
|
||||
for app in expected_apps:
|
||||
if app not in apps:
|
||||
print(f'- Expected app "{app}" not found in installed apps list')
|
||||
exit(1)
|
||||
|
||||
found_installed_apps = True
|
||||
|
||||
elif entry.get('model', None) == 'plugin.pluginconfig':
|
||||
key = entry['fields']['key']
|
||||
|
||||
if key == PLUGIN_SLUG:
|
||||
print(f'Found plugin configuration for plugin "{PLUGIN_KEY}"')
|
||||
found_plugin_config = True
|
||||
|
||||
elif entry.get('model', None) == f'{PLUGIN_KEY}.examplemodel':
|
||||
key = entry['fields']['key']
|
||||
value = entry['fields']['value']
|
||||
|
||||
plugin_data_records[key] = value
|
||||
|
||||
if not found_metadata:
|
||||
print('Error: No metadata entry found in exported data')
|
||||
exit(1)
|
||||
|
||||
if not found_installed_apps:
|
||||
print(
|
||||
f'Error: Plugin "{PLUGIN_KEY}" not found in installed apps list in metadata'
|
||||
)
|
||||
exit(1)
|
||||
|
||||
if not found_plugin_config:
|
||||
print(f'Error: No plugin configuration found for plugin "{PLUGIN_KEY}"')
|
||||
exit(1)
|
||||
|
||||
# Check the extracted plugin records
|
||||
expected_keys = ['alpha', 'beta', 'gamma', 'delta']
|
||||
|
||||
for key in expected_keys:
|
||||
if key not in plugin_data_records:
|
||||
print(
|
||||
f'Error: Expected plugin record with key "{key}" not found in exported data'
|
||||
)
|
||||
exit(1)
|
||||
|
||||
print('All checks passed successfully!')
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
# Ensure that data import / export functionality works as expected.
|
||||
# - Create a dataset in a Postgres database (including plugin data)
|
||||
# - Export the dataset to an agnostic format (JSON)
|
||||
# - Import the dataset into a Sqlite database
|
||||
|
||||
name: Import / Export
|
||||
|
||||
on:
|
||||
push:
|
||||
branches-ignore: ["l10*"]
|
||||
pull_request:
|
||||
branches-ignore: ["l10*"]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
python_version: 3.11
|
||||
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
INVENTREE_DEBUG: false
|
||||
INVENTREE_LOG_LEVEL: WARNING
|
||||
INVENTREE_MEDIA_ROOT: /home/runner/work/InvenTree/test_inventree_media
|
||||
INVENTREE_STATIC_ROOT: /home/runner/work/InvenTree/test_inventree_static
|
||||
INVENTREE_BACKUP_DIR: /home/runner/work/InvenTree/test_inventree_backup
|
||||
INVENTREE_SITE_URL: http://localhost:8000
|
||||
|
||||
INVENTREE_PLUGINS_ENABLED: true
|
||||
INVENTREE_AUTO_UPDATE: true
|
||||
INVENTREE_PLUGINS_MANDATORY: "dummy-app-plugin"
|
||||
INVENTREE_GLOBAL_SETTINGS: '{"ENABLE_PLUGINS_APP": true}'
|
||||
|
||||
DATA_FILE: /home/runner/work/InvenTree/test_inventree_data.json
|
||||
|
||||
INVENTREE_DB_ENGINE: postgresql
|
||||
INVENTREE_DB_NAME: inventree
|
||||
INVENTREE_DB_USER: inventree
|
||||
INVENTREE_DB_PASSWORD: password
|
||||
INVENTREE_DB_HOST: "127.0.0.1"
|
||||
INVENTREE_DB_PORT: 5432
|
||||
|
||||
jobs:
|
||||
|
||||
paths-filter:
|
||||
name: filter
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
server: ${{ steps.filter.outputs.server }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # pin@v4.0.1
|
||||
id: filter
|
||||
with:
|
||||
filters: |
|
||||
server:
|
||||
- .github/workflows/import_export.yaml
|
||||
- .github/scripts/check_exported_data.py
|
||||
- 'src/backend/**'
|
||||
- 'tasks.py'
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
needs: paths-filter
|
||||
if: needs.paths-filter.outputs.server == 'true' || contains(github.event.pull_request.labels.*.name, 'full-run')
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:17
|
||||
env:
|
||||
POSTGRES_USER: inventree
|
||||
POSTGRES_PASSWORD: password
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
- name: Environment Setup
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
apt-dependency: gettext poppler-utils libpq-dev
|
||||
pip-dependency: psycopg
|
||||
update: true
|
||||
static: false
|
||||
- name: Setup Postgres Database
|
||||
run: |
|
||||
invoke migrate
|
||||
invoke dev.setup-test -i
|
||||
- name: Create Plugin Data
|
||||
run: |
|
||||
pip install -U inventree-dummy-app-plugin
|
||||
invoke migrate
|
||||
cd src/backend/InvenTree && python manage.py create_dummy_data
|
||||
- name: Export Postgres Dataset
|
||||
run: |
|
||||
invoke export-records -o -f ${{ env.DATA_FILE }}
|
||||
python .github/scripts/check_exported_data.py ${{ env.DATA_FILE }}
|
||||
invoke dev.delete-data --force
|
||||
- name: Update Environment Variables for Sqlite
|
||||
run: |
|
||||
echo "Updating environment variables for Sqlite"
|
||||
echo "INVENTREE_DB_ENGINE=sqlite" >> $GITHUB_ENV
|
||||
echo "INVENTREE_DB_NAME=/home/runner/work/InvenTree/test_inventree_db.sqlite3" >> $GITHUB_ENV
|
||||
- name: Setup Sqlite Database
|
||||
run: |
|
||||
invoke migrate
|
||||
test -f /home/runner/work/InvenTree/test_inventree_db.sqlite3 || (echo "Sqlite database not created" && exit 1)
|
||||
- name: Import Sqlite Dataset
|
||||
run: |
|
||||
invoke import-records -c -f ${{ env.DATA_FILE }} --strict
|
||||
cd src/backend/InvenTree && python manage.py check_dummy_data
|
||||
- name: Export Sqlite Dataset
|
||||
run: |
|
||||
invoke export-records -o -f ${{ env.DATA_FILE }}
|
||||
python .github/scripts/check_exported_data.py ${{ env.DATA_FILE }}
|
||||
|
|
@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
### Changed
|
||||
|
||||
- [#11648](https://github.com/inventree/InvenTree/pull/11648) improves the import/export process, allowing data records defined by plugins to be loaded when importing a database from a file.
|
||||
- [#11630](https://github.com/inventree/InvenTree/pull/11630) enhances the `import_records` and `export_records` system commands, by adding a metadata entry to the exported data file to allow for compatibility checks during data import.
|
||||
|
||||
### Removed
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ django-auth-ldap==5.3.0 \
|
|||
--hash=sha256:743d8107b146240b46f7e97207dc06cb11facc0cd70dce490b7ca09dd5643d19 \
|
||||
--hash=sha256:aa880415983149b072f876d976ef8ec755a438090e176817998263a6ed9e1038
|
||||
# via -r contrib/container/requirements.in
|
||||
gunicorn==25.1.0 \
|
||||
--hash=sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616 \
|
||||
--hash=sha256:d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b
|
||||
gunicorn==25.2.0 \
|
||||
--hash=sha256:10bd7adb36d44945d97d0a1fdf9a0fb086ae9c7b39e56b4dece8555a6bf4a09c \
|
||||
--hash=sha256:88f5b444d0055bf298435384af7294f325e2273fd37ba9f9ff7b98e0a1e5dfdc
|
||||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# -r contrib/container/requirements.in
|
||||
|
|
|
|||
|
|
@ -149,9 +149,9 @@ jc==1.25.6 \
|
|||
--hash=sha256:27f58befc7ae0a4c63322926c5f1ec892e3eac4a065eff3b07cfe420a6924a07 \
|
||||
--hash=sha256:7367b59e6e0da8babeede1e5b0da083f3c5aa6b6e585b4aed28dd7c4b2d76162
|
||||
# via -r contrib/dev_reqs/requirements.in
|
||||
pygments==2.19.2 \
|
||||
--hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \
|
||||
--hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b
|
||||
pygments==2.20.0 \
|
||||
--hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \
|
||||
--hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176
|
||||
# via jc
|
||||
pyyaml==6.0.3 \
|
||||
--hash=sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c \
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ Deploying InvenTree to production requires to knowledge of the security assumpti
|
|||
|
||||
2. All users are trusted - therefore user uploaded files can be assumed to be safe. There are basic checks in place to ensure that the files are not using common attack vectors but those are not exhaustive.
|
||||
|
||||
3. Superuser permissions are only given to trusted users and not used for daily operations. A superuser account can manipulate or extract all files on the server that the InvenTree server process have access to.
|
||||
3. Superuser or staff permissions are only given to trusted users and not used for daily operations. A superuser account can manipulate or extract all files on the server that the InvenTree server process have access to. See [dangerous user flags](../settings/permissions.md#dangerous-user-flags) for more details on user permissions and flags.
|
||||
|
||||
4. All templates and plugins are trusted.
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,12 @@ In the example below, see that the *Wood Screw* line item is marked as consumabl
|
|||
|
||||
Further, in the [Build Order](./build.md) stock allocation table, we see that this line item cannot be allocated, as it is *consumable*.
|
||||
|
||||
### Optional BOM Line Items
|
||||
|
||||
If a BOM line item is marked as *optional*, this means that the part and quantity information is tracked in the BOM, but this line item is not required to be allocated to a [Build Order](./build.md). This may be useful for certain items which are not strictly required for the build process to be completed.
|
||||
|
||||
When completing a Build Order, the user can choose whether to include optional items in the build process or not. If optional items are included, they will be allocated to the Build Order as normal. If optional items are excluded, they will not be allocated to the Build Order, and the build process can be completed without them.
|
||||
|
||||
### Substitute BOM Line Items
|
||||
|
||||
Where alternative parts can be used when building an assembly, these parts are assigned as *Substitute* parts in the Bill of Materials. A particular line item may have multiple substitute parts assigned to it. When allocating stock to a [Build Order](./build.md), stock items associated with any of the substitute parts may be allocated against the particular line item.
|
||||
|
|
|
|||
|
|
@ -27,24 +27,22 @@ When creating a new revision of a part, there are some restrictions which must b
|
|||
|
||||
* **Circular References**: A part cannot be a revision of itself. This would create a circular reference which is not allowed.
|
||||
* **Unique Revisions**: A part cannot have two revisions with the same revision number. Each revision (of a given part) must have a unique revision code.
|
||||
* **Revisions of Revisions**: A single part can have multiple revisions, but a revision cannot have its own revision. This restriction is in place to prevent overly complex part relationships.
|
||||
* **Template Revisions**: A part which is a [template part](./template.md) cannot have revisions. This is because the template part is used to create variants, and allowing revisions of templates would create disallowed relationship states in the database. However, variant parts are allowed to have revisions.
|
||||
* **Template References**: A part which is a revision of a variant part must point to the same template as the original part. This is to ensure that the revision is correctly linked to the original part.
|
||||
|
||||
## Revision Settings
|
||||
|
||||
The following options are available to control the behavior of part revisions.
|
||||
The following [global settings](../settings/global.md) are available to control the behavior of part revisions:
|
||||
|
||||
Note that these options can be changed in the InvenTree settings:
|
||||
| Name | Description | Default | Units |
|
||||
| ---- | ----------- | ------- | ----- |
|
||||
{{ globalsetting("PART_ENABLE_REVISION") }}
|
||||
{{ globalsetting("PART_REVISION_ASSEMBLY_ONLY") }}
|
||||
|
||||
{{ image("part/part_revision_settings.png", "Part revision settings") }}
|
||||
|
||||
* **Enable Revisions**: If this setting is enabled, parts can have revisions. If this setting is disabled, parts cannot have revisions.
|
||||
* **Assembly Revisions Only**: If this setting is enabled, only assembly parts can have revisions. This is useful if you only want to track revisions of assemblies, and not individual parts.
|
||||
|
||||
## Create a Revision
|
||||
|
||||
To create a new revision for a given part, navigate to the part detail page, and click on the "Revisions" tab.
|
||||
To create a new revision for a given part, navigate to the part detail page, and click on the part actions menu (three vertical dots on the top right of the page).
|
||||
|
||||
Select the "Duplicate Part" action, to create a new copy of the selected part. This will open the "Duplicate Part" form:
|
||||
|
||||
|
|
@ -67,4 +65,5 @@ When multiple revisions exist for a particular part, you can navigate between re
|
|||
|
||||
{{ image("part/part_revision_select.png", "Select part revision") }}
|
||||
|
||||
Note that this revision selector is only visible when multiple revisions exist for the part.
|
||||
!!! info "Revision Selector Visibility"
|
||||
Note that this revision selector is only visible when multiple revisions exist for the part.
|
||||
|
|
|
|||
|
|
@ -50,6 +50,17 @@ Within each role, there are four levels of available permissions:
|
|||
| **Add** | The *add* permission allows the user to add / create database records associated with the particular role |
|
||||
| **Delete** | The *delete* permission allows the user to delete / remove database records associated with the particular role |
|
||||
|
||||
## Dangerous User Flags
|
||||
|
||||
In addition to the above permissions, there are two special flags that can be assigned to a user:
|
||||
- **Staff** - A user with the *staff* flag is able to access the admin interface, and can trigger dangerous actions that might have a security impact such as changing parsable files on the server (templates / reports / plugins). Some of these actions require the *admin* role to be assigned as well.
|
||||
- **Superuser** - A user with the *superuser* flag is able to access and change all data and functions of InvenTree. A superuser can modify and access all data that the InvenTree installation / server has access to - including shell access on the server OS itself. This is a very powerful flag, and should be used with caution.
|
||||
|
||||
It is strongly recommended to register any users with staff / superuser flags with strong MFA methods to reduce the risk of unauthorized access. These accounts should be used with caution, and should not be used for day-to-day operations.
|
||||
|
||||
Practicing account tiering is strongly recommended.
|
||||
|
||||
|
||||
## Admin Interface Permissions
|
||||
|
||||
If a user does not have the required permissions to perform a certain action in the admin interface, those options not be displayed.
|
||||
|
|
|
|||
|
|
@ -185,7 +185,6 @@ Proxy configuration can be complex, and any configuration beyond the basic setup
|
|||
|
||||
Refer to the [proxy server documentation](./processes.md#proxy-server) for more information.
|
||||
|
||||
|
||||
## Admin Site
|
||||
|
||||
Django provides a powerful [administrator interface]({% include "django.html" %}/ref/contrib/admin/) which can be used to manage the InvenTree database. This interface is enabled by default, and available at the `/admin/` URL.
|
||||
|
|
@ -468,6 +467,17 @@ The login-experience can be altered with the following settings:
|
|||
|
||||
Custom authentication backends can be used by specifying them here. These can for example be used to add [LDAP / AD login](https://django-auth-ldap.readthedocs.io/en/latest/) to InvenTree
|
||||
|
||||
## Background Worker Options
|
||||
|
||||
The following options are available for configuring the InvenTree [background worker process](./processes.md#background-worker):
|
||||
|
||||
| Environment Variable | Configuration File | Description | Default |
|
||||
| --- | --- | --- | --- |
|
||||
| INVENTREE_BACKGROUND_WORKERS | background.workers | Number of background worker processes | 1 |
|
||||
| INVENTREE_BACKGROUND_TIMEOUT | background.timeout | Timeout for background worker tasks (seconds) | 90 |
|
||||
| INVENTREE_BACKGROUND_RETRY | background.retry | Time to wait before retrying a background task (seconds) | 300 |
|
||||
| INVENTREE_BACKGROUND_MAX_ATTEMPTS | background.max_attempts | Maximum number of attempts for a background task | 5 |
|
||||
|
||||
## Sentry Integration
|
||||
|
||||
The InvenTree server can be integrated with the [sentry.io](https://sentry.io) monitoring service, for error logging and performance tracking.
|
||||
|
|
@ -554,4 +564,4 @@ To override global settings, provide a "dictionary" of settings overrides in the
|
|||
|
||||
| Environment Variable | Configuration File | Description | Default |
|
||||
| --- | --- | --- | --- |
|
||||
| GLOBAL_SETTINGS_OVERRIDES | global_settings_overrides | JSON object containing global settings overrides | *Not specified* |
|
||||
| INVENTREE_GLOBAL_SETTINGS | global_settings | JSON object containing global settings overrides | *Not specified* |
|
||||
|
|
|
|||
|
|
@ -201,3 +201,32 @@ This will load the database records from the backup file into the new database.
|
|||
### Caveats
|
||||
|
||||
The process described here is a *suggested* procedure for migrating between incompatible database versions. However, due to the complexity of database software, there may be unforeseen complications that arise during the process.
|
||||
|
||||
## Migrating Plugin Data
|
||||
|
||||
Custom plugins may define their own database models, and thus have their own data records stored in the database. If a plugin is being migrated from one InvenTree installation to another, then the plugin data must also be migrated.
|
||||
|
||||
To account for this, the `export-records` and `import-records` commands have been designed to also export and import plugin data, in addition to the core InvenTree data.
|
||||
|
||||
### Exporting Plugin Data
|
||||
|
||||
When running the `export-records` command, any data records associated with plugins will also be exported, and included in the output JSON file.
|
||||
|
||||
### Importing Plugin Data
|
||||
|
||||
When running the `import-records` command, the import process will also attempt to import any plugin data records contained in the input JSON file. However, for the plugin data to be imported correctly, the following conditions must be met:
|
||||
|
||||
1. The plugin *code* must be present in the new InvenTree installation. Any plugins *not* installed will not have their tables created, and thus the import process will fail for those records.
|
||||
2. The plugin *version* must be the same in both installations. If the plugin version is different, then the database schema may be different, and thus the import process may fail.
|
||||
3. The InvenTree software version must be the same in both installations. If the InvenTree version is different, then the database schema may be different, and thus the import process may fail.
|
||||
|
||||
If all of the above conditions are met, then the plugin data *should* be imported correctly into the new database. To achieve this reliably, the following process steps are implemented in the `import-records` command:
|
||||
|
||||
1. The database is cleaned of all existing records (if the `-c` option is used).
|
||||
2. The core InvenTree database migrations are run to ensure that the core database schema is correct.
|
||||
3. User auth records are imported into the database
|
||||
4. Common configuration records (such as global settings) are imported into the database
|
||||
5. Plugin configuration records (defining which plugins are active) are imported into the database
|
||||
6. Database migrations are run once more, to ensure that any plugin database schema are correctly initialized
|
||||
7. The database is checked to ensure that all required apps are present (i.e. all plugins are installed and correctly activated)
|
||||
8. All remaining records (including plugin data) are imported into the database
|
||||
|
|
|
|||
|
|
@ -143,3 +143,7 @@ InvenTree uses the [Redis](https://redis.io/) cache server to manage cache data.
|
|||
|
||||
!!! tip "Enable Cache"
|
||||
While a redis container is provided in the default configuration, by default it is not enabled in the InvenTree server. You can enable redis cache support by following the [caching configuration guide](./config.md#caching)
|
||||
|
||||
### Configuration
|
||||
|
||||
Refer to the [background worker configuration options](./config.md#background-worker-options) for more information on configuring the background worker process.
|
||||
|
|
|
|||
|
|
@ -461,15 +461,15 @@ platformdirs==4.9.4 \
|
|||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# mkdocs-get-deps
|
||||
pygments==2.19.2 \
|
||||
--hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \
|
||||
--hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b
|
||||
pygments==2.20.0 \
|
||||
--hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \
|
||||
--hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176
|
||||
# via
|
||||
# mkdocs-material
|
||||
# rich
|
||||
pymdown-extensions==10.21 \
|
||||
--hash=sha256:39f4a020f40773f6b2ff31d2cd2546c2c04d0a6498c31d9c688d2be07e1767d5 \
|
||||
--hash=sha256:91b879f9f864d49794c2d9534372b10150e6141096c3908a455e45ca72ad9d3f
|
||||
pymdown-extensions==10.21.2 \
|
||||
--hash=sha256:5c0fd2a2bea14eb39af8ff284f1066d898ab2187d81b889b75d46d4348c01638 \
|
||||
--hash=sha256:c3f55a5b8a1d0edf6699e35dcbea71d978d34ff3fa79f3d807b8a5b3fa90fbdc
|
||||
# via
|
||||
# mkdocs-material
|
||||
# mkdocs-mermaid2-plugin
|
||||
|
|
|
|||
|
|
@ -21,16 +21,19 @@ from django.http import StreamingHttpResponse
|
|||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
import bleach
|
||||
import bleach.css_sanitizer
|
||||
import bleach.sanitizer
|
||||
import nh3
|
||||
import structlog
|
||||
from bleach import clean
|
||||
from djmoney.money import Money
|
||||
from PIL import Image
|
||||
from stdimage.models import StdImageField, StdImageFieldFile
|
||||
|
||||
from common.currency import currency_code_default
|
||||
from InvenTree.sanitizer import (
|
||||
DEAFAULT_ATTRS,
|
||||
DEFAULT_CSS,
|
||||
DEFAULT_PROTOCOLS,
|
||||
DEFAULT_TAGS,
|
||||
)
|
||||
|
||||
from .setting.storages import StorageBackends
|
||||
from .settings import MEDIA_URL, STATIC_URL
|
||||
|
|
@ -895,13 +898,13 @@ def clean_decimal(number):
|
|||
|
||||
|
||||
def strip_html_tags(value: str, raise_error=True, field_name=None):
|
||||
"""Strip HTML tags from an input string using the bleach library.
|
||||
"""Strip HTML tags from an input string using the nh3 library.
|
||||
|
||||
If raise_error is True, a ValidationError will be thrown if HTML tags are detected
|
||||
"""
|
||||
value = str(value).strip()
|
||||
|
||||
cleaned = clean(value, strip=True, tags=[], attributes=[])
|
||||
cleaned = nh3.clean(value, tags=frozenset())
|
||||
|
||||
# Add escaped characters back in
|
||||
replacements = {'>': '>', '<': '<', '&': '&'}
|
||||
|
|
@ -961,34 +964,32 @@ def clean_markdown(value: str) -> str:
|
|||
output_format='html',
|
||||
)
|
||||
|
||||
# Bleach settings
|
||||
whitelist_tags = markdownify_settings.get(
|
||||
'WHITELIST_TAGS', bleach.sanitizer.ALLOWED_TAGS
|
||||
)
|
||||
whitelist_attrs = markdownify_settings.get(
|
||||
'WHITELIST_ATTRS', bleach.sanitizer.ALLOWED_ATTRIBUTES
|
||||
)
|
||||
whitelist_styles = markdownify_settings.get(
|
||||
'WHITELIST_STYLES', bleach.css_sanitizer.ALLOWED_CSS_PROPERTIES
|
||||
)
|
||||
# nh3 sanitizer settings
|
||||
whitelist_tags = markdownify_settings.get('WHITELIST_TAGS', DEFAULT_TAGS)
|
||||
whitelist_attrs = markdownify_settings.get('WHITELIST_ATTRS', DEAFAULT_ATTRS)
|
||||
whitelist_styles = markdownify_settings.get('WHITELIST_STYLES', DEFAULT_CSS)
|
||||
whitelist_protocols = markdownify_settings.get(
|
||||
'WHITELIST_PROTOCOLS', bleach.sanitizer.ALLOWED_PROTOCOLS
|
||||
'WHITELIST_PROTOCOLS', DEFAULT_PROTOCOLS
|
||||
)
|
||||
strip = markdownify_settings.get('STRIP', True)
|
||||
|
||||
css_sanitizer = bleach.css_sanitizer.CSSSanitizer(
|
||||
allowed_css_properties=whitelist_styles
|
||||
)
|
||||
cleaner = bleach.Cleaner(
|
||||
tags=whitelist_tags,
|
||||
attributes=whitelist_attrs,
|
||||
css_sanitizer=css_sanitizer,
|
||||
protocols=whitelist_protocols,
|
||||
strip=strip,
|
||||
)
|
||||
# Convert bleach-style attributes (list or dict) to nh3-compatible dict format
|
||||
if isinstance(whitelist_attrs, (list, tuple, set, frozenset)):
|
||||
attrs_dict = {'*': set(whitelist_attrs)}
|
||||
elif isinstance(whitelist_attrs, dict):
|
||||
attrs_dict = {tag: set(allowed) for tag, allowed in whitelist_attrs.items()}
|
||||
else:
|
||||
attrs_dict = None
|
||||
|
||||
# Clean the HTML content (for comparison). This must be the same as the original content
|
||||
clean_html = cleaner.clean(html)
|
||||
clean_html = nh3.clean(
|
||||
html,
|
||||
tags=set(whitelist_tags),
|
||||
attributes=attrs_dict,
|
||||
url_schemes=set(whitelist_protocols),
|
||||
filter_style_properties=set(whitelist_styles),
|
||||
link_rel=None,
|
||||
strip_comments=True,
|
||||
)
|
||||
|
||||
if html != clean_html:
|
||||
raise ValidationError(_('Data contains prohibited markdown content'))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
"""Helpers for logging integrations."""
|
||||
|
||||
from django.dispatch import receiver
|
||||
|
||||
import structlog
|
||||
from django_structlog import signals
|
||||
|
||||
|
||||
@receiver(signals.update_failure_response)
|
||||
@receiver(signals.bind_extra_request_finished_metadata)
|
||||
def add_request_id_to_response(response, logger, **kwargs):
|
||||
"""Add the request ID to the response header, so that it can be traced through logs.
|
||||
|
||||
source: https://django-structlog.readthedocs.io/en/latest/how_tos.html#bind-request-id-to-response-s-header
|
||||
"""
|
||||
context = structlog.contextvars.get_merged_contextvars(logger)
|
||||
response['X-InvenTree-ReqId'] = context['request_id']
|
||||
|
|
@ -19,7 +19,7 @@ from InvenTree.serializers import FilterableSerializerMixin
|
|||
|
||||
|
||||
class CleanMixin:
|
||||
"""Model mixin class which cleans inputs using the Mozilla bleach tools."""
|
||||
"""Model mixin class which cleans inputs using nh3."""
|
||||
|
||||
# Define a list of field names which will *not* be cleaned
|
||||
SAFE_FIELDS = []
|
||||
|
|
@ -52,16 +52,7 @@ class CleanMixin:
|
|||
return Response(serializer.data)
|
||||
|
||||
def clean_string(self, field: str, data: str) -> str:
|
||||
"""Clean / sanitize a single input string.
|
||||
|
||||
Note that this function will *allow* orphaned <>& characters,
|
||||
which would normally be escaped by bleach.
|
||||
|
||||
Nominally, the only thing that will be "cleaned" will be HTML tags
|
||||
|
||||
Ref: https://github.com/mozilla/bleach/issues/192
|
||||
|
||||
"""
|
||||
"""Clean / sanitize a single input string."""
|
||||
cleaned = data
|
||||
|
||||
# By default, newline characters are removed
|
||||
|
|
@ -101,7 +92,7 @@ class CleanMixin:
|
|||
def clean_data(self, data: dict) -> dict:
|
||||
"""Clean / sanitize data.
|
||||
|
||||
This uses Mozilla's bleach under the hood to disable certain html tags by
|
||||
This uses nh3 under the hood to disable certain html tags by
|
||||
encoding them - this leads to script tags etc. to not work.
|
||||
The results can be longer then the input; might make some character combinations
|
||||
`ugly`. Prevents XSS on the server-level.
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ def isGeneratingSchema():
|
|||
'qcluster',
|
||||
'check',
|
||||
'shell',
|
||||
'help',
|
||||
]
|
||||
|
||||
if any(cmd in sys.argv for cmd in excluded_commands):
|
||||
|
|
@ -132,12 +133,14 @@ def isGeneratingSchema():
|
|||
|
||||
included_commands = [
|
||||
'schema',
|
||||
'spectactular',
|
||||
# schema adjacent calls
|
||||
'export_settings_definitions',
|
||||
'export_tags',
|
||||
'export_filters',
|
||||
'export_report_context',
|
||||
]
|
||||
|
||||
if any(cmd in sys.argv for cmd in included_commands):
|
||||
return True
|
||||
|
||||
|
|
@ -185,11 +188,38 @@ def isInMainThread():
|
|||
return not isInWorkerThread()
|
||||
|
||||
|
||||
def readOnlyCommands():
|
||||
"""Return a list of read-only management commands which should not trigger database writes."""
|
||||
return [
|
||||
'help',
|
||||
'check',
|
||||
'shell',
|
||||
'sqlflush',
|
||||
'list_apps',
|
||||
'wait_for_db',
|
||||
'spectactular',
|
||||
'makemessages',
|
||||
'collectstatic',
|
||||
'showmigrations',
|
||||
'compilemessages',
|
||||
]
|
||||
|
||||
|
||||
def isReadOnlyCommand():
|
||||
"""Return True if the current command is a read-only command, which should not trigger any database writes."""
|
||||
return any(cmd in sys.argv for cmd in readOnlyCommands())
|
||||
|
||||
|
||||
def canAppAccessDatabase(
|
||||
allow_test: bool = False, allow_plugins: bool = False, allow_shell: bool = False
|
||||
):
|
||||
"""Returns True if the apps.py file can access database records.
|
||||
|
||||
Arguments:
|
||||
allow_test: If True, override checks and allow database access during testing mode
|
||||
allow_plugins: If True, override checks and allow database access during plugin loading
|
||||
allow_shell: If True, override checks and allow database access during shell sessions
|
||||
|
||||
There are some circumstances where we don't want the ready function in apps.py
|
||||
to touch the database
|
||||
"""
|
||||
|
|
@ -198,7 +228,7 @@ def canAppAccessDatabase(
|
|||
return False
|
||||
|
||||
# Prevent database access if we are importing data
|
||||
if isImportingData():
|
||||
if not allow_plugins and isImportingData():
|
||||
return False
|
||||
|
||||
# Prevent database access if we are rebuilding data
|
||||
|
|
@ -212,13 +242,13 @@ def canAppAccessDatabase(
|
|||
# If any of the following management commands are being executed,
|
||||
# prevent custom "on load" code from running!
|
||||
excluded_commands = [
|
||||
'check',
|
||||
'createsuperuser',
|
||||
'wait_for_db',
|
||||
'makemessages',
|
||||
'compilemessages',
|
||||
'spectactular',
|
||||
'createsuperuser',
|
||||
'collectstatic',
|
||||
'makemessages',
|
||||
'spectactular',
|
||||
'wait_for_db',
|
||||
'check',
|
||||
]
|
||||
|
||||
if not allow_shell:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,66 @@
|
|||
"""Functions to sanitize user input files."""
|
||||
|
||||
from bleach import clean
|
||||
from bleach.css_sanitizer import CSSSanitizer
|
||||
import nh3
|
||||
|
||||
# Allowed CSS properties for SVG sanitization (combines general CSS and SVG-specific properties)
|
||||
_SVG_ALLOWED_CSS_PROPERTIES = frozenset([
|
||||
# General CSS (matching bleach's original ALLOWED_CSS_PROPERTIES)
|
||||
'azimuth',
|
||||
'background-color',
|
||||
'border-bottom-color',
|
||||
'border-collapse',
|
||||
'border-color',
|
||||
'border-left-color',
|
||||
'border-right-color',
|
||||
'border-top-color',
|
||||
'clear',
|
||||
'color',
|
||||
'cursor',
|
||||
'direction',
|
||||
'display',
|
||||
'elevation',
|
||||
'float',
|
||||
'font',
|
||||
'font-family',
|
||||
'font-size',
|
||||
'font-style',
|
||||
'font-variant',
|
||||
'font-weight',
|
||||
'height',
|
||||
'letter-spacing',
|
||||
'line-height',
|
||||
'overflow',
|
||||
'pause',
|
||||
'pause-after',
|
||||
'pause-before',
|
||||
'pitch',
|
||||
'pitch-range',
|
||||
'richness',
|
||||
'speak',
|
||||
'speak-header',
|
||||
'speak-numeral',
|
||||
'speak-punctuation',
|
||||
'speech-rate',
|
||||
'stress',
|
||||
'text-align',
|
||||
'text-decoration',
|
||||
'text-indent',
|
||||
'unicode-bidi',
|
||||
'vertical-align',
|
||||
'voice-family',
|
||||
'volume',
|
||||
'white-space',
|
||||
'width',
|
||||
# SVG-specific CSS (matching bleach's ALLOWED_SVG_PROPERTIES)
|
||||
'fill',
|
||||
'fill-opacity',
|
||||
'fill-rule',
|
||||
'stroke',
|
||||
'stroke-linecap',
|
||||
'stroke-linejoin',
|
||||
'stroke-opacity',
|
||||
'stroke-width',
|
||||
])
|
||||
|
||||
ALLOWED_ELEMENTS_SVG = [
|
||||
'a',
|
||||
|
|
@ -184,6 +243,74 @@ ALLOWED_ATTRIBUTES_SVG = [
|
|||
'style',
|
||||
]
|
||||
|
||||
# Default allowlists (matching bleach's original defaults)
|
||||
# TODO: I do not see us needing a bunch of these but I do not want to introduce a breaking change; we might want to narroy this down with the next breaking change
|
||||
DEFAULT_TAGS = frozenset([
|
||||
'a',
|
||||
'abbr',
|
||||
'acronym',
|
||||
'b',
|
||||
'blockquote',
|
||||
'code',
|
||||
'em',
|
||||
'i',
|
||||
'li',
|
||||
'ol',
|
||||
'strong',
|
||||
'ul',
|
||||
])
|
||||
DEAFAULT_ATTRS = {'a': {'href', 'title'}, 'abbr': {'title'}, 'acronym': {'title'}}
|
||||
DEFAULT_CSS = frozenset([
|
||||
'azimuth',
|
||||
'background-color',
|
||||
'border-bottom-color',
|
||||
'border-collapse',
|
||||
'border-color',
|
||||
'border-left-color',
|
||||
'border-right-color',
|
||||
'border-top-color',
|
||||
'clear',
|
||||
'color',
|
||||
'cursor',
|
||||
'direction',
|
||||
'display',
|
||||
'elevation',
|
||||
'float',
|
||||
'font',
|
||||
'font-family',
|
||||
'font-size',
|
||||
'font-style',
|
||||
'font-variant',
|
||||
'font-weight',
|
||||
'height',
|
||||
'letter-spacing',
|
||||
'line-height',
|
||||
'overflow',
|
||||
'pause',
|
||||
'pause-after',
|
||||
'pause-before',
|
||||
'pitch',
|
||||
'pitch-range',
|
||||
'richness',
|
||||
'speak',
|
||||
'speak-header',
|
||||
'speak-numeral',
|
||||
'speak-punctuation',
|
||||
'speech-rate',
|
||||
'stress',
|
||||
'text-align',
|
||||
'text-decoration',
|
||||
'text-indent',
|
||||
'unicode-bidi',
|
||||
'vertical-align',
|
||||
'voice-family',
|
||||
'volume',
|
||||
'white-space',
|
||||
'width',
|
||||
])
|
||||
# TODO: We might want to respect the setting EXTRA_URL_SCHEMES here but that would be breaking
|
||||
DEFAULT_PROTOCOLS = frozenset(['http', 'https', 'mailto'])
|
||||
|
||||
|
||||
def sanitize_svg(
|
||||
file_data,
|
||||
|
|
@ -206,13 +333,16 @@ def sanitize_svg(
|
|||
if isinstance(file_data, bytes):
|
||||
file_data = file_data.decode('utf-8')
|
||||
|
||||
cleaned = clean(
|
||||
# nh3 requires attributes as dict[str, set[str]]; convert from list (allowed for all elements)
|
||||
attrs_dict = {elem: set(attributes) for elem in elements}
|
||||
|
||||
cleaned = nh3.clean(
|
||||
file_data,
|
||||
tags=elements,
|
||||
attributes=attributes,
|
||||
strip=strip,
|
||||
tags=set(elements),
|
||||
attributes=attrs_dict,
|
||||
filter_style_properties=_SVG_ALLOWED_CSS_PROPERTIES,
|
||||
strip_comments=strip,
|
||||
css_sanitizer=CSSSanitizer(),
|
||||
link_rel=None,
|
||||
)
|
||||
|
||||
return cleaned
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
"""Serializers used in various InvenTree apps."""
|
||||
|
||||
import os
|
||||
from collections import OrderedDict
|
||||
from copy import deepcopy
|
||||
from decimal import Decimal
|
||||
from typing import Any, Optional
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import ValidationError as DjangoValidationError
|
||||
from django.core.files.storage import default_storage
|
||||
from django.db import models
|
||||
from django.db.models import QuerySet
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
|
@ -33,8 +32,6 @@ from InvenTree.fields import InvenTreeRestURLField, InvenTreeURLField
|
|||
from InvenTree.helpers import str2bool
|
||||
from InvenTree.helpers_model import getModelsWithMixin
|
||||
|
||||
from .setting.storages import StorageBackends
|
||||
|
||||
|
||||
# region path filtering
|
||||
class FilterableSerializerField:
|
||||
|
|
@ -689,9 +686,7 @@ class InvenTreeAttachmentSerializerField(serializers.FileField):
|
|||
if not value:
|
||||
return None
|
||||
|
||||
if settings.STORAGE_TARGET == StorageBackends.S3:
|
||||
return str(value.url)
|
||||
return os.path.join(str(settings.MEDIA_URL), str(value))
|
||||
return default_storage.url(str(value))
|
||||
|
||||
|
||||
class InvenTreeImageSerializerField(serializers.ImageField):
|
||||
|
|
@ -705,9 +700,7 @@ class InvenTreeImageSerializerField(serializers.ImageField):
|
|||
if not value:
|
||||
return None
|
||||
|
||||
if settings.STORAGE_TARGET == StorageBackends.S3:
|
||||
return str(value.url)
|
||||
return os.path.join(str(settings.MEDIA_URL), str(value))
|
||||
return default_storage.url(str(value))
|
||||
|
||||
|
||||
class InvenTreeDecimalField(serializers.FloatField):
|
||||
|
|
|
|||
|
|
@ -194,6 +194,9 @@ PLUGINS_MANDATORY = get_setting(
|
|||
'INVENTREE_PLUGINS_MANDATORY', 'plugins_mandatory', typecast=list, default_value=[]
|
||||
)
|
||||
|
||||
if PLUGINS_MANDATORY:
|
||||
logger.info('Mandatory plugins: %s', PLUGINS_MANDATORY)
|
||||
|
||||
PLUGINS_INSTALL_DISABLED = get_boolean_setting(
|
||||
'INVENTREE_PLUGIN_NOINSTALL', 'plugin_noinstall', False
|
||||
)
|
||||
|
|
@ -831,10 +834,15 @@ GLOBAL_CACHE_ENABLED = is_global_cache_enabled()
|
|||
|
||||
CACHES = {'default': get_cache_config(GLOBAL_CACHE_ENABLED)}
|
||||
|
||||
_q_worker_timeout = int(
|
||||
BACKGROUND_WORKER_TIMEOUT = int(
|
||||
get_setting('INVENTREE_BACKGROUND_TIMEOUT', 'background.timeout', 90)
|
||||
)
|
||||
|
||||
# Set the retry time for background workers to be slightly longer than the worker timeout, to ensure that workers have time to timeout before being retried
|
||||
BACKGROUND_WORKER_RETRY = max(
|
||||
int(get_setting('INVENTREE_BACKGROUND_RETRY', 'background.retry', 300)),
|
||||
BACKGROUND_WORKER_TIMEOUT + 120,
|
||||
)
|
||||
|
||||
# Prevent running multiple background workers if global cache is disabled
|
||||
# This is to prevent scheduling conflicts due to the lack of a shared cache
|
||||
|
|
@ -848,16 +856,18 @@ BACKGROUND_WORKER_COUNT = (
|
|||
if 'sqlite' in DB_ENGINE:
|
||||
BACKGROUND_WORKER_COUNT = 1
|
||||
|
||||
BACKGROUND_WORKER_ATTEMPTS = int(
|
||||
get_setting('INVENTREE_BACKGROUND_MAX_ATTEMPTS', 'background.max_attempts', 5)
|
||||
)
|
||||
|
||||
# django-q background worker configuration
|
||||
Q_CLUSTER = {
|
||||
'name': 'InvenTree',
|
||||
'label': 'Background Tasks',
|
||||
'workers': BACKGROUND_WORKER_COUNT,
|
||||
'timeout': _q_worker_timeout,
|
||||
'retry': max(120, _q_worker_timeout + 30),
|
||||
'max_attempts': int(
|
||||
get_setting('INVENTREE_BACKGROUND_MAX_ATTEMPTS', 'background.max_attempts', 5)
|
||||
),
|
||||
'timeout': BACKGROUND_WORKER_TIMEOUT,
|
||||
'retry': BACKGROUND_WORKER_RETRY,
|
||||
'max_attempts': BACKGROUND_WORKER_ATTEMPTS,
|
||||
'save_limit': 1000,
|
||||
'queue_limit': 50,
|
||||
'catch_up': False,
|
||||
|
|
|
|||
|
|
@ -1604,11 +1604,11 @@ class SanitizerTest(TestCase):
|
|||
def test_svg_sanitizer(self):
|
||||
"""Test that SVGs are sanitized accordingly."""
|
||||
valid_string = """<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="svg2" height="400" width="400">{0}
|
||||
<path id="path1" d="m -151.78571,359.62883 v 112.76373 l 97.068507,-56.04253 V 303.14815 Z" style="fill:#ddbc91;"></path>
|
||||
<path id="path1" d="m -151.78571,359.62883 v 112.76373 l 97.068507,-56.04253 V 303.14815 Z" style="fill:#ddbc91"></path>
|
||||
</svg>"""
|
||||
dangerous_string = valid_string.format('<script>alert();</script>')
|
||||
|
||||
# Test that valid string
|
||||
# Test that valid string passes through unchanged
|
||||
self.assertEqual(valid_string, sanitize_svg(valid_string))
|
||||
|
||||
# Test that invalid string is cleaned
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import build.api
|
|||
import common.api
|
||||
import company.api
|
||||
import importer.api
|
||||
import InvenTree.logging # noqa: F401 - ensure logging handlers are registered
|
||||
import machine.api
|
||||
import order.api
|
||||
import part.api
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -776,18 +776,12 @@ class Part(
|
|||
'revision_of': _('Part cannot be a revision of itself')
|
||||
})
|
||||
|
||||
# Part cannot be a revision of a part which is itself a revision
|
||||
if self.revision_of.revision_of:
|
||||
raise ValidationError({
|
||||
'revision_of': _(
|
||||
'Cannot make a revision of a part which is already a revision'
|
||||
)
|
||||
})
|
||||
|
||||
# If this part is a revision, it must have a revision code
|
||||
if not self.revision:
|
||||
raise ValidationError({
|
||||
'revision': _('Revision code must be specified')
|
||||
'revision': _(
|
||||
'Revision code must be specified for a part marked as a revision'
|
||||
)
|
||||
})
|
||||
|
||||
if get_global_setting('PART_REVISION_ASSEMBLY_ONLY'):
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ class PartCategoryAPITest(InvenTreeAPITestCase):
|
|||
# There should not be any templates left at this point
|
||||
self.assertEqual(PartCategoryParameterTemplate.objects.count(), 0)
|
||||
|
||||
def test_bleach(self):
|
||||
def test_sanitizer(self):
|
||||
"""Test that the data cleaning functionality is working.
|
||||
|
||||
This helps to protect against XSS injection
|
||||
|
|
|
|||
|
|
@ -412,15 +412,11 @@ class PartTest(TestCase):
|
|||
name='Master Part', description='Master part (revision B)'
|
||||
)
|
||||
|
||||
with self.assertRaises(ValidationError) as exc:
|
||||
rev_b.revision_of = rev_a
|
||||
rev_b.revision = 'B'
|
||||
rev_b.save()
|
||||
|
||||
self.assertIn(
|
||||
'Cannot make a revision of a part which is already a revision',
|
||||
str(exc.exception),
|
||||
)
|
||||
# Ensure we can make a revision of a revision
|
||||
rev_b.revision_of = rev_a
|
||||
rev_b.variant_of = template
|
||||
rev_b.revision = 'B'
|
||||
rev_b.save()
|
||||
|
||||
rev_b.variant_of = template
|
||||
rev_b.revision_of = part
|
||||
|
|
|
|||
|
|
@ -222,13 +222,18 @@ class PluginsRegistry:
|
|||
import InvenTree.ready
|
||||
from plugin.models import PluginConfig
|
||||
|
||||
if InvenTree.ready.isImportingData():
|
||||
return None
|
||||
# Under certain circumstances, we want to avoid creating new PluginConfig instances in the database
|
||||
can_create = (
|
||||
InvenTree.ready.canAppAccessDatabase(
|
||||
allow_plugins=False, allow_shell=True, allow_test=True
|
||||
)
|
||||
and not InvenTree.ready.isReadOnlyCommand()
|
||||
)
|
||||
|
||||
try:
|
||||
cfg = PluginConfig.objects.filter(key=slug).first()
|
||||
|
||||
if not cfg:
|
||||
if not cfg and can_create:
|
||||
logger.debug(
|
||||
"get_plugin_config: Creating new PluginConfig for '%s'", slug
|
||||
)
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@ class ReportConfig(AppConfig):
|
|||
if not InvenTree.ready.canAppAccessDatabase(allow_test=False):
|
||||
return # pragma: no cover
|
||||
|
||||
if InvenTree.ready.isReadOnlyCommand():
|
||||
return # pragma: no cover
|
||||
|
||||
with maintenance_mode_on():
|
||||
try:
|
||||
self.create_default_labels()
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ def image_data(img, fmt='PNG') -> str:
|
|||
def clean_barcode(data):
|
||||
"""Return a 'cleaned' string for encoding into a barcode / qrcode.
|
||||
|
||||
- This function runs the data through bleach, and removes any malicious HTML content.
|
||||
- This function sanitizes the data using nh3, and removes any malicious HTML content.
|
||||
- Used to render raw barcode data into the rendered HTML templates
|
||||
"""
|
||||
from InvenTree.helpers import strip_html_tags
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
import base64
|
||||
import logging
|
||||
import os
|
||||
from datetime import date, datetime
|
||||
from decimal import Decimal, InvalidOperation
|
||||
from io import BytesIO
|
||||
|
|
@ -11,7 +10,6 @@ from typing import Any, Optional
|
|||
|
||||
from django import template
|
||||
from django.apps.registry import apps
|
||||
from django.conf import settings
|
||||
from django.contrib.staticfiles.storage import staticfiles_storage
|
||||
from django.core.exceptions import SuspiciousFileOperation, ValidationError
|
||||
from django.core.files.storage import default_storage
|
||||
|
|
@ -292,7 +290,7 @@ def asset(filename: str, raise_error: bool = False) -> str | None:
|
|||
|
||||
# In debug mode, return a web URL to the asset file (rather than a local file path)
|
||||
if get_global_setting('REPORT_DEBUG_MODE', cache=False):
|
||||
return str(Path(settings.MEDIA_URL, 'report', 'assets', filename))
|
||||
return default_storage.url(str(full_path))
|
||||
|
||||
storage_path = default_storage.path(str(full_path))
|
||||
|
||||
|
|
@ -368,8 +366,9 @@ def uploaded_image(
|
|||
if debug_mode:
|
||||
# In debug mode, return a web path (rather than an encoded image blob)
|
||||
if exists:
|
||||
return os.path.join(settings.MEDIA_URL, filename)
|
||||
return os.path.join(settings.STATIC_URL, 'img', replacement_file)
|
||||
return default_storage.url(filename)
|
||||
|
||||
return staticfiles_storage.url(str(Path('img', replacement_file)))
|
||||
|
||||
if img_data:
|
||||
img = Image.open(BytesIO(img_data))
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ from rest_framework.authtoken.models import Token as AuthToken
|
|||
import InvenTree.helpers
|
||||
import InvenTree.models
|
||||
from common.settings import get_global_setting
|
||||
from InvenTree.ready import isImportingData
|
||||
from InvenTree.ready import isImportingData, isReadOnlyCommand
|
||||
|
||||
from .ruleset import RULESET_CHOICES, get_ruleset_models
|
||||
|
||||
|
|
@ -463,7 +463,7 @@ class Owner(models.Model):
|
|||
def create_owner(sender, instance, **kwargs):
|
||||
"""Callback function to create a new owner instance after either a new group or user instance is saved."""
|
||||
# Ignore during data import process to avoid data duplication
|
||||
if not isImportingData():
|
||||
if not isReadOnlyCommand() and not isImportingData():
|
||||
Owner.create(obj=instance)
|
||||
|
||||
|
||||
|
|
@ -600,8 +600,8 @@ class UserProfile(InvenTree.models.MetadataMixin):
|
|||
@receiver(post_save, sender=User)
|
||||
def create_or_update_user_profile(sender, instance, created, **kwargs):
|
||||
"""Create or update user profile when user is saved."""
|
||||
# Disable profile creation if importing data from file
|
||||
if isImportingData():
|
||||
# Disable profile creation if importing data from file or running a read-only command
|
||||
if isReadOnlyCommand() or isImportingData():
|
||||
return
|
||||
|
||||
if created:
|
||||
|
|
|
|||
|
|
@ -89,28 +89,28 @@ bcrypt==5.0.0 \
|
|||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# paramiko
|
||||
bleach[css]==6.3.0 \
|
||||
--hash=sha256:6f3b91b1c0a02bb9a78b5a454c92506aa0fdf197e1d5e114d2e00c6f64306d22 \
|
||||
--hash=sha256:fe10ec77c93ddf3d13a73b035abaac7a9f5e436513864ccdad516693213c65d6
|
||||
bleach==4.1.0 \
|
||||
--hash=sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da \
|
||||
--hash=sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994
|
||||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# django-markdownify
|
||||
blessed==1.33.0 \
|
||||
--hash=sha256:1bc8ecac6d139286ea51ec1683433528ce75b0c60db77b7d881112bf9fc85b0f \
|
||||
--hash=sha256:c732a1043042d84f411423a1a7b74643e1dd3a2271bd6e5955682dd4a321b0ef
|
||||
blessed==1.34.0 \
|
||||
--hash=sha256:3d17468c3d47e11ed8d6ca3da1270b8aba8ac8bd0a55a1f8189e4d04f223a1f0 \
|
||||
--hash=sha256:eb403f9ce2efab633bd1e7a05fbb35b979a7b9f213ddc41478dd55dd6999e8bf
|
||||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# -r src/backend/requirements.in
|
||||
boto3==1.42.72 \
|
||||
--hash=sha256:2b5fdac4f202b2ccb9ed21f8b84229463b15573ea16941c2b1b8db1c69e08b63 \
|
||||
--hash=sha256:932f023ea3b54fd85df453dcfff7d8c5a0f8be144c0ad57568943505c72c1e6a
|
||||
boto3==1.42.76 \
|
||||
--hash=sha256:63c6779c814847016b89ae1b72ed968f8a63d80e589ba337511aa6fc1b59585e \
|
||||
--hash=sha256:aa2b1973eee8973a9475d24bb579b1dee7176595338d4e4f7880b5c6189b8814
|
||||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# django-anymail
|
||||
# django-storages
|
||||
botocore==1.42.72 \
|
||||
--hash=sha256:038f34553da68df2ce70edc729f170cc198678daaad43f98649727c59f6404d4 \
|
||||
--hash=sha256:491b75eb41d46cf99cf8d6cab89f2e2c3602ce8e90d738a1da217a5fb6b2b7ef
|
||||
botocore==1.42.76 \
|
||||
--hash=sha256:151e714ae3c32f68ea0b4dc60751401e03f84a87c6cf864ea0ee64aa10eb4607 \
|
||||
--hash=sha256:c553fa0ae29e36a5c407f74da78b78404b81b74b15fb62bf640a3cd9385f0874
|
||||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# boto3
|
||||
|
|
@ -631,9 +631,9 @@ django-maintenance-mode==0.22.0 \
|
|||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# -r src/backend/requirements.in
|
||||
django-markdownify==0.9.6 \
|
||||
--hash=sha256:9863b2bfa6d159ad1423dc93bf0d6eadc6413776de304049aa9fcfa5edd2ce1c \
|
||||
--hash=sha256:edcf47b2026d55a8439049d35c8b54e11066a4856c4fad1060e139cb3d2eee52
|
||||
django-markdownify==0.9.1 \
|
||||
--hash=sha256:06ff2994ff09ce030b50de8c6fc5b89b9c25a66796948aff55370716ca1233af \
|
||||
--hash=sha256:24ba68b8a5996b6ec9632d11a3fd2e7159cb7e6becd3104e0a9372b5a2a148ef
|
||||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# -r src/backend/requirements.in
|
||||
|
|
@ -736,9 +736,9 @@ django-xforwardedfor-middleware==2.0 \
|
|||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# -r src/backend/requirements.in
|
||||
djangorestframework==3.17.0 \
|
||||
--hash=sha256:456fd992a33f9e64c9d0f47e85d9787db0efb44f894c1e513315b5e74765bd4c \
|
||||
--hash=sha256:d84fe85f30b7ac6e8c0076ce9ff635e4eaedca5912f8d7d2926ce448c08533ba
|
||||
djangorestframework==3.17.1 \
|
||||
--hash=sha256:a6def5f447fe78ff853bff1d47a3c59bf38f5434b031780b351b0c73a62db1a5 \
|
||||
--hash=sha256:c3c74dd3e83a5a3efc37b3c18d92bd6f86a6791c7b7d4dff62bb068500e76457
|
||||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# -r src/backend/requirements.in
|
||||
|
|
@ -959,9 +959,9 @@ grpcio==1.78.0 \
|
|||
# -c src/backend/requirements.txt
|
||||
# -r src/backend/requirements.in
|
||||
# opentelemetry-exporter-otlp-proto-grpc
|
||||
gunicorn==25.1.0 \
|
||||
--hash=sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616 \
|
||||
--hash=sha256:d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b
|
||||
gunicorn==25.2.0 \
|
||||
--hash=sha256:10bd7adb36d44945d97d0a1fdf9a0fb086ae9c7b39e56b4dece8555a6bf4a09c \
|
||||
--hash=sha256:88f5b444d0055bf298435384af7294f325e2273fd37ba9f9ff7b98e0a1e5dfdc
|
||||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# -r src/backend/requirements.in
|
||||
|
|
@ -1277,6 +1277,37 @@ markupsafe==3.0.3 \
|
|||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# jinja2
|
||||
nh3==0.3.4 \
|
||||
--hash=sha256:07999b998bf89692738f15c0eac76a416382932f855709e0b7488b595c30ec89 \
|
||||
--hash=sha256:0961a27dc2057c38d0364cb05880e1997ae1c80220cbc847db63213720b8f304 \
|
||||
--hash=sha256:0d825722a1e8cbc87d7ca1e47ffb1d2a6cf343ad4c1b8465becf7cadcabcdfd0 \
|
||||
--hash=sha256:18a2e44ccb29cbb45071b8f3f2dab9ebfb41a6516f328f91f1f1fd18196239a4 \
|
||||
--hash=sha256:3390e4333883673a684ce16c1716b481e91782d6f56dec5c85fed9feedb23382 \
|
||||
--hash=sha256:41e46b3499918ab6128b6421677b316e79869d0c140da24069d220a94f4e72d1 \
|
||||
--hash=sha256:43ad4eedee7e049b9069bc015b7b095d320ed6d167ecec111f877de1540656e9 \
|
||||
--hash=sha256:47d749d99ae005ab19517224140b280dd56e77b33afb82f9b600e106d0458003 \
|
||||
--hash=sha256:4aa8b43e68c26b68069a3b6cef09de166d1d7fa140cf8d77e409a46cbf742e44 \
|
||||
--hash=sha256:554cc2bab281758e94d770c3fb0bf2d8be5fb403ef6b2e8841dd7c1615df7a0f \
|
||||
--hash=sha256:72e4e9ca1c4bd41b4a28b0190edc2e21e3f71496acd36a0162858e1a28db3d7e \
|
||||
--hash=sha256:75643c22f5092d8e209f766ee8108c400bc1e44760fc94d2d638eb138d18f853 \
|
||||
--hash=sha256:7cae217f031809321db962cd7e092bda8d4e95a87f78c0226628fa6c2ea8ebc5 \
|
||||
--hash=sha256:80b955d802bf365bd42e09f6c3d64567dce777d20e97968d94b3e9d9e99b265e \
|
||||
--hash=sha256:87dac8d611b4a478400e0821a13b35770e88c266582f065e7249d6a37b0f86e8 \
|
||||
--hash=sha256:883d5a6d6ee8078c4afc8e96e022fe579c4c265775ff6ee21e39b8c542cabab3 \
|
||||
--hash=sha256:8b61058f34c2105d44d2a4d4241bacf603a1ef5c143b08766bbd0cf23830118f \
|
||||
--hash=sha256:8d697e19f2995b337f648204848ac3a528eaafffc39e7ce4ac6b7a2fbe6c84af \
|
||||
--hash=sha256:9337517edb7c10228252cce2898e20fb3d77e32ffaccbb3c66897927d74215a0 \
|
||||
--hash=sha256:96709a379997c1b28c8974146ca660b0dcd3794f4f6d50c1ea549bab39ac6ade \
|
||||
--hash=sha256:c10b1f0c741e257a5cb2978d6bac86e7c784ab20572724b20c6402c2e24bce75 \
|
||||
--hash=sha256:ca90397c8d36c1535bf1988b2bed006597337843a164c7ec269dc8813f37536b \
|
||||
--hash=sha256:d866701affe67a5171b916b5c076e767a74c6a9efb7fb2006eb8d3c5f9a293d5 \
|
||||
--hash=sha256:d8bebcb20ab4b91858385cd98fe58046ec4a624275b45ef9b976475604f45b49 \
|
||||
--hash=sha256:dbe76feaa44e2ef9436f345016012a591550e77818876a8de5c8bc2a248e08df \
|
||||
--hash=sha256:f5f214618ad5eff4f2a6b13a8d4da4d9e7f37c569d90a13fb9f0caaf7d04fe21 \
|
||||
--hash=sha256:f987cb56458323405e8e5ea827e1befcf141ffa0c0ac797d6d02e6b646056d9a
|
||||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# -r src/backend/requirements.in
|
||||
oauthlib==3.3.1 \
|
||||
--hash=sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9 \
|
||||
--hash=sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1
|
||||
|
|
@ -1447,6 +1478,7 @@ packaging==26.0 \
|
|||
--hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529
|
||||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# bleach
|
||||
# gunicorn
|
||||
# opentelemetry-instrumentation
|
||||
paramiko==4.0.0 \
|
||||
|
|
@ -1915,9 +1947,9 @@ rapidfuzz==3.14.3 \
|
|||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# -r src/backend/requirements.in
|
||||
redis==7.3.0 \
|
||||
--hash=sha256:4d1b768aafcf41b01022410b3cc4f15a07d9b3d6fe0c66fc967da2c88e551034 \
|
||||
--hash=sha256:9d4fcb002a12a5e3c3fbe005d59c48a2cc231f87fbb2f6b70c2d89bb64fec364
|
||||
redis==7.4.0 \
|
||||
--hash=sha256:64a6ea7bf567ad43c964d2c30d82853f8df927c5c9017766c55a1d1ed95d18ad \
|
||||
--hash=sha256:a9c74a5c893a5ef8455a5adb793a31bb70feb821c86eccb62eebef5a19c429ec
|
||||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# django-redis
|
||||
|
|
@ -2063,9 +2095,9 @@ s3transfer==0.16.0 \
|
|||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# boto3
|
||||
sentry-sdk==2.55.0 \
|
||||
--hash=sha256:3774c4d8820720ca4101548131b9c162f4c9426eb7f4d24aca453012a7470f69 \
|
||||
--hash=sha256:97026981cb15699394474a196b88503a393cbc58d182ece0d3abe12b9bd978d4
|
||||
sentry-sdk==2.56.0 \
|
||||
--hash=sha256:5afafb744ceb91d22f4cc650c6bd048ac6af5f7412dcc6c59305a2e36f4dbc02 \
|
||||
--hash=sha256:fdab72030b69625665b2eeb9738bdde748ad254e8073085a0ce95382678e8168
|
||||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# -r src/backend/requirements.in
|
||||
|
|
@ -2086,6 +2118,7 @@ six==1.17.0 \
|
|||
--hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81
|
||||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# bleach
|
||||
# python-dateutil
|
||||
sqlparse==0.5.5 \
|
||||
--hash=sha256:12a08b3bf3eec877c519589833aed092e2444e68240a3577e8e26148acc7b1ba \
|
||||
|
|
@ -2106,12 +2139,11 @@ tablib[xls, xlsx, yaml]==3.9.0 \
|
|||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# -r src/backend/requirements.in
|
||||
tinycss2==1.4.0 \
|
||||
--hash=sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7 \
|
||||
--hash=sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289
|
||||
tinycss2==1.5.1 \
|
||||
--hash=sha256:3415ba0f5839c062696996998176c4a3751d18b7edaaeeb658c9ce21ec150661 \
|
||||
--hash=sha256:d339d2b616ba90ccce58da8495a78f46e55d4d25f9fd71dfd526f07e7d53f957
|
||||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# bleach
|
||||
# cssselect2
|
||||
# weasyprint
|
||||
tinyhtml5==2.1.0 \
|
||||
|
|
@ -2165,9 +2197,9 @@ wcwidth==0.6.0 \
|
|||
# -c src/backend/requirements.txt
|
||||
# blessed
|
||||
# prettytable
|
||||
weasyprint==66.0 \
|
||||
--hash=sha256:82b0783b726fcd318e2c977dcdddca76515b30044bc7a830cc4fbe717582a6d0 \
|
||||
--hash=sha256:da71dc87dc129ac9cffdc65e5477e90365ab9dbae45c744014ec1d06303dde40
|
||||
weasyprint==68.1 \
|
||||
--hash=sha256:4dc3ba63c68bbbce3e9617cb2226251c372f5ee90a8a484503b1c099da9cf5be \
|
||||
--hash=sha256:d3b752049b453a5c95edb27ce78d69e9319af5a34f257fa0f4c738c701b4184e
|
||||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# -r src/backend/requirements.in
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ asgiref==3.11.1 \
|
|||
# -c src/backend/requirements-3.14.txt
|
||||
# -c src/backend/requirements.txt
|
||||
# django
|
||||
build==1.4.0 \
|
||||
--hash=sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596 \
|
||||
--hash=sha256:f1b91b925aa322be454f8330c6fb48b465da993d1e7e7e6fa35027ec49f3c936
|
||||
build==1.4.2 \
|
||||
--hash=sha256:35b14e1ee329c186d3f08466003521ed7685ec15ecffc07e68d706090bf161d1 \
|
||||
--hash=sha256:7a4d8651ea877cb2a89458b1b198f2e69f536c95e89129dbf5d448045d60db88
|
||||
# via pip-tools
|
||||
certifi==2026.2.25 \
|
||||
--hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \
|
||||
|
|
@ -251,113 +251,113 @@ click==8.3.1 \
|
|||
--hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \
|
||||
--hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6
|
||||
# via pip-tools
|
||||
coverage[toml]==7.13.4 \
|
||||
--hash=sha256:01d4cbc3c283a17fc1e42d614a119f7f438eabb593391283adca8dc86eff1246 \
|
||||
--hash=sha256:02231499b08dabbe2b96612993e5fc34217cdae907a51b906ac7fca8027a4459 \
|
||||
--hash=sha256:0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129 \
|
||||
--hash=sha256:0e086334e8537ddd17e5f16a344777c1ab8194986ec533711cbe6c41cde841b6 \
|
||||
--hash=sha256:0fc31c787a84f8cd6027eba44010517020e0d18487064cd3d8968941856d1415 \
|
||||
--hash=sha256:14375934243ee05f56c45393fe2ce81fe5cc503c07cee2bdf1725fb8bef3ffaf \
|
||||
--hash=sha256:1731dc33dc276dafc410a885cbf5992f1ff171393e48a21453b78727d090de80 \
|
||||
--hash=sha256:19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11 \
|
||||
--hash=sha256:1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0 \
|
||||
--hash=sha256:1d4be36a5114c499f9f1f9195e95ebf979460dbe2d88e6816ea202010ba1c34b \
|
||||
--hash=sha256:200dea7d1e8095cc6e98cdabe3fd1d21ab17d3cee6dab00cadbb2fe35d9c15b9 \
|
||||
--hash=sha256:23e3f687cf945070d1c90f85db66d11e3025665d8dafa831301a0e0038f3db9b \
|
||||
--hash=sha256:2421d591f8ca05b308cf0092807308b2facbefe54af7c02ac22548b88b95c98f \
|
||||
--hash=sha256:245e37f664d89861cf2329c9afa2c1fe9e6d4e1a09d872c947e70718aeeac505 \
|
||||
--hash=sha256:25381386e80ae727608e662474db537d4df1ecd42379b5ba33c84633a2b36d47 \
|
||||
--hash=sha256:25a41c3104d08edb094d9db0d905ca54d0cd41c928bb6be3c4c799a54753af55 \
|
||||
--hash=sha256:296f8b0af861d3970c2a4d8c91d48eb4dd4771bcef9baedec6a9b515d7de3def \
|
||||
--hash=sha256:29e3220258d682b6226a9b0925bc563ed9a1ebcff3cad30f043eceea7eaf2689 \
|
||||
--hash=sha256:2a09cfa6a5862bc2fc6ca7c3def5b2926194a56b8ab78ffcf617d28911123012 \
|
||||
--hash=sha256:2b0f6ccf3dbe577170bebfce1318707d0e8c3650003cb4b3a9dd744575daa8b5 \
|
||||
--hash=sha256:2c048ea43875fbf8b45d476ad79f179809c590ec7b79e2035c662e7afa3192e3 \
|
||||
--hash=sha256:2cb0f1e000ebc419632bbe04366a8990b6e32c4e0b51543a6484ffe15eaeda95 \
|
||||
--hash=sha256:2fa8d5f8de70688a28240de9e139fa16b153cc3cbb01c5f16d88d6505ebdadf9 \
|
||||
--hash=sha256:300deaee342f90696ed186e3a00c71b5b3d27bffe9e827677954f4ee56969601 \
|
||||
--hash=sha256:30b8d0512f2dc8c8747557e8fb459d6176a2c9e5731e2b74d311c03b78451997 \
|
||||
--hash=sha256:33901f604424145c6e9c2398684b92e176c0b12df77d52db81c20abd48c3794c \
|
||||
--hash=sha256:3599eb3992d814d23b35c536c28df1a882caa950f8f507cef23d1cbf334995ac \
|
||||
--hash=sha256:391ee8f19bef69210978363ca930f7328081c6a0152f1166c91f0b5fdd2a773c \
|
||||
--hash=sha256:3998e5a32e62fdf410c0dbd3115df86297995d6e3429af80b8798aad894ca7aa \
|
||||
--hash=sha256:3c06f0f1337c667b971ca2f975523347e63ec5e500b9aa5882d91931cd3ef750 \
|
||||
--hash=sha256:40aa8808140e55dc022b15d8aa7f651b6b3d68b365ea0398f1441e0b04d859c3 \
|
||||
--hash=sha256:40d74da8e6c4b9ac18b15331c4b5ebc35a17069410cad462ad4f40dcd2d50c0d \
|
||||
--hash=sha256:4223b4230a376138939a9173f1bdd6521994f2aff8047fae100d6d94d50c5a12 \
|
||||
--hash=sha256:48685fee12c2eb3b27c62f2658e7ea21e9c3239cba5a8a242801a0a3f6a8c62a \
|
||||
--hash=sha256:4c7d3cc01e7350f2f0f6f7036caaf5673fb56b6998889ccfe9e1c1fe75a9c932 \
|
||||
--hash=sha256:4e83efc079eb39480e6346a15a1bcb3e9b04759c5202d157e1dd4303cd619356 \
|
||||
--hash=sha256:4fc7fa81bbaf5a02801b65346c8b3e657f1d93763e58c0abdf7c992addd81a92 \
|
||||
--hash=sha256:53d133df809c743eb8bce33b24bcababb371f4441340578cd406e084d94a6148 \
|
||||
--hash=sha256:590c0ed4bf8e85f745e6b805b2e1c457b2e33d5255dd9729743165253bc9ad39 \
|
||||
--hash=sha256:5b856a8ccf749480024ff3bd7310adaef57bf31fd17e1bfc404b7940b6986634 \
|
||||
--hash=sha256:65dfcbe305c3dfe658492df2d85259e0d79ead4177f9ae724b6fb245198f55d6 \
|
||||
--hash=sha256:6f01afcff62bf9a08fb32b2c1d6e924236c0383c02c790732b6537269e466a72 \
|
||||
--hash=sha256:6fdef321fdfbb30a197efa02d48fcd9981f0d8ad2ae8903ac318adc653f5df98 \
|
||||
--hash=sha256:71ca20079dd8f27fcf808817e281e90220475cd75115162218d0e27549f95fef \
|
||||
--hash=sha256:725d985c5ab621268b2edb8e50dfe57633dc69bda071abc470fed55a14935fd3 \
|
||||
--hash=sha256:75eab1ebe4f2f64d9509b984f9314d4aa788540368218b858dad56dc8f3e5eb9 \
|
||||
--hash=sha256:75fcd519f2a5765db3f0e391eb3b7d150cce1a771bf4c9f861aeab86c767a3c0 \
|
||||
--hash=sha256:76451d1978b95ba6507a039090ba076105c87cc76fc3efd5d35d72093964d49a \
|
||||
--hash=sha256:784fc3cf8be001197b652d51d3fd259b1e2262888693a4636e18879f613a62a9 \
|
||||
--hash=sha256:78cdf0d578b15148b009ccf18c686aa4f719d887e76e6b40c38ffb61d264a552 \
|
||||
--hash=sha256:79be69cf7f3bf9b0deeeb062eab7ac7f36cd4cc4c4dd694bd28921ba4d8596cc \
|
||||
--hash=sha256:79e73a76b854d9c6088fe5d8b2ebe745f8681c55f7397c3c0a016192d681045f \
|
||||
--hash=sha256:7b322db1284a2ed3aa28ffd8ebe3db91c929b7a333c0820abec3d838ef5b3525 \
|
||||
--hash=sha256:7d41eead3cc673cbd38a4417deb7fd0b4ca26954ff7dc6078e33f6ff97bed940 \
|
||||
--hash=sha256:7eda778067ad7ffccd23ecffce537dface96212576a07924cbf0d8799d2ded5a \
|
||||
--hash=sha256:7f57b33491e281e962021de110b451ab8a24182589be17e12a22c79047935e23 \
|
||||
--hash=sha256:8041b6c5bfdc03257666e9881d33b1abc88daccaf73f7b6340fb7946655cd10f \
|
||||
--hash=sha256:8248977c2e33aecb2ced42fef99f2d319e9904a36e55a8a68b69207fb7e43edc \
|
||||
--hash=sha256:845f352911777a8e722bfce168958214951e07e47e5d5d9744109fa5fe77f79b \
|
||||
--hash=sha256:85480adfb35ffc32d40918aad81b89c69c9cc5661a9b8a81476d3e645321a056 \
|
||||
--hash=sha256:8e264226ec98e01a8e1054314af91ee6cde0eacac4f465cc93b03dbe0bce2fd7 \
|
||||
--hash=sha256:8e798c266c378da2bd819b0677df41ab46d78065fb2a399558f3f6cae78b2fbb \
|
||||
--hash=sha256:9181a3ccead280b828fae232df12b16652702b49d41e99d657f46cc7b1f6ec7a \
|
||||
--hash=sha256:9351229c8c8407645840edcc277f4a2d44814d1bc34a2128c11c2a031d45a5dd \
|
||||
--hash=sha256:93550784d9281e374fb5a12bf1324cc8a963fd63b2d2f223503ef0fd4aa339ea \
|
||||
--hash=sha256:9401ebc7ef522f01d01d45532c68c5ac40fb27113019b6b7d8b208f6e9baa126 \
|
||||
--hash=sha256:94eb63f9b363180aff17de3e7c8760c3ba94664ea2695c52f10111244d16a299 \
|
||||
--hash=sha256:9d107aff57a83222ddbd8d9ee705ede2af2cc926608b57abed8ef96b50b7e8f9 \
|
||||
--hash=sha256:a32ebc02a1805adf637fc8dec324b5cdacd2e493515424f70ee33799573d661b \
|
||||
--hash=sha256:a3aa4e7b9e416774b21797365b358a6e827ffadaaca81b69ee02946852449f00 \
|
||||
--hash=sha256:a6f94a7d00eb18f1b6d403c91a88fd58cfc92d4b16080dfdb774afc8294469bf \
|
||||
--hash=sha256:aa3feb8db2e87ff5e6d00d7e1480ae241876286691265657b500886c98f38bda \
|
||||
--hash=sha256:ad27098a189e5838900ce4c2a99f2fe42a0bf0c2093c17c69b45a71579e8d4a2 \
|
||||
--hash=sha256:ae4578f8528569d3cf303fef2ea569c7f4c4059a38c8667ccef15c6e1f118aa5 \
|
||||
--hash=sha256:b1ec7b6b6e93255f952e27ab58fbc68dcc468844b16ecbee881aeb29b6ab4d8d \
|
||||
--hash=sha256:b507778ae8a4c915436ed5c2e05b4a6cecfa70f734e19c22a005152a11c7b6a9 \
|
||||
--hash=sha256:b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9 \
|
||||
--hash=sha256:b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b \
|
||||
--hash=sha256:b7b38448866e83176e28086674fe7368ab8590e4610fb662b44e345b86d63ffa \
|
||||
--hash=sha256:b8eb931ee8e6d8243e253e5ed7336deea6904369d2fd8ae6e43f68abbf167092 \
|
||||
--hash=sha256:bb28c0f2cf2782508a40cec377935829d5fcc3ad9a3681375af4e84eb34b6b58 \
|
||||
--hash=sha256:bd60d4fe2f6fa7dff9223ca1bbc9f05d2b6697bc5961072e5d3b952d46e1b1ea \
|
||||
--hash=sha256:c35eb28c1d085eb7d8c9b3296567a1bebe03ce72962e932431b9a61f28facf26 \
|
||||
--hash=sha256:c4240e7eded42d131a2d2c4dec70374b781b043ddc79a9de4d55ca71f8e98aea \
|
||||
--hash=sha256:caa421e2684e382c5d8973ac55e4f36bed6821a9bad5c953494de960c74595c9 \
|
||||
--hash=sha256:d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053 \
|
||||
--hash=sha256:d65b2d373032411e86960604dc4edac91fdfb5dca539461cf2cbe78327d1e64f \
|
||||
--hash=sha256:dae88bc0fc77edaa65c14be099bd57ee140cf507e6bfdeea7938457ab387efb0 \
|
||||
--hash=sha256:de6defc1c9badbf8b9e67ae90fd00519186d6ab64e5cc5f3d21359c2a9b2c1d3 \
|
||||
--hash=sha256:e101609bcbbfb04605ea1027b10dc3735c094d12d40826a60f897b98b1c30256 \
|
||||
--hash=sha256:e24f9156097ff9dc286f2f913df3a7f63c0e333dcafa3c196f2c18b4175ca09a \
|
||||
--hash=sha256:e2f25215f1a359ab17320b47bcdaca3e6e6356652e8256f2441e4ef972052903 \
|
||||
--hash=sha256:e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91 \
|
||||
--hash=sha256:e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd \
|
||||
--hash=sha256:e856bf6616714c3a9fbc270ab54103f4e685ba236fa98c054e8f87f266c93505 \
|
||||
--hash=sha256:e87f6c587c3f34356c3759f0420693e35e7eb0e2e41e4c011cb6ec6ecbbf1db7 \
|
||||
--hash=sha256:eb30bf180de3f632cd043322dad5751390e5385108b2807368997d1a92a509d0 \
|
||||
--hash=sha256:eb88b316ec33760714a4720feb2816a3a59180fd58c1985012054fa7aebee4c2 \
|
||||
--hash=sha256:eb9078108fbf0bcdde37c3f4779303673c2fa1fe8f7956e68d447d0dd426d38a \
|
||||
--hash=sha256:ecae9737b72408d6a950f7e525f30aca12d4bd8dd95e37342e5beb3a2a8c4f71 \
|
||||
--hash=sha256:ee756f00726693e5ba94d6df2bdfd64d4852d23b09bb0bc700e3b30e6f333985 \
|
||||
--hash=sha256:f4594c67d8a7c89cf922d9df0438c7c7bb022ad506eddb0fdb2863359ff78242 \
|
||||
--hash=sha256:f53d492307962561ac7de4cd1de3e363589b000ab69617c6156a16ba7237998d \
|
||||
--hash=sha256:fb07dc5da7e849e2ad31a5d74e9bece81f30ecf5a42909d0a695f8bd1874d6af \
|
||||
--hash=sha256:fb26a934946a6afe0e326aebe0730cdff393a8bc0bbb65a2f41e30feddca399c \
|
||||
--hash=sha256:fdfc1e28e7c7cdce44985b3043bc13bbd9c747520f94a4d7164af8260b3d91f0
|
||||
coverage[toml]==7.13.5 \
|
||||
--hash=sha256:012d5319e66e9d5a218834642d6c35d265515a62f01157a45bcc036ecf947256 \
|
||||
--hash=sha256:02ca0eed225b2ff301c474aeeeae27d26e2537942aa0f87491d3e147e784a82b \
|
||||
--hash=sha256:03ccc709a17a1de074fb1d11f217342fb0d2b1582ed544f554fc9fc3f07e95f5 \
|
||||
--hash=sha256:0428cbef5783ad91fe240f673cc1f76b25e74bbfe1a13115e4aa30d3f538162d \
|
||||
--hash=sha256:04690832cbea4e4663d9149e05dba142546ca05cb1848816760e7f58285c970a \
|
||||
--hash=sha256:0590e44dd2745c696a778f7bab6aa95256de2cbc8b8cff4f7db8ff09813d6969 \
|
||||
--hash=sha256:0672854dc733c342fa3e957e0605256d2bf5934feeac328da9e0b5449634a642 \
|
||||
--hash=sha256:084b84a8c63e8d6fc7e3931b316a9bcafca1458d753c539db82d31ed20091a87 \
|
||||
--hash=sha256:0b67af5492adb31940ee418a5a655c28e48165da5afab8c7fa6fd72a142f8740 \
|
||||
--hash=sha256:0cd9ed7a8b181775459296e402ca4fb27db1279740a24e93b3b41942ebe4b215 \
|
||||
--hash=sha256:0cef0cdec915d11254a7f549c1170afecce708d30610c6abdded1f74e581666d \
|
||||
--hash=sha256:0e223ce4b4ed47f065bfb123687686512e37629be25cc63728557ae7db261422 \
|
||||
--hash=sha256:0e3c426ffc4cd952f54ee9ffbdd10345709ecc78a3ecfd796a57236bfad0b9b8 \
|
||||
--hash=sha256:0ecf12ecb326fe2c339d93fc131816f3a7367d223db37817208905c89bded911 \
|
||||
--hash=sha256:10a0c37f0b646eaff7cce1874c31d1f1ccb297688d4c747291f4f4c70741cc8b \
|
||||
--hash=sha256:145ede53ccbafb297c1c9287f788d1bc3efd6c900da23bf6931b09eafc931587 \
|
||||
--hash=sha256:1b11eef33edeae9d142f9b4358edb76273b3bfd30bc3df9a4f95d0e49caf94e8 \
|
||||
--hash=sha256:1b88c69c8ef5d4b6fe7dea66d6636056a0f6a7527c440e890cf9259011f5e606 \
|
||||
--hash=sha256:258354455f4e86e3e9d0d17571d522e13b4e1e19bf0f8596bcf9476d61e7d8a9 \
|
||||
--hash=sha256:259b69bb83ad9894c4b25be2528139eecba9a82646ebdda2d9db1ba28424a6bf \
|
||||
--hash=sha256:2aa055ae1857258f9e0045be26a6d62bdb47a72448b62d7b55f4820f361a2633 \
|
||||
--hash=sha256:2d3807015f138ffea1ed9afeeb8624fd781703f2858b62a8dd8da5a0994c57b6 \
|
||||
--hash=sha256:301e3b7dfefecaca37c9f1aa6f0049b7d4ab8dd933742b607765d757aca77d43 \
|
||||
--hash=sha256:32ca0c0114c9834a43f045a87dcebd69d108d8ffb666957ea65aa132f50332e2 \
|
||||
--hash=sha256:34b02417cf070e173989b3db962f7ed56d2f644307b2cf9d5a0f258e13084a61 \
|
||||
--hash=sha256:356e76b46783a98c2a2fe81ec79df4883a1e62895ea952968fb253c114e7f930 \
|
||||
--hash=sha256:35a31f2b1578185fbe6aa2e74cea1b1d0bbf4c552774247d9160d29b80ed56cc \
|
||||
--hash=sha256:380e8e9084d8eb38db3a9176a1a4f3c0082c3806fa0dc882d1d87abc3c789247 \
|
||||
--hash=sha256:3ad050321264c49c2fa67bb599100456fc51d004b82534f379d16445da40fb75 \
|
||||
--hash=sha256:3e1bb5f6c78feeb1be3475789b14a0f0a5b47d505bfc7267126ccbd50289999e \
|
||||
--hash=sha256:3f4818d065964db3c1c66dc0fbdac5ac692ecbc875555e13374fdbe7eedb4376 \
|
||||
--hash=sha256:460cf0114c5016fa841214ff5564aa4864f11948da9440bc97e21ad1f4ba1e01 \
|
||||
--hash=sha256:48c39bc4a04d983a54a705a6389512883d4a3b9862991b3617d547940e9f52b1 \
|
||||
--hash=sha256:4b59148601efcd2bac8c4dbf1f0ad6391693ccf7a74b8205781751637076aee3 \
|
||||
--hash=sha256:4d2afbc5cc54d286bfb54541aa50b64cdb07a718227168c87b9e2fb8f25e1743 \
|
||||
--hash=sha256:505d7083c8b0c87a8fa8c07370c285847c1f77739b22e299ad75a6af6c32c5c9 \
|
||||
--hash=sha256:52f444e86475992506b32d4e5ca55c24fc88d73bcbda0e9745095b28ef4dc0cf \
|
||||
--hash=sha256:5b13955d31d1633cf9376908089b7cebe7d15ddad7aeaabcbe969a595a97e95e \
|
||||
--hash=sha256:5ec4af212df513e399cf11610cc27063f1586419e814755ab362e50a85ea69c1 \
|
||||
--hash=sha256:60365289c3741e4db327e7baff2a4aaacf22f788e80fa4683393891b70a89fbd \
|
||||
--hash=sha256:631efb83f01569670a5e866ceb80fe483e7c159fac6f167e6571522636104a0b \
|
||||
--hash=sha256:6697e29b93707167687543480a40f0db8f356e86d9f67ddf2e37e2dfd91a9dab \
|
||||
--hash=sha256:66a80c616f80181f4d643b0f9e709d97bcea413ecd9631e1dedc7401c8e6695d \
|
||||
--hash=sha256:67e9bc5449801fad0e5dff329499fb090ba4c5800b86805c80617b4e29809b2a \
|
||||
--hash=sha256:68a4953be99b17ac3c23b6efbc8a38330d99680c9458927491d18700ef23ded0 \
|
||||
--hash=sha256:6c36ddb64ed9d7e496028d1d00dfec3e428e0aabf4006583bb1839958d280510 \
|
||||
--hash=sha256:6e3370441f4513c6252bf042b9c36d22491142385049243253c7e48398a15a9f \
|
||||
--hash=sha256:7034b5c56a58ae5e85f23949d52c14aca2cfc6848a31764995b7de88f13a1ea0 \
|
||||
--hash=sha256:704de6328e3d612a8f6c07000a878ff38181ec3263d5a11da1db294fa6a9bdf8 \
|
||||
--hash=sha256:7132bed4bd7b836200c591410ae7d97bf7ae8be6fc87d160b2bd881df929e7bf \
|
||||
--hash=sha256:7300c8a6d13335b29bb76d7651c66af6bd8658517c43499f110ddc6717bfc209 \
|
||||
--hash=sha256:750db93a81e3e5a9831b534be7b1229df848b2e125a604fe6651e48aa070e5f9 \
|
||||
--hash=sha256:777c4d1eff1b67876139d24288aaf1817f6c03d6bae9c5cc8d27b83bcfe38fe3 \
|
||||
--hash=sha256:78e696e1cc714e57e8b25760b33a8b1026b7048d270140d25dafe1b0a1ee05a3 \
|
||||
--hash=sha256:79060214983769c7ba3f0cee10b54c97609dca4d478fa1aa32b914480fd5738d \
|
||||
--hash=sha256:7c8d4bc913dd70b93488d6c496c77f3aff5ea99a07e36a18f865bca55adef8bd \
|
||||
--hash=sha256:7f2c47b36fe7709a6e83bfadf4eefb90bd25fbe4014d715224c4316f808e59a2 \
|
||||
--hash=sha256:800bc829053c80d240a687ceeb927a94fd108bbdc68dfbe505d0d75ab578a882 \
|
||||
--hash=sha256:843ea8643cf967d1ac7e8ecd4bb00c99135adf4816c0c0593fdcc47b597fcf09 \
|
||||
--hash=sha256:8769751c10f339021e2638cd354e13adeac54004d1941119b2c96fe5276d45ea \
|
||||
--hash=sha256:8dd02af98971bdb956363e4827d34425cb3df19ee550ef92855b0acb9c7ce51c \
|
||||
--hash=sha256:8fdf453a942c3e4d99bd80088141c4c6960bb232c409d9c3558e2dbaa3998562 \
|
||||
--hash=sha256:941617e518602e2d64942c88ec8499f7fbd49d3f6c4327d3a71d43a1973032f3 \
|
||||
--hash=sha256:972a9cd27894afe4bc2b1480107054e062df08e671df7c2f18c205e805ccd806 \
|
||||
--hash=sha256:9adb6688e3b53adffefd4a52d72cbd8b02602bfb8f74dcd862337182fd4d1a4e \
|
||||
--hash=sha256:9b74db26dfea4f4e50d48a4602207cd1e78be33182bc9cbf22da94f332f99878 \
|
||||
--hash=sha256:9bb2a28101a443669a423b665939381084412b81c3f8c0fcfbac57f4e30b5b8e \
|
||||
--hash=sha256:9d44d7aa963820b1b971dbecd90bfe5fe8f81cff79787eb6cca15750bd2f79b9 \
|
||||
--hash=sha256:9dacc2ad679b292709e0f5fc1ac74a6d4d5562e424058962c7bb0c658ad25e45 \
|
||||
--hash=sha256:9ddb4f4a5479f2539644be484da179b653273bca1a323947d48ab107b3ed1f29 \
|
||||
--hash=sha256:a1a6d79a14e1ec1832cabc833898636ad5f3754a678ef8bb4908515208bf84f4 \
|
||||
--hash=sha256:a698e363641b98843c517817db75373c83254781426e94ada3197cabbc2c919c \
|
||||
--hash=sha256:ad14385487393e386e2ea988b09d62dd42c397662ac2dabc3832d71253eee479 \
|
||||
--hash=sha256:ad146744ca4fd09b50c482650e3c1b1f4dfa1d4792e0a04a369c7f23336f0400 \
|
||||
--hash=sha256:b5db73ba3c41c7008037fa731ad5459fc3944cb7452fc0aa9f822ad3533c583c \
|
||||
--hash=sha256:bd3a2fbc1c6cccb3c5106140d87cc6a8715110373ef42b63cf5aea29df8c217a \
|
||||
--hash=sha256:bdba0a6b8812e8c7df002d908a9a2ea3c36e92611b5708633c50869e6d922fdf \
|
||||
--hash=sha256:be3d4bbad9d4b037791794ddeedd7d64a56f5933a2c1373e18e9e568b9141686 \
|
||||
--hash=sha256:bf69236a9a81bdca3bff53796237aab096cdbf8d78a66ad61e992d9dac7eb2de \
|
||||
--hash=sha256:bff95879c33ec8da99fc9b6fe345ddb5be6414b41d6d1ad1c8f188d26f36e028 \
|
||||
--hash=sha256:c555b48be1853fe3997c11c4bd521cdd9a9612352de01fa4508f16ec341e6fe0 \
|
||||
--hash=sha256:c81f6515c4c40141f83f502b07bbfa5c240ba25bbe73da7b33f1e5b6120ff179 \
|
||||
--hash=sha256:c9136ff29c3a91e25b1d1552b5308e53a1e0653a23e53b6366d7c2dcbbaf8a16 \
|
||||
--hash=sha256:ce1998c0483007608c8382f4ff50164bfc5bd07a2246dd272aa4043b75e61e85 \
|
||||
--hash=sha256:cec2d83125531bd153175354055cdb7a09987af08a9430bd173c937c6d0fba2a \
|
||||
--hash=sha256:cff784eef7f0b8f6cb28804fbddcfa99f89efe4cc35fb5627e3ac58f91ed3ac0 \
|
||||
--hash=sha256:d2c87e0c473a10bffe991502eac389220533024c8082ec1ce849f4218dded810 \
|
||||
--hash=sha256:d7cfad2d6d81dd298ab6b89fe72c3b7b05ec7544bdda3b707ddaecff8d25c161 \
|
||||
--hash=sha256:d8a7a2049c14f413163e2bdabd37e41179b1d1ccb10ffc6ccc4b7a718429c607 \
|
||||
--hash=sha256:da305e9937617ee95c2e39d8ff9f040e0487cbf1ac174f777ed5eddd7a7c1f26 \
|
||||
--hash=sha256:da86cdcf10d2519e10cabb8ac2de03da1bcb6e4853790b7fbd48523332e3a819 \
|
||||
--hash=sha256:dc022073d063b25a402454e5712ef9e007113e3a676b96c5f29b2bda29352f40 \
|
||||
--hash=sha256:e0723d2c96324561b9aa76fb982406e11d93cdb388a7a7da2b16e04719cf7ca5 \
|
||||
--hash=sha256:e092b9499de38ae0fbfbc603a74660eb6ff3e869e507b50d85a13b6db9863e15 \
|
||||
--hash=sha256:e0b216a19534b2427cc201a26c25da4a48633f29a487c61258643e89d28200c0 \
|
||||
--hash=sha256:e1c85e0b6c05c592ea6d8768a66a254bfb3874b53774b12d4c89c481eb78cb90 \
|
||||
--hash=sha256:e301d30dd7e95ae068671d746ba8c34e945a82682e62918e41b2679acd2051a0 \
|
||||
--hash=sha256:e808af52a0513762df4d945ea164a24b37f2f518cbe97e03deaa0ee66139b4d6 \
|
||||
--hash=sha256:eb07647a5738b89baab047f14edd18ded523de60f3b30e75c2acc826f79c839a \
|
||||
--hash=sha256:eb7fdf1ef130660e7415e0253a01a7d5a88c9c4d158bcf75cbbd922fd65a5b58 \
|
||||
--hash=sha256:ec10e2a42b41c923c2209b846126c6582db5e43a33157e9870ba9fb70dc7854b \
|
||||
--hash=sha256:ee2aa19e03161671ec964004fb74b2257805d9710bf14a5c704558b9d8dbaf17 \
|
||||
--hash=sha256:f08fd75c50a760c7eb068ae823777268daaf16a80b918fa58eea888f8e3919f5 \
|
||||
--hash=sha256:f4cd16206ad171cbc2470dbea9103cf9a7607d5fe8c242fdf1edf36174020664 \
|
||||
--hash=sha256:f70c9ab2595c56f81a89620e22899eea8b212a4041bd728ac6f4a28bf5d3ddd0 \
|
||||
--hash=sha256:fbabfaceaeb587e16f7008f7795cd80d20ec548dc7f94fbb0d4ec2e038ce563f
|
||||
# via -r src/backend/requirements-dev.in
|
||||
cryptography==46.0.6 \
|
||||
--hash=sha256:02fad249cb0e090b574e30b276a3da6a149e04ee2f049725b1f69e7b8351ec70 \
|
||||
|
|
@ -430,20 +430,20 @@ django==5.2.12 \
|
|||
django-querycount==0.8.3 \
|
||||
--hash=sha256:0782484e8a1bd29498fa0195a67106e47cdcc98fafe80cebb1991964077cb694
|
||||
# via -r src/backend/requirements-dev.in
|
||||
django-silk==5.4.3 \
|
||||
--hash=sha256:bedb17c8fd9c029a7746cb947864f5c9ea943ae33d6a9581e60f67c45e4490ad \
|
||||
--hash=sha256:f7920ae91a34716654296140b2cbf449e9798237a0c6eb7cf2cd79c2cfb39321
|
||||
django-silk==5.5.0 \
|
||||
--hash=sha256:41fcabe65d59d31ccdb69daeb3c3e6d30879ab2c00b0875b111fda0f69aec065 \
|
||||
--hash=sha256:82b5a690d623935be916dd145e2f605a4ac9454d54e03df6a7ffcf38333c8444
|
||||
# via -r src/backend/requirements-dev.in
|
||||
django-slowtests==1.1.1 \
|
||||
--hash=sha256:3c6936d420c9df444ac03625b41d97de043c662bbde61fbcd33e4cd407d0c247
|
||||
# via -r src/backend/requirements-dev.in
|
||||
django-stubs==5.2.9 \
|
||||
--hash=sha256:2317a7130afdaa76f6ff7f623650d7f3bf1b6c86a60f95840e14e6ec6de1a7cd \
|
||||
--hash=sha256:c192257120b08785cfe6f2f1c91f1797aceae8e9daa689c336e52c91e8f6a493
|
||||
django-stubs==6.0.1 \
|
||||
--hash=sha256:d885044bd0876610f3eb969d6b5ed22f386002a879fdcb369cd8efa0502dbbce \
|
||||
--hash=sha256:e1ca63634221b57a55e16562b9b6d1849aeee2cabfd0fc026084dbe8aa893366
|
||||
# via -r src/backend/requirements-dev.in
|
||||
django-stubs-ext==5.2.9 \
|
||||
--hash=sha256:230c51575551b0165be40177f0f6805f1e3ebf799b835c85f5d64c371ca6cf71 \
|
||||
--hash=sha256:6db4054d1580657b979b7d391474719f1a978773e66c7070a5e246cd445a25a9
|
||||
django-stubs-ext==6.0.1 \
|
||||
--hash=sha256:17415759b9a3f4b4da7998ac3b08c7dc5137f9a019490b918aece1a8a4c2ade4 \
|
||||
--hash=sha256:633b280f89c0cbb7e3ce2f2f842e0acc43d8091378e75f84921d6be675d052dc
|
||||
# via django-stubs
|
||||
django-test-migrations==1.5.0 \
|
||||
--hash=sha256:1cbff04b1e82c5564a6f635284907b381cc11a2ff883adff46776d9126824f07 \
|
||||
|
|
@ -453,9 +453,9 @@ django-types==0.23.0 \
|
|||
--hash=sha256:0727b13ae810c4b1f14eeac9872834ac928c99dc76584ea7c23afc4461e049dd \
|
||||
--hash=sha256:f97fb746166fb15a5f40e470a1fd7a58226349aac9e0a9cb8ae81deb14d94fd0
|
||||
# via -r src/backend/requirements-dev.in
|
||||
filelock==3.25.0 \
|
||||
--hash=sha256:5ccf8069f7948f494968fc0713c10e5c182a9c9d9eef3a636307a20c2490f047 \
|
||||
--hash=sha256:8f00faf3abf9dc730a1ffe9c354ae5c04e079ab7d3a683b7c32da5dd05f26af3
|
||||
filelock==3.25.2 \
|
||||
--hash=sha256:b64ece2b38f4ca29dd3e810287aa8c48182bbecd1ae6e9ae126c9b35f1382694 \
|
||||
--hash=sha256:ca8afb0da15f229774c9ad1b455ed96e85a81373065fb10446672f64444ddf70
|
||||
# via
|
||||
# python-discovery
|
||||
# virtualenv
|
||||
|
|
@ -463,9 +463,9 @@ gprof2dot==2025.4.14 \
|
|||
--hash=sha256:0742e4c0b4409a5e8777e739388a11e1ed3750be86895655312ea7c20bd0090e \
|
||||
--hash=sha256:35743e2d2ca027bf48fa7cba37021aaf4a27beeae1ae8e05a50b55f1f921a6ce
|
||||
# via django-silk
|
||||
identify==2.6.17 \
|
||||
--hash=sha256:be5f8412d5ed4b20f2bd41a65f920990bdccaa6a4a18a08f1eefdcd0bdd885f0 \
|
||||
--hash=sha256:f816b0b596b204c9fdf076ded172322f2723cf958d02f9c3587504834c8ff04d
|
||||
identify==2.6.18 \
|
||||
--hash=sha256:873ac56a5e3fd63e7438a7ecbc4d91aca692eb3fefa4534db2b7913f3fc352fd \
|
||||
--hash=sha256:8db9d3c8ea9079db92cafb0ebf97abdc09d52e97f4dcf773a2e694048b7cd737
|
||||
# via pre-commit
|
||||
idna==3.11 \
|
||||
--hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \
|
||||
|
|
@ -538,9 +538,9 @@ pycparser==3.0 \
|
|||
# -c src/backend/requirements-3.14.txt
|
||||
# -c src/backend/requirements.txt
|
||||
# cffi
|
||||
pygments==2.19.2 \
|
||||
--hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \
|
||||
--hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b
|
||||
pygments==2.20.0 \
|
||||
--hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \
|
||||
--hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176
|
||||
# via
|
||||
# pytest
|
||||
# rich
|
||||
|
|
@ -578,9 +578,9 @@ pytest-django==4.12.0 \
|
|||
--hash=sha256:3ff300c49f8350ba2953b90297d23bf5f589db69545f56f1ec5f8cff5da83e85 \
|
||||
--hash=sha256:df94ec819a83c8979c8f6de13d9cdfbe76e8c21d39473cfe2b40c9fc9be3c758
|
||||
# via -r src/backend/requirements-dev.in
|
||||
python-discovery==1.1.0 \
|
||||
--hash=sha256:447941ba1aed8cc2ab7ee3cb91be5fc137c5bdbb05b7e6ea62fbdcb66e50b268 \
|
||||
--hash=sha256:a162893b8809727f54594a99ad2179d2ede4bf953e12d4c7abc3cc9cdbd1437b
|
||||
python-discovery==1.2.0 \
|
||||
--hash=sha256:1e108f1bbe2ed0ef089823d28805d5ad32be8e734b86a5f212bf89b71c266e4a \
|
||||
--hash=sha256:7d33e350704818b09e3da2bd419d37e21e7c30db6e0977bb438916e06b41b5b1
|
||||
# via virtualenv
|
||||
pyyaml==6.0.3 \
|
||||
--hash=sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c \
|
||||
|
|
@ -735,9 +735,9 @@ urllib3==2.6.3 \
|
|||
# -c src/backend/requirements-3.14.txt
|
||||
# -c src/backend/requirements.txt
|
||||
# requests
|
||||
virtualenv==21.1.0 \
|
||||
--hash=sha256:164f5e14c5587d170cf98e60378eb91ea35bf037be313811905d3a24ea33cc07 \
|
||||
--hash=sha256:1990a0188c8f16b6b9cf65c9183049007375b26aad415514d377ccacf1e4fb44
|
||||
virtualenv==21.2.0 \
|
||||
--hash=sha256:1720dc3a62ef5b443092e3f499228599045d7fea4c79199770499df8becf9098 \
|
||||
--hash=sha256:1bd755b504931164a5a496d217c014d098426cddc79363ad66ac78125f9d908f
|
||||
# via pre-commit
|
||||
wheel==0.46.3 \
|
||||
--hash=sha256:4b399d56c9d9338230118d705d9737a2a468ccca63d5e813e2a4fc7815d8bc4d \
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ asgiref==3.11.1 \
|
|||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# django
|
||||
build==1.4.0 \
|
||||
--hash=sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596 \
|
||||
--hash=sha256:f1b91b925aa322be454f8330c6fb48b465da993d1e7e7e6fa35027ec49f3c936
|
||||
build==1.4.2 \
|
||||
--hash=sha256:35b14e1ee329c186d3f08466003521ed7685ec15ecffc07e68d706090bf161d1 \
|
||||
--hash=sha256:7a4d8651ea877cb2a89458b1b198f2e69f536c95e89129dbf5d448045d60db88
|
||||
# via pip-tools
|
||||
certifi==2026.2.25 \
|
||||
--hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \
|
||||
|
|
@ -528,9 +528,9 @@ pycparser==3.0 \
|
|||
# via
|
||||
# -c src/backend/requirements.txt
|
||||
# cffi
|
||||
pygments==2.19.2 \
|
||||
--hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \
|
||||
--hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b
|
||||
pygments==2.20.0 \
|
||||
--hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \
|
||||
--hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176
|
||||
# via
|
||||
# pytest
|
||||
# rich
|
||||
|
|
@ -677,73 +677,74 @@ sqlparse==0.5.5 \
|
|||
# -c src/backend/requirements.txt
|
||||
# django
|
||||
# django-silk
|
||||
tomli==2.4.0 \
|
||||
--hash=sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729 \
|
||||
--hash=sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b \
|
||||
--hash=sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d \
|
||||
--hash=sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df \
|
||||
--hash=sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576 \
|
||||
--hash=sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d \
|
||||
--hash=sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1 \
|
||||
--hash=sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a \
|
||||
--hash=sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e \
|
||||
--hash=sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc \
|
||||
--hash=sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702 \
|
||||
--hash=sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6 \
|
||||
--hash=sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd \
|
||||
--hash=sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4 \
|
||||
--hash=sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776 \
|
||||
--hash=sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a \
|
||||
--hash=sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66 \
|
||||
--hash=sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87 \
|
||||
--hash=sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2 \
|
||||
--hash=sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f \
|
||||
--hash=sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475 \
|
||||
--hash=sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f \
|
||||
--hash=sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95 \
|
||||
--hash=sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9 \
|
||||
--hash=sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3 \
|
||||
--hash=sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9 \
|
||||
--hash=sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76 \
|
||||
--hash=sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da \
|
||||
--hash=sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8 \
|
||||
--hash=sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51 \
|
||||
--hash=sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86 \
|
||||
--hash=sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8 \
|
||||
--hash=sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0 \
|
||||
--hash=sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b \
|
||||
--hash=sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1 \
|
||||
--hash=sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e \
|
||||
--hash=sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d \
|
||||
--hash=sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c \
|
||||
--hash=sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867 \
|
||||
--hash=sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a \
|
||||
--hash=sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c \
|
||||
--hash=sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0 \
|
||||
--hash=sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4 \
|
||||
--hash=sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614 \
|
||||
--hash=sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132 \
|
||||
--hash=sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa \
|
||||
--hash=sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087
|
||||
tomli==2.4.1 \
|
||||
--hash=sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853 \
|
||||
--hash=sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe \
|
||||
--hash=sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5 \
|
||||
--hash=sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d \
|
||||
--hash=sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd \
|
||||
--hash=sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26 \
|
||||
--hash=sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54 \
|
||||
--hash=sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6 \
|
||||
--hash=sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c \
|
||||
--hash=sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a \
|
||||
--hash=sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd \
|
||||
--hash=sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f \
|
||||
--hash=sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5 \
|
||||
--hash=sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9 \
|
||||
--hash=sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662 \
|
||||
--hash=sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9 \
|
||||
--hash=sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1 \
|
||||
--hash=sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585 \
|
||||
--hash=sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e \
|
||||
--hash=sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c \
|
||||
--hash=sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41 \
|
||||
--hash=sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f \
|
||||
--hash=sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085 \
|
||||
--hash=sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15 \
|
||||
--hash=sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7 \
|
||||
--hash=sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c \
|
||||
--hash=sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36 \
|
||||
--hash=sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076 \
|
||||
--hash=sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac \
|
||||
--hash=sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8 \
|
||||
--hash=sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232 \
|
||||
--hash=sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece \
|
||||
--hash=sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a \
|
||||
--hash=sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897 \
|
||||
--hash=sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d \
|
||||
--hash=sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4 \
|
||||
--hash=sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917 \
|
||||
--hash=sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396 \
|
||||
--hash=sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a \
|
||||
--hash=sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc \
|
||||
--hash=sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba \
|
||||
--hash=sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f \
|
||||
--hash=sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257 \
|
||||
--hash=sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30 \
|
||||
--hash=sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf \
|
||||
--hash=sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9 \
|
||||
--hash=sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049
|
||||
# via coverage
|
||||
ty==0.0.24 \
|
||||
--hash=sha256:0c94c25d0500939fd5f8f16ce41cbed5b20528702c1d649bf80300253813f0a2 \
|
||||
--hash=sha256:1ab4f1f61334d533a3fdf5d9772b51b1300ac5da4f3cdb0be9657a3ccb2ce3e7 \
|
||||
--hash=sha256:280a3d31e86d0721947238f17030c33f0911cae851d108ea9f4e3ab12a5ed01f \
|
||||
--hash=sha256:438ecbf1608a9b16dd84502f3f1b23ef2ef32bbd0ab3e0ca5a82f0e0d1cd41ea \
|
||||
--hash=sha256:5674a1146d927ab77ff198a88e0c4505134ced342a0e7d1beb4a076a728b7496 \
|
||||
--hash=sha256:748a60eb6912d1cf27aaab105ffadb6f4d2e458a3fcadfbd3cf26db0d8062eeb \
|
||||
--hash=sha256:7981df5c709c054da4ac5d7c93f8feb8f45e69e829e4461df4d5f0988fe67d04 \
|
||||
--hash=sha256:83013fb3a4764a8f8bcc6ca11ff8bdfd8c5f719fc249241cb2b8916e80778eb1 \
|
||||
--hash=sha256:89cbe7bc7df0fab02dbd8cda79b737df83f1ef7fb573b08c0ee043dc68cffb08 \
|
||||
--hash=sha256:9fe42f6b98207bdaef51f71487d6d087f2cb02555ee3939884d779b2b3cc8bfc \
|
||||
--hash=sha256:a52b7f589c3205512a9c50ba5b2b1e8c0698b72e51b8b9285c90420c06f1cae8 \
|
||||
--hash=sha256:b2860151ad95a00d0f0280b8fef79900d08dcd63276b57e6e5774f2c055979c5 \
|
||||
--hash=sha256:b6d2a3b6d4470c483552a31e9b368c86f154dcc964bccb5406159dc9cd362246 \
|
||||
--hash=sha256:ba44512db5b97c3bbd59d93e11296e8548d0c9a3bdd1280de36d7ff22d351896 \
|
||||
--hash=sha256:db2c5d269bcc9b764850c99f457b5018a79b3ef40ecfbc03344e65effd6cf743 \
|
||||
--hash=sha256:ddeed3098dd92a83964e7aa7b41e509ba3530eb539fc4cd8322ff64a09daf1f5 \
|
||||
--hash=sha256:facbf2c4aaa6985229e08f8f9bf152215eb078212f22b5c2411f35386688ab42
|
||||
ty==0.0.1a21 \
|
||||
--hash=sha256:0efba2e52b58f536f4198ba5c4a36cac2ba67d83ec6f429ebc7704233bcda4c3 \
|
||||
--hash=sha256:1474d883129bb63da3b2380fc7ead824cd3baf6a9551e6aa476ffefc58057af3 \
|
||||
--hash=sha256:1f276ceab23a1410aec09508248c76ae0989c67fb7a0c287e0d4564994295531 \
|
||||
--hash=sha256:218d53e7919e885bd98e9196d9cb952d82178b299aa36da6f7f39333eb7400ed \
|
||||
--hash=sha256:21f708d02b6588323ffdbfdba38830dd0ecfd626db50aa6006b296b5470e52f9 \
|
||||
--hash=sha256:334d2a212ebf42a0e55d57561926af7679fe1e878175e11dcb81ad8df892844e \
|
||||
--hash=sha256:3c3bc66fcae41eff133cfe326dd65d82567a2fb5d4efe2128773b10ec2766819 \
|
||||
--hash=sha256:5dfc73299d441cc6454e36ed0a976877415024143dfca6592dc36f7701424383 \
|
||||
--hash=sha256:7505aeb8bf2a62f00f12cfa496f6c965074d75c8126268776565284c8a12d5dd \
|
||||
--hash=sha256:84243455f295ed850bd53f7089819321807d4e6ee3b1cbff6086137ae0259466 \
|
||||
--hash=sha256:87a200c21e02962e8a27374d9d152582331d57d709672431be58f4f898bf6cad \
|
||||
--hash=sha256:9463cac96b8f1bb5ba740fe1d42cd6bd152b43c5b159b2f07f8fd629bcdded34 \
|
||||
--hash=sha256:a8c769987d00fbc33054ff7e342633f475ea10dc43bc60fb9fb056159d48cb90 \
|
||||
--hash=sha256:ba13d03b9e095216ceb4e4d554a308517f28ab0a6e4dcd07cfe94563e4c2c489 \
|
||||
--hash=sha256:be8f457d7841b7ead2a3f6b65ba668abc172a1150a0f1f6c0958af3725dbb61a \
|
||||
--hash=sha256:cc0880ec344fbdf736b05d8d0da01f0caaaa02409bd9a24b68d18d0127a79b0e \
|
||||
--hash=sha256:e941e9a9d1e54b03eeaf9c3197c26a19cf76009fd5e41e16e5657c1c827bd6d3 \
|
||||
--hash=sha256:ecf41706b803827b0de8717f32a434dad1e67be9f4b8caf403e12013179ea06a
|
||||
# via -r src/backend/requirements-dev.in
|
||||
types-psycopg2==2.9.21.20260223 \
|
||||
--hash=sha256:78ed70de2e56bc6b5c26c8c1da8e9af54e49fdc3c94d1504609f3519e2b84f02 \
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@ django-ical # iCal export for calendar views
|
|||
django-maintenance-mode # Shut down application while reloading etc.
|
||||
django-mailbox # Email scraping
|
||||
django-markdownify # Markdown rendering
|
||||
django-mptt # Modified Preorder Tree Traversal
|
||||
django-markdownify # Markdown rendering
|
||||
django-money # Django app for currency management
|
||||
django-mptt # Modified Preorder Tree Traversal
|
||||
django-redis>=5.0.0 # Redis integration
|
||||
|
|
@ -39,6 +37,7 @@ drf-spectacular # DRF API documentation
|
|||
feedparser # RSS newsfeed parser
|
||||
gunicorn # Gunicorn web server
|
||||
jinja2 # Jinja2 templating engine
|
||||
nh3 # HTML sanitization (replaces bleach)
|
||||
pdf2image # PDF to image conversion
|
||||
pillow # Image manipulation
|
||||
pint # Unit conversion
|
||||
|
|
|
|||
|
|
@ -87,23 +87,23 @@ bcrypt==5.0.0 \
|
|||
--hash=sha256:f8429e1c410b4073944f03bd778a9e066e7fad723564a52ff91841d278dfc822 \
|
||||
--hash=sha256:fc746432b951e92b58317af8e0ca746efe93e66555f1b40888865ef5bf56446b
|
||||
# via paramiko
|
||||
bleach[css]==6.3.0 \
|
||||
--hash=sha256:6f3b91b1c0a02bb9a78b5a454c92506aa0fdf197e1d5e114d2e00c6f64306d22 \
|
||||
--hash=sha256:fe10ec77c93ddf3d13a73b035abaac7a9f5e436513864ccdad516693213c65d6
|
||||
bleach==4.1.0 \
|
||||
--hash=sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da \
|
||||
--hash=sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994
|
||||
# via django-markdownify
|
||||
blessed==1.33.0 \
|
||||
--hash=sha256:1bc8ecac6d139286ea51ec1683433528ce75b0c60db77b7d881112bf9fc85b0f \
|
||||
--hash=sha256:c732a1043042d84f411423a1a7b74643e1dd3a2271bd6e5955682dd4a321b0ef
|
||||
blessed==1.34.0 \
|
||||
--hash=sha256:3d17468c3d47e11ed8d6ca3da1270b8aba8ac8bd0a55a1f8189e4d04f223a1f0 \
|
||||
--hash=sha256:eb403f9ce2efab633bd1e7a05fbb35b979a7b9f213ddc41478dd55dd6999e8bf
|
||||
# via -r src/backend/requirements.in
|
||||
boto3==1.42.72 \
|
||||
--hash=sha256:2b5fdac4f202b2ccb9ed21f8b84229463b15573ea16941c2b1b8db1c69e08b63 \
|
||||
--hash=sha256:932f023ea3b54fd85df453dcfff7d8c5a0f8be144c0ad57568943505c72c1e6a
|
||||
boto3==1.42.76 \
|
||||
--hash=sha256:63c6779c814847016b89ae1b72ed968f8a63d80e589ba337511aa6fc1b59585e \
|
||||
--hash=sha256:aa2b1973eee8973a9475d24bb579b1dee7176595338d4e4f7880b5c6189b8814
|
||||
# via
|
||||
# django-anymail
|
||||
# django-storages
|
||||
botocore==1.42.72 \
|
||||
--hash=sha256:038f34553da68df2ce70edc729f170cc198678daaad43f98649727c59f6404d4 \
|
||||
--hash=sha256:491b75eb41d46cf99cf8d6cab89f2e2c3602ce8e90d738a1da217a5fb6b2b7ef
|
||||
botocore==1.42.76 \
|
||||
--hash=sha256:151e714ae3c32f68ea0b4dc60751401e03f84a87c6cf864ea0ee64aa10eb4607 \
|
||||
--hash=sha256:c553fa0ae29e36a5c407f74da78b78404b81b74b15fb62bf640a3cd9385f0874
|
||||
# via
|
||||
# boto3
|
||||
# s3transfer
|
||||
|
|
@ -585,9 +585,9 @@ django-maintenance-mode==0.22.0 \
|
|||
--hash=sha256:502f04f845d6996e8add321186b3b9236c3702de7cb0ab14952890af6523b9e5 \
|
||||
--hash=sha256:a9cf2ba79c9945bd67f98755a6cfd281869d39b3745bbb5d1f571d058657aa85
|
||||
# via -r src/backend/requirements.in
|
||||
django-markdownify==0.9.6 \
|
||||
--hash=sha256:9863b2bfa6d159ad1423dc93bf0d6eadc6413776de304049aa9fcfa5edd2ce1c \
|
||||
--hash=sha256:edcf47b2026d55a8439049d35c8b54e11066a4856c4fad1060e139cb3d2eee52
|
||||
django-markdownify==0.9.1 \
|
||||
--hash=sha256:06ff2994ff09ce030b50de8c6fc5b89b9c25a66796948aff55370716ca1233af \
|
||||
--hash=sha256:24ba68b8a5996b6ec9632d11a3fd2e7159cb7e6becd3104e0a9372b5a2a148ef
|
||||
# via -r src/backend/requirements.in
|
||||
django-money==3.6.0 \
|
||||
--hash=sha256:94402f2831f2726b94ef2da35b4059441b4c0aedfc47b312472200d4ffdf8d73 \
|
||||
|
|
@ -654,9 +654,9 @@ django-taggit==6.1.0 \
|
|||
django-xforwardedfor-middleware==2.0 \
|
||||
--hash=sha256:16fd1cb27f33a5541b6f3e0b43afb1b7334a76f27a1255b69e14ec5c440f0b24
|
||||
# via -r src/backend/requirements.in
|
||||
djangorestframework==3.17.0 \
|
||||
--hash=sha256:456fd992a33f9e64c9d0f47e85d9787db0efb44f894c1e513315b5e74765bd4c \
|
||||
--hash=sha256:d84fe85f30b7ac6e8c0076ce9ff635e4eaedca5912f8d7d2926ce448c08533ba
|
||||
djangorestframework==3.17.1 \
|
||||
--hash=sha256:a6def5f447fe78ff853bff1d47a3c59bf38f5434b031780b351b0c73a62db1a5 \
|
||||
--hash=sha256:c3c74dd3e83a5a3efc37b3c18d92bd6f86a6791c7b7d4dff62bb068500e76457
|
||||
# via
|
||||
# -r src/backend/requirements.in
|
||||
# djangorestframework-simplejwt
|
||||
|
|
@ -854,9 +854,9 @@ grpcio==1.78.0 \
|
|||
# via
|
||||
# -r src/backend/requirements.in
|
||||
# opentelemetry-exporter-otlp-proto-grpc
|
||||
gunicorn==25.1.0 \
|
||||
--hash=sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616 \
|
||||
--hash=sha256:d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b
|
||||
gunicorn==25.2.0 \
|
||||
--hash=sha256:10bd7adb36d44945d97d0a1fdf9a0fb086ae9c7b39e56b4dece8555a6bf4a09c \
|
||||
--hash=sha256:88f5b444d0055bf298435384af7294f325e2273fd37ba9f9ff7b98e0a1e5dfdc
|
||||
# via -r src/backend/requirements.in
|
||||
icalendar==7.0.3 \
|
||||
--hash=sha256:8c9fea6d3a89671bba8b6938d8565b4d0ec465c6a2796ef0f92790dcb9e627cd \
|
||||
|
|
@ -1145,6 +1145,35 @@ markupsafe==3.0.3 \
|
|||
--hash=sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a \
|
||||
--hash=sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50
|
||||
# via jinja2
|
||||
nh3==0.3.4 \
|
||||
--hash=sha256:07999b998bf89692738f15c0eac76a416382932f855709e0b7488b595c30ec89 \
|
||||
--hash=sha256:0961a27dc2057c38d0364cb05880e1997ae1c80220cbc847db63213720b8f304 \
|
||||
--hash=sha256:0d825722a1e8cbc87d7ca1e47ffb1d2a6cf343ad4c1b8465becf7cadcabcdfd0 \
|
||||
--hash=sha256:18a2e44ccb29cbb45071b8f3f2dab9ebfb41a6516f328f91f1f1fd18196239a4 \
|
||||
--hash=sha256:3390e4333883673a684ce16c1716b481e91782d6f56dec5c85fed9feedb23382 \
|
||||
--hash=sha256:41e46b3499918ab6128b6421677b316e79869d0c140da24069d220a94f4e72d1 \
|
||||
--hash=sha256:43ad4eedee7e049b9069bc015b7b095d320ed6d167ecec111f877de1540656e9 \
|
||||
--hash=sha256:47d749d99ae005ab19517224140b280dd56e77b33afb82f9b600e106d0458003 \
|
||||
--hash=sha256:4aa8b43e68c26b68069a3b6cef09de166d1d7fa140cf8d77e409a46cbf742e44 \
|
||||
--hash=sha256:554cc2bab281758e94d770c3fb0bf2d8be5fb403ef6b2e8841dd7c1615df7a0f \
|
||||
--hash=sha256:72e4e9ca1c4bd41b4a28b0190edc2e21e3f71496acd36a0162858e1a28db3d7e \
|
||||
--hash=sha256:75643c22f5092d8e209f766ee8108c400bc1e44760fc94d2d638eb138d18f853 \
|
||||
--hash=sha256:7cae217f031809321db962cd7e092bda8d4e95a87f78c0226628fa6c2ea8ebc5 \
|
||||
--hash=sha256:80b955d802bf365bd42e09f6c3d64567dce777d20e97968d94b3e9d9e99b265e \
|
||||
--hash=sha256:87dac8d611b4a478400e0821a13b35770e88c266582f065e7249d6a37b0f86e8 \
|
||||
--hash=sha256:883d5a6d6ee8078c4afc8e96e022fe579c4c265775ff6ee21e39b8c542cabab3 \
|
||||
--hash=sha256:8b61058f34c2105d44d2a4d4241bacf603a1ef5c143b08766bbd0cf23830118f \
|
||||
--hash=sha256:8d697e19f2995b337f648204848ac3a528eaafffc39e7ce4ac6b7a2fbe6c84af \
|
||||
--hash=sha256:9337517edb7c10228252cce2898e20fb3d77e32ffaccbb3c66897927d74215a0 \
|
||||
--hash=sha256:96709a379997c1b28c8974146ca660b0dcd3794f4f6d50c1ea549bab39ac6ade \
|
||||
--hash=sha256:c10b1f0c741e257a5cb2978d6bac86e7c784ab20572724b20c6402c2e24bce75 \
|
||||
--hash=sha256:ca90397c8d36c1535bf1988b2bed006597337843a164c7ec269dc8813f37536b \
|
||||
--hash=sha256:d866701affe67a5171b916b5c076e767a74c6a9efb7fb2006eb8d3c5f9a293d5 \
|
||||
--hash=sha256:d8bebcb20ab4b91858385cd98fe58046ec4a624275b45ef9b976475604f45b49 \
|
||||
--hash=sha256:dbe76feaa44e2ef9436f345016012a591550e77818876a8de5c8bc2a248e08df \
|
||||
--hash=sha256:f5f214618ad5eff4f2a6b13a8d4da4d9e7f37c569d90a13fb9f0caaf7d04fe21 \
|
||||
--hash=sha256:f987cb56458323405e8e5ea827e1befcf141ffa0c0ac797d6d02e6b646056d9a
|
||||
# via -r src/backend/requirements.in
|
||||
oauthlib==3.3.1 \
|
||||
--hash=sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9 \
|
||||
--hash=sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1
|
||||
|
|
@ -1282,6 +1311,7 @@ packaging==26.0 \
|
|||
--hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \
|
||||
--hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529
|
||||
# via
|
||||
# bleach
|
||||
# gunicorn
|
||||
# opentelemetry-instrumentation
|
||||
paramiko==4.0.0 \
|
||||
|
|
@ -1702,9 +1732,9 @@ rapidfuzz==3.14.3 \
|
|||
--hash=sha256:fa7c8f26f009f8c673fbfb443792f0cf8cf50c4e18121ff1e285b5e08a94fbdb \
|
||||
--hash=sha256:fce3152f94afcfd12f3dd8cf51e48fa606e3cb56719bccebe3b401f43d0714f9
|
||||
# via -r src/backend/requirements.in
|
||||
redis==7.3.0 \
|
||||
--hash=sha256:4d1b768aafcf41b01022410b3cc4f15a07d9b3d6fe0c66fc967da2c88e551034 \
|
||||
--hash=sha256:9d4fcb002a12a5e3c3fbe005d59c48a2cc231f87fbb2f6b70c2d89bb64fec364
|
||||
redis==7.4.0 \
|
||||
--hash=sha256:64a6ea7bf567ad43c964d2c30d82853f8df927c5c9017766c55a1d1ed95d18ad \
|
||||
--hash=sha256:a9c74a5c893a5ef8455a5adb793a31bb70feb821c86eccb62eebef5a19c429ec
|
||||
# via django-redis
|
||||
referencing==0.37.0 \
|
||||
--hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \
|
||||
|
|
@ -1843,9 +1873,9 @@ s3transfer==0.16.0 \
|
|||
--hash=sha256:18e25d66fed509e3868dc1572b3f427ff947dd2c56f844a5bf09481ad3f3b2fe \
|
||||
--hash=sha256:8e990f13268025792229cd52fa10cb7163744bf56e719e0b9cb925ab79abf920
|
||||
# via boto3
|
||||
sentry-sdk==2.55.0 \
|
||||
--hash=sha256:3774c4d8820720ca4101548131b9c162f4c9426eb7f4d24aca453012a7470f69 \
|
||||
--hash=sha256:97026981cb15699394474a196b88503a393cbc58d182ece0d3abe12b9bd978d4
|
||||
sentry-sdk==2.56.0 \
|
||||
--hash=sha256:5afafb744ceb91d22f4cc650c6bd048ac6af5f7412dcc6c59305a2e36f4dbc02 \
|
||||
--hash=sha256:fdab72030b69625665b2eeb9738bdde748ad254e8073085a0ce95382678e8168
|
||||
# via
|
||||
# -r src/backend/requirements.in
|
||||
# django-q-sentry
|
||||
|
|
@ -1859,7 +1889,9 @@ sgmllib3k==1.0.0 \
|
|||
six==1.17.0 \
|
||||
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
|
||||
--hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81
|
||||
# via python-dateutil
|
||||
# via
|
||||
# bleach
|
||||
# python-dateutil
|
||||
sqlparse==0.5.5 \
|
||||
--hash=sha256:12a08b3bf3eec877c519589833aed092e2444e68240a3577e8e26148acc7b1ba \
|
||||
--hash=sha256:e20d4a9b0b8585fdf63b10d30066c7c94c5d7a7ec47c889a2d83a3caa93ff28e
|
||||
|
|
@ -1874,11 +1906,10 @@ tablib[xls, xlsx, yaml]==3.9.0 \
|
|||
--hash=sha256:1b6abd8edb0f35601e04c6161d79660fdcde4abb4a54f66cc9f9054bd55d5fe2 \
|
||||
--hash=sha256:eda17cd0d4dda614efc0e710227654c60ddbeb1ca92cdcfc5c3bd1fc5f5a6e4a
|
||||
# via -r src/backend/requirements.in
|
||||
tinycss2==1.4.0 \
|
||||
--hash=sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7 \
|
||||
--hash=sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289
|
||||
tinycss2==1.5.1 \
|
||||
--hash=sha256:3415ba0f5839c062696996998176c4a3751d18b7edaaeeb658c9ce21ec150661 \
|
||||
--hash=sha256:d339d2b616ba90ccce58da8495a78f46e55d4d25f9fd71dfd526f07e7d53f957
|
||||
# via
|
||||
# bleach
|
||||
# cssselect2
|
||||
# weasyprint
|
||||
tinyhtml5==2.1.0 \
|
||||
|
|
@ -1926,9 +1957,9 @@ wcwidth==0.6.0 \
|
|||
# via
|
||||
# blessed
|
||||
# prettytable
|
||||
weasyprint==66.0 \
|
||||
--hash=sha256:82b0783b726fcd318e2c977dcdddca76515b30044bc7a830cc4fbe717582a6d0 \
|
||||
--hash=sha256:da71dc87dc129ac9cffdc65e5477e90365ab9dbae45c744014ec1d06303dde40
|
||||
weasyprint==68.1 \
|
||||
--hash=sha256:4dc3ba63c68bbbce3e9617cb2226251c372f5ee90a8a484503b1c099da9cf5be \
|
||||
--hash=sha256:d3b752049b453a5c95edb27ce78d69e9319af5a34f257fa0f4c738c701b4184e
|
||||
# via -r src/backend/requirements.in
|
||||
webencodings==0.5.1 \
|
||||
--hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@ export function usePartFields({
|
|||
duplicatePartInstance?: any;
|
||||
create?: boolean;
|
||||
}): ApiFormFieldSet {
|
||||
const settings = useGlobalSettingsState();
|
||||
|
||||
const globalSettings = useGlobalSettingsState();
|
||||
|
||||
const [virtual, setVirtual] = useState<boolean | undefined>(undefined);
|
||||
|
|
@ -38,8 +36,10 @@ export function usePartFields({
|
|||
revision: {},
|
||||
revision_of: {
|
||||
filters: {
|
||||
is_revision: false,
|
||||
is_template: false
|
||||
is_template: false,
|
||||
assembly: globalSettings.isSet('PART_REVISION_ASSEMBLY_ONLY')
|
||||
? true
|
||||
: undefined
|
||||
}
|
||||
},
|
||||
variant_of: {
|
||||
|
|
@ -155,14 +155,14 @@ export function usePartFields({
|
|||
value: true
|
||||
},
|
||||
copy_bom: {
|
||||
value: settings.isSet('PART_COPY_BOM'),
|
||||
value: globalSettings.isSet('PART_COPY_BOM'),
|
||||
hidden: !duplicatePartInstance?.assembly
|
||||
},
|
||||
copy_notes: {
|
||||
value: true
|
||||
},
|
||||
copy_parameters: {
|
||||
value: settings.isSet('PART_COPY_PARAMETERS')
|
||||
value: globalSettings.isSet('PART_COPY_PARAMETERS')
|
||||
},
|
||||
copy_tests: {
|
||||
value: true,
|
||||
|
|
@ -172,18 +172,18 @@ export function usePartFields({
|
|||
};
|
||||
}
|
||||
|
||||
if (settings.isSet('PART_REVISION_ASSEMBLY_ONLY')) {
|
||||
if (globalSettings.isSet('PART_REVISION_ASSEMBLY_ONLY')) {
|
||||
fields.revision_of.filters['assembly'] = true;
|
||||
}
|
||||
|
||||
// Pop 'revision' field if PART_ENABLE_REVISION is False
|
||||
if (!settings.isSet('PART_ENABLE_REVISION')) {
|
||||
if (!globalSettings.isSet('PART_ENABLE_REVISION')) {
|
||||
delete fields['revision'];
|
||||
delete fields['revision_of'];
|
||||
}
|
||||
|
||||
// Pop 'expiry' field if expiry not enabled
|
||||
if (!settings.isSet('STOCK_ENABLE_EXPIRY')) {
|
||||
if (!globalSettings.isSet('STOCK_ENABLE_EXPIRY')) {
|
||||
delete fields['default_expiry'];
|
||||
}
|
||||
|
||||
|
|
@ -198,8 +198,7 @@ export function usePartFields({
|
|||
purchaseable,
|
||||
create,
|
||||
globalSettings,
|
||||
duplicatePartInstance,
|
||||
settings
|
||||
duplicatePartInstance
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue