mirror of
https://github.com/wger-project/wger.git
synced 2026-02-18 00:17:51 +01:00
Merge branch 'master' into feature/set_ui_language
This commit is contained in:
16
.github/workflows/ci.yml
vendored
16
.github/workflows/ci.yml
vendored
@@ -16,6 +16,11 @@ on:
|
||||
jobs:
|
||||
ci-job:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
DJANGO_SETTINGS_MODULE: settings.ci
|
||||
DJANGO_MEDIA_ROOT: /tmp/wger-test
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
# Note: removed 3.14 because lingua-language-detector has no wheels yet
|
||||
@@ -41,22 +46,19 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
uv sync --group dev
|
||||
mkdir /tmp/wger-test
|
||||
|
||||
# Only run the tests with coverage for one version of python
|
||||
- name: Test the application with coverage
|
||||
if: matrix.python-version == 3.13
|
||||
run: |
|
||||
source .venv/bin/activate
|
||||
wger create-settings
|
||||
coverage run --source='.' ./manage.py test
|
||||
coverage lcov
|
||||
uv run coverage run --source='.' ./manage.py test
|
||||
uv run coverage lcov
|
||||
|
||||
- name: Test the application
|
||||
if: matrix.python-version != 3.13
|
||||
run: |
|
||||
source .venv/bin/activate
|
||||
wger create-settings
|
||||
python manage.py test
|
||||
uv run ./manage.py test
|
||||
|
||||
- name: Coveralls
|
||||
if: matrix.python-version == 3.13
|
||||
|
||||
4
.github/workflows/docker.yml
vendored
4
.github/workflows/docker.yml
vendored
@@ -44,7 +44,7 @@ jobs:
|
||||
# https://github.com/docker/metadata-action
|
||||
tags: |
|
||||
type=raw,value=latest
|
||||
type=raw,value=2.4-dev
|
||||
type=raw,value=2.5-dev
|
||||
images: |
|
||||
${{ env.REGISTRY_IMAGE }}
|
||||
|
||||
@@ -133,7 +133,7 @@ jobs:
|
||||
with:
|
||||
tags: |
|
||||
type=raw,value=latest
|
||||
type=raw,value=2.4-dev
|
||||
type=raw,value=2.5-dev
|
||||
images: |
|
||||
${{ env.REGISTRY_IMAGE }}
|
||||
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -46,7 +46,7 @@ coverage.xml
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
settings*.py
|
||||
settings/*_extra.py
|
||||
*.sqlite
|
||||
/CACHE
|
||||
|
||||
|
||||
75
AUTHORS.md
75
AUTHORS.md
@@ -2,7 +2,7 @@
|
||||
|
||||
Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
|
||||
*Generated on 2025-11-10*
|
||||
*Generated on 2026-01-18*
|
||||
|
||||
---
|
||||
|
||||
@@ -10,20 +10,38 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
|
||||
- Github-actions - [https://github.com/invalid-email-address](https://github.com/invalid-email-address)
|
||||
- Roland Geider - [https://github.com/rolandgeider](https://github.com/rolandgeider)
|
||||
- Justin - [https://github.com/justin-pinheiro](https://github.com/justin-pinheiro)
|
||||
- Justin Pinheiro - [https://github.com/justin-pinheiro](https://github.com/justin-pinheiro)
|
||||
- HairyCrabW - [https://github.com/HairyCrabW](https://github.com/HairyCrabW)
|
||||
- Jeremy - [https://github.com/zru-1](https://github.com/zru-1)
|
||||
- Yousef - [https://github.com/yza-cmu](https://github.com/yza-cmu)
|
||||
- Chidinma Obiekwe - [https://github.com/DidiNDexter](https://github.com/DidiNDexter)
|
||||
- Max Pylypenko - [https://github.com/3mpee3mpee](https://github.com/3mpee3mpee)
|
||||
- AKSHIT - [https://github.com/Akshit-MMQH](https://github.com/Akshit-MMQH)
|
||||
- Saad Muhammad - [https://github.com/saadpy0](https://github.com/saadpy0)
|
||||
- JANVI - [https://github.com/JANVI-CHATURVEDI](https://github.com/JANVI-CHATURVEDI)
|
||||
- Joseph - [https://github.com/seppzer0](https://github.com/seppzer0)
|
||||
- Christián Feliks - [https://github.com/ChristianFeliks](https://github.com/ChristianFeliks)
|
||||
- Shantanu - [https://github.com/shantanugupta2004](https://github.com/shantanugupta2004)
|
||||
- Amandeep Mandal - [https://github.com/AmandeepMandal1077](https://github.com/AmandeepMandal1077)
|
||||
- Ziqi Lin
|
||||
- Dieter Plaetinck - [https://github.com/Dieterbe](https://github.com/Dieterbe)
|
||||
- hangy - [https://github.com/hangy](https://github.com/hangy)
|
||||
- Bonicki Wojciech
|
||||
- Horacio Duran - [https://github.com/perrito666](https://github.com/perrito666)
|
||||
- Peter Dave Hello - [https://github.com/PeterDaveHello](https://github.com/PeterDaveHello)
|
||||
- Cam Cecil - [https://github.com/scrapcode](https://github.com/scrapcode)
|
||||
- Ali Rahbar - [https://github.com/crypto-a](https://github.com/crypto-a)
|
||||
- Joshua Shelley - [https://github.com/navyjosh](https://github.com/navyjosh)
|
||||
- Joshua - [https://github.com/navyjosh](https://github.com/navyjosh)
|
||||
- Ali Rahbar - [https://github.com/crypto-a](https://github.com/crypto-a)
|
||||
- eyjhb - [https://github.com/eyJhb](https://github.com/eyJhb)
|
||||
- Matthew Harrison - [https://github.com/Maralai](https://github.com/Maralai)
|
||||
- Josh - [https://github.com/FlyingNimbusCloud](https://github.com/FlyingNimbusCloud)
|
||||
- eyjhb - [https://github.com/eyJhb](https://github.com/eyJhb)
|
||||
- kmoy1 - [https://github.com/kmoy1](https://github.com/kmoy1)
|
||||
- Kevin Moy - [https://github.com/kmoy1](https://github.com/kmoy1)
|
||||
- Victor B - [https://github.com/victorbmlabs](https://github.com/victorbmlabs)
|
||||
- Dieter Plaetinck - [https://github.com/Dieterbe](https://github.com/Dieterbe)
|
||||
- Taylor Fuller - [https://github.com/taylor-fuller](https://github.com/taylor-fuller)
|
||||
- Victor B
|
||||
- Taylor Fuller - [https://github.com/taylor-hileman](https://github.com/taylor-hileman)
|
||||
- JLaField - [https://github.com/JLaField](https://github.com/JLaField)
|
||||
- JLaField - [https://github.com/JLaField](https://github.com/JLaField)
|
||||
- bbk - [https://github.com/bbkz](https://github.com/bbkz)
|
||||
@@ -108,7 +126,7 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
- Withnale
|
||||
- Veltarn - [https://github.com/Veltarn](https://github.com/Veltarn)
|
||||
- Anjalie Kini
|
||||
- gmmoraes - [https://github.com/gmmoraes](https://github.com/gmmoraes)
|
||||
- gmmoraes - [https://github.com/Zutzsa](https://github.com/Zutzsa)
|
||||
- Peter van der Does - [https://github.com/petervanderdoes](https://github.com/petervanderdoes)
|
||||
- Daniel Topal - [https://github.com/dtopal](https://github.com/dtopal)
|
||||
- Mbarak Mbigo - [https://github.com/Mbarak-Mbigo](https://github.com/Mbarak-Mbigo)
|
||||
@@ -144,6 +162,8 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
|
||||
### Arabic (Saudi Arabia)
|
||||
|
||||
- E. Ta.
|
||||
- MR - [https://github.com/MyaserAL-Healy](https://github.com/MyaserAL-Healy)
|
||||
- SlyBat - [https://github.com/AW-G](https://github.com/AW-G)
|
||||
- Hissabat Manager - [https://github.com/Chinguetti-Quizz](https://github.com/Chinguetti-Quizz)
|
||||
- My Google - [https://github.com/ahmedtahraoui90](https://github.com/ahmedtahraoui90)
|
||||
@@ -159,6 +179,7 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
|
||||
### Chinese (Simplified Han script)
|
||||
|
||||
- KW Lam - [https://github.com/loksonlkw](https://github.com/loksonlkw)
|
||||
- Herb Huang
|
||||
|
||||
### Chinese (Simplified)
|
||||
@@ -191,11 +212,13 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
|
||||
### Danish
|
||||
|
||||
- Fedder Skovgaard - [https://github.com/fedders](https://github.com/fedders)
|
||||
- Tomasz Cielecki - [https://github.com/Cheesebaron](https://github.com/Cheesebaron)
|
||||
- Roland Geider - [https://github.com/rolandgeider](https://github.com/rolandgeider)
|
||||
|
||||
### Dutch
|
||||
|
||||
- Floris C
|
||||
- Christijan Mulder
|
||||
- Christijan - [https://github.com/ChrispyM](https://github.com/ChrispyM)
|
||||
- SilverServerT - [https://github.com/SilverServerT](https://github.com/SilverServerT)
|
||||
@@ -210,6 +233,7 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
|
||||
### Finnish
|
||||
|
||||
- Petri Hämäläinen - [https://github.com/pHamala](https://github.com/pHamala)
|
||||
- Ricky Tigg - [https://github.com/Ricky-Tigg](https://github.com/Ricky-Tigg)
|
||||
- Nikolay Korotkiy - [https://github.com/sikmir](https://github.com/sikmir)
|
||||
- Juuso Haapanen - [https://github.com/juusohaapanen](https://github.com/juusohaapanen)
|
||||
@@ -217,6 +241,9 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
|
||||
### French
|
||||
|
||||
- Justin Pinheiro - [https://github.com/justin-pinheiro](https://github.com/justin-pinheiro)
|
||||
- Paul Bonneau - [https://github.com/paulbonneau](https://github.com/paulbonneau)
|
||||
- Kilian
|
||||
- MrSniikyz - [https://github.com/BabyGeek](https://github.com/BabyGeek)
|
||||
- florent4014 - [https://github.com/florent4014](https://github.com/florent4014)
|
||||
- Lucas Batier - [https://github.com/lucas-batier](https://github.com/lucas-batier)
|
||||
@@ -229,10 +256,13 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
|
||||
### German
|
||||
|
||||
- Elias Lang - [https://github.com/elias170105](https://github.com/elias170105)
|
||||
- Traladarer
|
||||
- Richard Mrosk - [https://github.com/EtheriousNight](https://github.com/EtheriousNight)
|
||||
- Roland Geider - [https://github.com/rolandgeider](https://github.com/rolandgeider)
|
||||
- kvnrmnn - [https://github.com/rmnn92](https://github.com/rmnn92)
|
||||
- Tobias Lechner - [https://github.com/Lxchnxr](https://github.com/Lxchnxr)
|
||||
- becothas - [https://github.com/becothas](https://github.com/becothas)
|
||||
- Roland Geider - [https://github.com/rolandgeider](https://github.com/rolandgeider)
|
||||
- m4skedbyte
|
||||
- StefMe - [https://github.com/StefMe](https://github.com/StefMe)
|
||||
- Axel Steinbrecher
|
||||
@@ -244,7 +274,7 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
|
||||
### Greek
|
||||
|
||||
- Antonis-geo - [https://github.com/Antonis-geo](https://github.com/Antonis-geo)
|
||||
- Antonis-geo
|
||||
- George Koikas
|
||||
- Eugenia Russell - [https://github.com/eugenia-russell](https://github.com/eugenia-russell)
|
||||
- Allan Nordhøy - [https://github.com/comradekingu](https://github.com/comradekingu)
|
||||
@@ -252,12 +282,15 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
|
||||
### Hebrew
|
||||
|
||||
- Omer I.S - [https://github.com/omeritzics](https://github.com/omeritzics)
|
||||
- DR
|
||||
- shlomi assaf - [https://github.com/shlomiassaf](https://github.com/shlomiassaf)
|
||||
- Tsz Hong CHAN - [https://github.com/tomyan112](https://github.com/tomyan112)
|
||||
- n,rdo
|
||||
|
||||
### Hindi
|
||||
|
||||
- Madhav Agarwal - [https://github.com/gmrmad1](https://github.com/gmrmad1)
|
||||
- Ritik Sharma - [https://github.com/RitikSharma02](https://github.com/RitikSharma02)
|
||||
- Ritish Bhardwaj - [https://github.com/levidroid](https://github.com/levidroid)
|
||||
|
||||
@@ -269,12 +302,13 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
|
||||
### Italian
|
||||
|
||||
- Luca Galli - [https://github.com/Lvcaa](https://github.com/Lvcaa)
|
||||
- clafalco - [https://github.com/clafalco](https://github.com/clafalco)
|
||||
- Federico Pierantoni - [https://github.com/F3FFO](https://github.com/F3FFO)
|
||||
- oarion - [https://github.com/oarion](https://github.com/oarion)
|
||||
- Alessandro Faucci - [https://github.com/Dhy19971](https://github.com/Dhy19971)
|
||||
- Marco Accorinti - [https://github.com/accodev](https://github.com/accodev)
|
||||
- Armando La Placa - [https://github.com/a-lp](https://github.com/a-lp)
|
||||
- clafalco - [https://github.com/clafalco](https://github.com/clafalco)
|
||||
- DT
|
||||
- MARCO ACORTE - [https://github.com/marco-acorte](https://github.com/marco-acorte)
|
||||
- Roland Geider - [https://github.com/rolandgeider](https://github.com/rolandgeider)
|
||||
@@ -283,11 +317,13 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
|
||||
### Japanese
|
||||
|
||||
- Ryohei Morimoto - [https://github.com/Ryohei-Caulked](https://github.com/Ryohei-Caulked)
|
||||
- sasukeiscool - [https://github.com/sasukeiscool](https://github.com/sasukeiscool)
|
||||
- yuki chi - [https://github.com/kumo2kumo](https://github.com/kumo2kumo)
|
||||
|
||||
### Korean
|
||||
|
||||
- kobo
|
||||
- 고수처럼 - [https://github.com/rrrmaster](https://github.com/rrrmaster)
|
||||
- Gyu-sun Youm - [https://github.com/Perlmint](https://github.com/Perlmint)
|
||||
- 성동하 - [https://github.com/tomjovi](https://github.com/tomjovi)
|
||||
@@ -296,12 +332,14 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
|
||||
### Norwegian Bokmål
|
||||
|
||||
- GS Bacon
|
||||
- GS Bacon - [https://github.com/Z0ink5](https://github.com/Z0ink5)
|
||||
- Allan Nordhøy - [https://github.com/comradekingu](https://github.com/comradekingu)
|
||||
- Roland Geider - [https://github.com/rolandgeider](https://github.com/rolandgeider)
|
||||
|
||||
### Persian
|
||||
|
||||
- Mahmuoud Salehi
|
||||
- William Sky - [https://github.com/William-cloud-tech](https://github.com/William-cloud-tech)
|
||||
- m93n pk - [https://github.com/m93n](https://github.com/m93n)
|
||||
- anyBlackSoul
|
||||
- keyvanmj - [https://github.com/keyvanmj](https://github.com/keyvanmj)
|
||||
@@ -312,7 +350,7 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
- Karol Solecki - [https://github.com/karolsol](https://github.com/karolsol)
|
||||
- Dawid Panyło
|
||||
- Marcin Schoenknecht
|
||||
- gnu-ewm
|
||||
- gnu-ewm - [https://github.com/e-michalak](https://github.com/e-michalak)
|
||||
- A M - [https://github.com/AugiAugi44](https://github.com/AugiAugi44)
|
||||
- Jacob - [https://github.com/devzom](https://github.com/devzom)
|
||||
- Henio Szewczyk - [https://github.com/hszewczyk](https://github.com/hszewczyk)
|
||||
@@ -320,6 +358,7 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
|
||||
### Portuguese
|
||||
|
||||
- Ninguém Mesmo
|
||||
- Luiz Felipe Guidorizzi de Oliveira - [https://github.com/EvilMonark](https://github.com/EvilMonark)
|
||||
- Wilton Rodrigues
|
||||
- Guilherme Salomão - [https://github.com/salomaoparkour](https://github.com/salomaoparkour)
|
||||
@@ -337,6 +376,7 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
|
||||
### Romanian
|
||||
|
||||
- Vlad Bejenaru - [https://github.com/vladbejenaru](https://github.com/vladbejenaru)
|
||||
- B Sebastian
|
||||
- Daniel Vigaru - [https://github.com/danielvigaru](https://github.com/danielvigaru)
|
||||
- dimii27 - [https://github.com/dimii27](https://github.com/dimii27)
|
||||
@@ -344,6 +384,10 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
|
||||
### Russian
|
||||
|
||||
- Gevorg Danielyan - [https://github.com/Cyworc](https://github.com/Cyworc)
|
||||
- Иван Редун - [https://github.com/ireduntr](https://github.com/ireduntr)
|
||||
- Iskander - [https://github.com/iskanderCabbie](https://github.com/iskanderCabbie)
|
||||
- Maksim_220 Кабанов
|
||||
- Алексей Курышко - [https://github.com/alexkuryshko](https://github.com/alexkuryshko)
|
||||
- Kira - [https://github.com/Balalaika87](https://github.com/Balalaika87)
|
||||
- Nikolay Korotkiy - [https://github.com/sikmir](https://github.com/sikmir)
|
||||
@@ -356,6 +400,10 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
|
||||
### Spanish
|
||||
|
||||
- v7mbz
|
||||
- Jose David Villegas (JoseDv1) - [https://github.com/JoseDv1](https://github.com/JoseDv1)
|
||||
- Oscar González - [https://github.com/ogrydc](https://github.com/ogrydc)
|
||||
- Roland Geider - [https://github.com/rolandgeider](https://github.com/rolandgeider)
|
||||
- gallegonovato - [https://github.com/gallegonovato](https://github.com/gallegonovato)
|
||||
- hhugoac - [https://github.com/hhugoac](https://github.com/hhugoac)
|
||||
- Sergio Varela - [https://github.com/IngrownMink4](https://github.com/IngrownMink4)
|
||||
@@ -365,13 +413,13 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
- Sergio - [https://github.com/MrPointcut95](https://github.com/MrPointcut95)
|
||||
- abraham
|
||||
- Santiago Persico - [https://github.com/spersico](https://github.com/spersico)
|
||||
- Roland Geider - [https://github.com/rolandgeider](https://github.com/rolandgeider)
|
||||
- Alex Hidalgo - [https://github.com/alexjhidalgo](https://github.com/alexjhidalgo)
|
||||
- J. Lavoie
|
||||
- Allan Nordhøy - [https://github.com/comradekingu](https://github.com/comradekingu)
|
||||
|
||||
### Swedish
|
||||
|
||||
- wonnock - [https://github.com/emgust](https://github.com/emgust)
|
||||
- PNS11 - [https://github.com/cess11](https://github.com/cess11)
|
||||
- Kevin Gregard - [https://github.com/Kladdiskakan](https://github.com/Kladdiskakan)
|
||||
- tygyh - [https://github.com/tygyh](https://github.com/tygyh)
|
||||
@@ -387,6 +435,9 @@ Thank you all for contributing to the project, you are true heroes! 🫶
|
||||
|
||||
### Ukrainian
|
||||
|
||||
- Максим Горпиніч - [https://github.com/maksim2005UKR](https://github.com/maksim2005UKR)
|
||||
- Максим Горпиніч - [https://github.com/Maksim2005UA](https://github.com/Maksim2005UA)
|
||||
- Максим Горпиніч
|
||||
- Максим Горпиніч
|
||||
- kvinto - [https://github.com/badsystem](https://github.com/badsystem)
|
||||
- Dan - [https://github.com/Kefir2105](https://github.com/Kefir2105)
|
||||
|
||||
@@ -93,8 +93,6 @@ def fetch_commits_from_github(repo_name, github_token):
|
||||
print(f'Error fetching commits: {e}')
|
||||
break
|
||||
|
||||
break
|
||||
|
||||
return commits
|
||||
|
||||
|
||||
|
||||
@@ -41,15 +41,18 @@ RUN wget -O- https://deb.nodesource.com/setup_22.x | bash - \
|
||||
WORKDIR /home/wger/src
|
||||
COPY README.md pyproject.toml package.json package-lock.json package-lock.json /home/wger/src/
|
||||
COPY wger/version.py wger/__init__.py /home/wger/src/wger/
|
||||
COPY wger/core/static /root/src/wger/core/static
|
||||
COPY wger/core/static /home/wger/src/wger/core/static
|
||||
RUN npm ci --production \
|
||||
&& npm run build:css:sass \
|
||||
&& PACKAGE_NAME="@wger-project/react-components" \
|
||||
&& PACKAGE_VERSION=$(node -p "require('./package.json').devDependencies['$PACKAGE_NAME']") \
|
||||
&& TARBALL=$(npm pack ${PACKAGE_NAME}@${PACKAGE_VERSION}) \
|
||||
&& mkdir -p node_modules/${PACKAGE_NAME} \
|
||||
&& tar -xzf ${TARBALL} -C node_modules/${PACKAGE_NAME} --strip-components=1
|
||||
|
||||
&& tar -xzf ${TARBALL} -C node_modules/${PACKAGE_NAME} --strip-components=1 \
|
||||
&& pip3 wheel \
|
||||
--no-cache-dir \
|
||||
--wheel-dir /wheels \
|
||||
--group docker .
|
||||
|
||||
########
|
||||
# Final
|
||||
@@ -101,19 +104,24 @@ USER wger
|
||||
WORKDIR /home/wger/src
|
||||
RUN python3 -m venv /home/wger/venv
|
||||
|
||||
# Change permissions of some files and folders so the apache process
|
||||
# can access them.
|
||||
# Configure the application
|
||||
ENV PYTHONPATH=/home/wger/src
|
||||
ENV DJANGO_SETTINGS_MODULE=settings.main
|
||||
ENV MEDIA_ROOT=/home/wger/media
|
||||
ENV STATIC_ROOT=/home/wger/static
|
||||
ENV DJANGO_DB_DATABASE=/home/wger/db/database.sqlite
|
||||
ENV DJANGO_CACHE_BACKEND=django.core.cache.backends.locmem.LocMemCache
|
||||
|
||||
# Change permissions of some files and folders so the apache process can access them.
|
||||
RUN mkdir -p ~/static/CACHE ~/media \
|
||||
&& ln -s /home/wger/static/CACHE /home/wger/src/CACHE \
|
||||
&& chmod g+w /home/wger/static/CACHE
|
||||
|
||||
RUN --mount=type=bind,from=builder,source=/wheels,target=/wheels . /home/wger/venv/bin/activate \
|
||||
&& pip install --upgrade pip \
|
||||
&& pip install --no-cache /wheels/* \
|
||||
&& pip install -e . \
|
||||
&& wger create-settings --database-path /home/wger/db/database.sqlite \
|
||||
&& sed -i "/^MEDIA_ROOT/c\MEDIA_ROOT='\/home\/wger\/media'" settings.py \
|
||||
&& echo STATIC_ROOT=\'/home/wger/static\' >> settings.py \
|
||||
&& mkdir -p /home/wger/db \
|
||||
&& . /home/wger/venv/bin/activate \
|
||||
&& wger bootstrap --no-process-static \
|
||||
&& python3 manage.py sync-exercises \
|
||||
&& wger load-online-fixtures \
|
||||
|
||||
@@ -79,6 +79,8 @@ ARG BUILD_DATE
|
||||
ENV PATH="/home/wger/.local/bin:$PATH"
|
||||
ENV APP_BUILD_COMMIT=$BUILD_COMMIT
|
||||
ENV APP_BUILD_DATE=$BUILD_DATE
|
||||
ENV PYTHONPATH=/home/wger/src
|
||||
ENV DJANGO_SETTINGS_MODULE=settings.main
|
||||
|
||||
WORKDIR /home/wger/src
|
||||
EXPOSE 8000
|
||||
@@ -88,8 +90,6 @@ COPY --chown=wger:wger . /home/wger/src
|
||||
COPY --chown=wger:wger --from=builder /root/src/node_modules /home/wger/src/node_modules
|
||||
COPY --chown=wger:wger --from=builder /root/src/wger/core/static/bootstrap-compiled.css /home/wger/src/wger/core/static/bootstrap-compiled.css
|
||||
COPY --chown=wger:wger --from=builder /root/src/wger/core/static/bootstrap-compiled.css.map /home/wger/src/wger/core/static/bootstrap-compiled.css.map
|
||||
COPY ${DOCKER_DIR}/settings.py /home/wger/src
|
||||
COPY ${DOCKER_DIR}/settings.py /tmp/
|
||||
COPY ${DOCKER_DIR}/entrypoint.sh /home/wger/entrypoint.sh
|
||||
COPY ${DOCKER_DIR}/celery/start-beat /start-beat
|
||||
COPY ${DOCKER_DIR}/celery/start-worker /start-worker
|
||||
|
||||
@@ -65,8 +65,9 @@ fi
|
||||
# Sync ingredients
|
||||
if [[ "$SYNC_INGREDIENTS_ON_STARTUP" == "True" ]];
|
||||
then
|
||||
echo "Syncing ingredients"
|
||||
python3 manage.py sync-ingredients
|
||||
echo "The option SYNC_INGREDIENTS_ON_STARTUP is not supported anymore as it needs several hours to complete."
|
||||
echo "Please start the process manually with: docker compose exec web python3 manage.py sync-ingredients"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set the site URL
|
||||
|
||||
@@ -1,229 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Third Party
|
||||
import environ
|
||||
|
||||
# wger
|
||||
from wger.settings_global import *
|
||||
|
||||
env = environ.Env(
|
||||
# set casting, default value
|
||||
DJANGO_DEBUG=(bool, False)
|
||||
)
|
||||
|
||||
# Use 'DEBUG = True' to get more details for server errors
|
||||
DEBUG = env("DJANGO_DEBUG")
|
||||
|
||||
if os.environ.get('DJANGO_ADMINS'):
|
||||
ADMINS = [env.tuple('DJANGO_ADMINS'), ]
|
||||
MANAGERS = ADMINS
|
||||
|
||||
if os.environ.get("DJANGO_DB_ENGINE"):
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': env.str("DJANGO_DB_ENGINE"),
|
||||
'NAME': env.str("DJANGO_DB_DATABASE"),
|
||||
'USER': env.str("DJANGO_DB_USER"),
|
||||
'PASSWORD': env.str("DJANGO_DB_PASSWORD"),
|
||||
'HOST': env.str("DJANGO_DB_HOST"),
|
||||
'PORT': env.int("DJANGO_DB_PORT"),
|
||||
}
|
||||
}
|
||||
else:
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': env.str('DJANGO_DB_DATABASE', '/home/wger/db/database.sqlite'),
|
||||
}
|
||||
}
|
||||
|
||||
# Timezone for this installation. Consult settings_global.py for more information
|
||||
TIME_ZONE = env.str("TIME_ZONE", 'Europe/Berlin')
|
||||
|
||||
# Make this unique, and don't share it with anybody.
|
||||
SECRET_KEY = env.str("SECRET_KEY", 'wger-docker-supersecret-key-1234567890!@#$%^&*(-_)')
|
||||
|
||||
# Your reCaptcha keys
|
||||
RECAPTCHA_PUBLIC_KEY = env.str('RECAPTCHA_PUBLIC_KEY', '')
|
||||
RECAPTCHA_PRIVATE_KEY = env.str('RECAPTCHA_PRIVATE_KEY', '')
|
||||
|
||||
# The site's URL (e.g. http://www.my-local-gym.com or http://localhost:8000)
|
||||
# This is needed for uploaded files and images (exercise images, etc.) to be
|
||||
# properly served.
|
||||
SITE_URL = env.str('SITE_URL', 'http://localhost:8000')
|
||||
|
||||
# Path to uploaded files
|
||||
# Absolute filesystem path to the directory that will hold user-uploaded files.
|
||||
MEDIA_ROOT = env.str("DJANGO_MEDIA_ROOT", '/home/wger/media')
|
||||
STATIC_ROOT = env.str("DJANGO_STATIC_ROOT", '/home/wger/static')
|
||||
|
||||
# If you change these, adjust nginx alias definitions as well
|
||||
MEDIA_URL = env.str('MEDIA_URL', '/media/')
|
||||
STATIC_URL = env.str('STATIC_URL', '/static/')
|
||||
|
||||
LOGIN_REDIRECT_URL = env.str('LOGIN_REDIRECT_URL', '/')
|
||||
|
||||
# Allow all hosts to access the application. Change if used in production.
|
||||
ALLOWED_HOSTS = ['*', ]
|
||||
|
||||
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
|
||||
|
||||
# Configure a real backend in production
|
||||
if DEBUG:
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||
if env.bool("ENABLE_EMAIL", False):
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
EMAIL_HOST = env.str("EMAIL_HOST")
|
||||
EMAIL_PORT = env.int("EMAIL_PORT")
|
||||
EMAIL_HOST_USER = env.str("EMAIL_HOST_USER")
|
||||
EMAIL_HOST_PASSWORD = env.str("EMAIL_HOST_PASSWORD")
|
||||
EMAIL_USE_TLS = env.bool("EMAIL_USE_TLS", True)
|
||||
EMAIL_USE_SSL = env.bool("EMAIL_USE_SSL", False)
|
||||
EMAIL_TIMEOUT = 60
|
||||
|
||||
# Sender address used for sent emails
|
||||
DEFAULT_FROM_EMAIL = env.str("FROM_EMAIL", "wger Workout Manager <wger@example.com>")
|
||||
WGER_SETTINGS['EMAIL_FROM'] = DEFAULT_FROM_EMAIL
|
||||
SERVER_EMAIL = DEFAULT_FROM_EMAIL
|
||||
EMAIL_FROM_ADDRESS = DEFAULT_FROM_EMAIL
|
||||
|
||||
# Management
|
||||
WGER_SETTINGS["ALLOW_GUEST_USERS"] = env.bool("ALLOW_GUEST_USERS", True)
|
||||
WGER_SETTINGS["ALLOW_REGISTRATION"] = env.bool("ALLOW_REGISTRATION", True)
|
||||
WGER_SETTINGS["ALLOW_UPLOAD_VIDEOS"] = env.bool("ALLOW_UPLOAD_VIDEOS", True)
|
||||
WGER_SETTINGS["DOWNLOAD_INGREDIENTS_FROM"] = env.str("DOWNLOAD_INGREDIENTS_FROM", "WGER")
|
||||
WGER_SETTINGS["EXERCISE_CACHE_TTL"] = env.int("EXERCISE_CACHE_TTL", 3600)
|
||||
WGER_SETTINGS["MIN_ACCOUNT_AGE_TO_TRUST"] = env.int("MIN_ACCOUNT_AGE_TO_TRUST", 21) # in days
|
||||
WGER_SETTINGS["SYNC_EXERCISES_CELERY"] = env.bool("SYNC_EXERCISES_CELERY", False)
|
||||
WGER_SETTINGS["SYNC_EXERCISE_IMAGES_CELERY"] = env.bool("SYNC_EXERCISE_IMAGES_CELERY", False)
|
||||
WGER_SETTINGS["SYNC_EXERCISE_VIDEOS_CELERY"] = env.bool("SYNC_EXERCISE_VIDEOS_CELERY", False)
|
||||
WGER_SETTINGS["SYNC_INGREDIENTS_CELERY"] = env.bool("SYNC_INGREDIENTS_CELERY", False)
|
||||
WGER_SETTINGS["SYNC_OFF_DAILY_DELTA_CELERY"] = env.bool("SYNC_OFF_DAILY_DELTA_CELERY", False)
|
||||
WGER_SETTINGS["USE_RECAPTCHA"] = env.bool("USE_RECAPTCHA", False)
|
||||
WGER_SETTINGS["USE_CELERY"] = env.bool("USE_CELERY", False)
|
||||
WGER_SETTINGS["CACHE_API_EXERCISES_CELERY"] = env.bool("CACHE_API_EXERCISES_CELERY", False)
|
||||
WGER_SETTINGS["CACHE_API_EXERCISES_CELERY_FORCE_UPDATE"] = env.bool("CACHE_API_EXERCISES_CELERY_FORCE_UPDATE", False)
|
||||
|
||||
#
|
||||
# Auth Proxy Authentication
|
||||
# https://wger.readthedocs.io/en/latest/administration/auth_proxy.html
|
||||
AUTH_PROXY_HEADER = env.str("AUTH_PROXY_HEADER", '')
|
||||
AUTH_PROXY_TRUSTED_IPS = env.list("AUTH_PROXY_TRUSTED_IPS", default=[])
|
||||
AUTH_PROXY_CREATE_UNKNOWN_USER = env.bool("AUTH_PROXY_CREATE_UNKNOWN_USER", False)
|
||||
AUTH_PROXY_USER_EMAIL_HEADER = env.str("AUTH_PROXY_USER_EMAIL_HEADER", '')
|
||||
AUTH_PROXY_USER_NAME_HEADER = env.str("AUTH_PROXY_USER_NAME_HEADER", '')
|
||||
|
||||
# Cache
|
||||
if os.environ.get("DJANGO_CACHE_BACKEND"):
|
||||
CACHES = {
|
||||
'default': {
|
||||
'BACKEND': env.str("DJANGO_CACHE_BACKEND"),
|
||||
'LOCATION': env.str("DJANGO_CACHE_LOCATION"),
|
||||
'TIMEOUT': env.int("DJANGO_CACHE_TIMEOUT"),
|
||||
'OPTIONS': {
|
||||
'CLIENT_CLASS': env.str("DJANGO_CACHE_CLIENT_CLASS")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if os.environ.get('DJANGO_CACHE_CLIENT_PASSWORD'):
|
||||
CACHES['default']['OPTIONS']['PASSWORD'] = env.str('DJANGO_CACHE_CLIENT_PASSWORD')
|
||||
|
||||
CONNECTION_POOL_KWARGS = dict()
|
||||
if "DJANGO_CACHE_CLIENT_SSL_KEYFILE" in os.environ:
|
||||
CONNECTION_POOL_KWARGS['ssl_keyfile'] = env.str("DJANGO_CACHE_CLIENT_SSL_KEYFILE")
|
||||
|
||||
if "DJANGO_CACHE_CLIENT_SSL_CERTFILE" in os.environ:
|
||||
CONNECTION_POOL_KWARGS['ssl_certfile'] = env.str("DJANGO_CACHE_CLIENT_SSL_CERTFILE")
|
||||
|
||||
if "DJANGO_CACHE_CLIENT_SSL_CERT_REQS" in os.environ:
|
||||
CONNECTION_POOL_KWARGS['ssl_cert_reqs'] = env.str("DJANGO_CACHE_CLIENT_SSL_CERT_REQS")
|
||||
|
||||
if "DJANGO_CACHE_CLIENT_SSL_CHECK_HOSTNAME" in os.environ:
|
||||
CONNECTION_POOL_KWARGS['ssl_check_hostname'] = env.bool(
|
||||
"DJANGO_CACHE_CLIENT_SSL_CHECK_HOSTNAME")
|
||||
|
||||
if CONNECTION_POOL_KWARGS:
|
||||
CACHES["default"]["OPTIONS"]["CONNECTION_POOL_KWARGS"] = CONNECTION_POOL_KWARGS
|
||||
|
||||
# Folder for compressed CSS and JS files
|
||||
COMPRESS_ROOT = STATIC_ROOT
|
||||
COMPRESS_ENABLED = env.bool('COMPRESS_ENABLED', not DEBUG)
|
||||
|
||||
# The site's domain as used by the email verification workflow
|
||||
EMAIL_PAGE_DOMAIN = SITE_URL
|
||||
|
||||
#
|
||||
# Django Axes
|
||||
#
|
||||
AXES_ENABLED = env.bool('AXES_ENABLED', True)
|
||||
AXES_LOCKOUT_PARAMETERS = env.list('AXES_LOCKOUT_PARAMETERS', default=['ip_address'])
|
||||
AXES_FAILURE_LIMIT = env.int('AXES_FAILURE_LIMIT', 10)
|
||||
AXES_COOLOFF_TIME = timedelta(minutes=env.float('AXES_COOLOFF_TIME', 30))
|
||||
AXES_HANDLER = env.str('AXES_HANDLER', 'axes.handlers.cache.AxesCacheHandler')
|
||||
AXES_IPWARE_PROXY_COUNT = env.int('AXES_IPWARE_PROXY_COUNT', 0)
|
||||
AXES_IPWARE_META_PRECEDENCE_ORDER = env.list('AXES_IPWARE_META_PRECEDENCE_ORDER',
|
||||
default=['REMOTE_ADDR'])
|
||||
|
||||
#
|
||||
# Django Rest Framework SimpleJWT
|
||||
#
|
||||
SIMPLE_JWT['ACCESS_TOKEN_LIFETIME'] = timedelta(minutes=env.int("ACCESS_TOKEN_LIFETIME", 15))
|
||||
SIMPLE_JWT['REFRESH_TOKEN_LIFETIME'] = timedelta(hours=env.int("REFRESH_TOKEN_LIFETIME", 24))
|
||||
SIMPLE_JWT['SIGNING_KEY'] = env.str("SIGNING_KEY", SECRET_KEY)
|
||||
|
||||
#
|
||||
# https://docs.djangoproject.com/en/4.1/ref/csrf/
|
||||
#
|
||||
CSRF_TRUSTED_ORIGINS = env.list(
|
||||
"CSRF_TRUSTED_ORIGINS",
|
||||
default=['http://127.0.0.1', 'http://localhost', 'https://localhost'],
|
||||
)
|
||||
|
||||
if env.bool('X_FORWARDED_PROTO_HEADER_SET', False):
|
||||
SECURE_PROXY_SSL_HEADER = (
|
||||
env.str('SECURE_PROXY_SSL_HEADER', 'HTTP_X_FORWARDED_PROTO'),
|
||||
'https'
|
||||
)
|
||||
|
||||
REST_FRAMEWORK['NUM_PROXIES'] = env.int('NUMBER_OF_PROXIES', 1)
|
||||
|
||||
#
|
||||
# Celery message queue configuration
|
||||
#
|
||||
CELERY_BROKER_URL = env.str("CELERY_BROKER", "redis://cache:6379/2")
|
||||
CELERY_RESULT_BACKEND = env.str("CELERY_BACKEND", "redis://cache:6379/2")
|
||||
|
||||
#
|
||||
# Prometheus metrics
|
||||
#
|
||||
EXPOSE_PROMETHEUS_METRICS = env.bool('EXPOSE_PROMETHEUS_METRICS', False)
|
||||
PROMETHEUS_URL_PATH = env.str('PROMETHEUS_URL_PATH', 'super-secret-path')
|
||||
|
||||
#
|
||||
# Logging
|
||||
#
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'formatters': {
|
||||
'simple': {
|
||||
'format': 'level={levelname} ts={asctime} module={module} path={pathname} line={lineno} message={message}',
|
||||
'style': '{',
|
||||
},
|
||||
},
|
||||
'handlers': {
|
||||
'console': {
|
||||
'level': 'DEBUG',
|
||||
'class': 'logging.StreamHandler',
|
||||
'formatter': 'simple'
|
||||
},
|
||||
},
|
||||
'loggers': {
|
||||
'': {
|
||||
'handlers': ['console'],
|
||||
'level': env.str('LOG_LEVEL_PYTHON', 'INFO').upper(),
|
||||
'propagate': True,
|
||||
},
|
||||
}
|
||||
}
|
||||
15
manage.py
15
manage.py
@@ -1,24 +1,13 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Standard Library
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Django
|
||||
from django.core.management import execute_from_command_line
|
||||
|
||||
# wger
|
||||
from wger.tasks import (
|
||||
get_path,
|
||||
setup_django_environment,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# If user passed the settings flag ignore the default wger settings
|
||||
if not any('--settings' in s for s in sys.argv):
|
||||
setup_django_environment(get_path('settings.py'))
|
||||
|
||||
# Alternative to above
|
||||
# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings.main')
|
||||
execute_from_command_line(sys.argv)
|
||||
|
||||
72
package-lock.json
generated
72
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "wger",
|
||||
"version": "2.4.alpha1",
|
||||
"version": "2.5-alpha1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "wger",
|
||||
"version": "2.4.alpha1",
|
||||
"version": "2.5-alpha1",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.11.8",
|
||||
@@ -18,7 +18,7 @@
|
||||
"masonry-layout": "^4.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@wger-project/react-components": "25.12.5"
|
||||
"@wger-project/react-components": "26.1.18"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
@@ -2082,9 +2082,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@wger-project/react-components": {
|
||||
"version": "25.12.5",
|
||||
"resolved": "https://registry.npmjs.org/@wger-project/react-components/-/react-components-25.12.5.tgz",
|
||||
"integrity": "sha512-Z2UKlale7up/t1eZ9YrIY9UfczfRh0I1na96/xinxdYGt6lzMIG/4Yvo22VbNUAm6hIya0tMzeRitQ0CkUz6IQ==",
|
||||
"version": "26.1.18",
|
||||
"resolved": "https://registry.npmjs.org/@wger-project/react-components/-/react-components-26.1.18.tgz",
|
||||
"integrity": "sha512-mPeGaf6uvwnWBPSsLFcvM6N/z9f1rzGVyCrm9f/RiVS+SOP/ntCHbfxbEd/dl/CARfk0ceZL3QVREYu7Riq+IQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@emotion/babel-plugin": "^11.13.5",
|
||||
@@ -2114,7 +2114,9 @@
|
||||
"react-responsive": "^10.0.1",
|
||||
"react-router-dom": "^7.9.4",
|
||||
"react-simple-wysiwyg": "^3.4.1",
|
||||
"react-slick": "^0.31.0",
|
||||
"recharts": "^3.4.1",
|
||||
"slick-carousel": "^1.8.1",
|
||||
"slug": "^9.1.0",
|
||||
"typescript": "^5.9.3",
|
||||
"vite-tsconfig-paths": "^5.1.4",
|
||||
@@ -2265,6 +2267,13 @@
|
||||
],
|
||||
"license": "CC-BY-4.0"
|
||||
},
|
||||
"node_modules/classnames": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
|
||||
"integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/clsx": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
||||
@@ -3206,6 +3215,16 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/json2mq": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz",
|
||||
"integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"string-convert": "^0.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/json5": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
@@ -3240,6 +3259,13 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.debounce": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
|
||||
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
@@ -3758,6 +3784,23 @@
|
||||
"react": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-slick": {
|
||||
"version": "0.31.0",
|
||||
"resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.31.0.tgz",
|
||||
"integrity": "sha512-zo6VLT8wuSBJffg/TFPbzrw2dEnfZ/cUKmYsKByh3AgatRv29m2LoFbq5vRMa3R3A4wp4d8gwbJKO2fWZFaI3g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"classnames": "^2.2.5",
|
||||
"json2mq": "^0.2.0",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"resize-observer-polyfill": "^1.5.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-transition-group": {
|
||||
"version": "4.4.5",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
||||
@@ -3942,6 +3985,16 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/slick-carousel": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/slick-carousel/-/slick-carousel-1.8.1.tgz",
|
||||
"integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"jquery": ">=1.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/slug": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/slug/-/slug-9.1.0.tgz",
|
||||
@@ -3973,6 +4026,13 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string-convert": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz",
|
||||
"integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/stylis": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wger",
|
||||
"version": "2.4.alpha1",
|
||||
"version": "2.5-alpha1",
|
||||
"description": "Self hosted FLOSS fitness/workout and weight tracker",
|
||||
"repository": "github:wger-project/wger",
|
||||
"author": "wger team <hello@wger.de>",
|
||||
@@ -19,7 +19,7 @@
|
||||
"masonry-layout": "^4.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@wger-project/react-components": "25.12.5"
|
||||
"@wger-project/react-components": "26.1.18"
|
||||
},
|
||||
"scripts": {
|
||||
"build:css:sass": "sass wger/core/static/scss/main.scss wger/core/static/bootstrap-compiled.css"
|
||||
|
||||
@@ -34,7 +34,6 @@ dependencies = [
|
||||
"django-activity-stream~=2.0.0",
|
||||
"django-axes[ipware]~=8.0.0",
|
||||
"django-bootstrap-breadcrumbs2==1.0.0",
|
||||
"django-compressor~=4.6.0",
|
||||
"django-cors-headers~=4.9.0",
|
||||
"django-crispy-forms~=2.5",
|
||||
"django-email-verification~=0.3.3",
|
||||
@@ -165,7 +164,7 @@ line-ending = "auto"
|
||||
src_paths = ["wger", "extras"]
|
||||
|
||||
sections = ["FUTURE", "STDLIB", "DJANGO", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"]
|
||||
skip = ["extras", "build", "dist", "node_modules", "migrations", "docs", "settings.py", "apps.py"]
|
||||
skip = ["extras", "build", "dist", "node_modules", "migrations", "docs", "settings", "apps.py"]
|
||||
# If set to true - ensures that if a star import is present, nothing else is
|
||||
# imported from that namespace.
|
||||
combine_star = false
|
||||
|
||||
15
settings/README.md
Normal file
15
settings/README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Settings
|
||||
|
||||
This directory contains configuration files and settings for the project.
|
||||
|
||||
You can add your own configuration files here, e.g. for development. Set
|
||||
the `DJANGO_SETTINGS_MODULE` environment variable to point to the new settings
|
||||
file. E.g.:
|
||||
|
||||
```bash
|
||||
export DJANGO_SETTINGS_MODULE=settings.local_dev
|
||||
python manage.py runserver
|
||||
```
|
||||
|
||||
If you want to add settings that are not tracked by git, you can create a
|
||||
`local_dev_extra.py` file, this will be imported by `local_dev.py` if it exists.
|
||||
0
settings/__init__.py
Normal file
0
settings/__init__.py
Normal file
@@ -1,31 +1,48 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# This file is part of wger Workout Manager.
|
||||
#
|
||||
# wger Workout Manager is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# wger Workout Manager is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
|
||||
# ruff: noqa: F405
|
||||
|
||||
# Third Party
|
||||
import environ
|
||||
|
||||
# wger
|
||||
from wger.settings_global import *
|
||||
from .settings_global import * # noqa: F403
|
||||
|
||||
env = environ.Env()
|
||||
|
||||
# Use 'DEBUG = True' to get more details for server errors
|
||||
DEBUG = True
|
||||
|
||||
# Application settings
|
||||
WGER_SETTINGS['EMAIL_FROM'] = 'wger Workout Manager <wger@example.com>'
|
||||
WGER_SETTINGS["ALLOW_REGISTRATION"] = True
|
||||
WGER_SETTINGS["ALLOW_GUEST_USERS"] = True
|
||||
WGER_SETTINGS["ALLOW_UPLOAD_VIDEOS"] = False
|
||||
WGER_SETTINGS["MIN_ACCOUNT_AGE_TO_TRUST"] = 21 # in days
|
||||
WGER_SETTINGS["EXERCISE_CACHE_TTL"] = 3600 # in seconds
|
||||
WGER_SETTINGS['ALLOW_REGISTRATION'] = True
|
||||
WGER_SETTINGS['ALLOW_GUEST_USERS'] = True
|
||||
WGER_SETTINGS['ALLOW_UPLOAD_VIDEOS'] = False
|
||||
WGER_SETTINGS['MIN_ACCOUNT_AGE_TO_TRUST'] = 21 # in days
|
||||
WGER_SETTINGS['EXERCISE_CACHE_TTL'] = 3600 # in seconds
|
||||
|
||||
DATABASES = {{
|
||||
'default': {{
|
||||
'ENGINE': 'django.db.backends.{dbengine}',
|
||||
'NAME': '{dbname}',
|
||||
'USER': '{dbuser}',
|
||||
'PASSWORD': '{dbpassword}',
|
||||
'HOST': '{dbhost}',
|
||||
'PORT': '{dbport}',
|
||||
}}
|
||||
}} # yapf: disable
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': '/Users/roland/Entwicklung/wger/server/database.sqlite',
|
||||
'USER': '',
|
||||
'PASSWORD': '',
|
||||
'HOST': '',
|
||||
'PORT': '',
|
||||
}
|
||||
} # yapf: disable
|
||||
|
||||
# List of administrations
|
||||
ADMINS = (('Your name', 'your_email@example.com'),)
|
||||
@@ -39,7 +56,7 @@ MANAGERS = ADMINS
|
||||
TIME_ZONE = 'Europe/Berlin'
|
||||
|
||||
# Make this unique, and don't share it with anybody.
|
||||
SECRET_KEY = '{default_key}'
|
||||
SECRET_KEY = '61fxc$k%9nj!be-_up9%xzm(z)9l7$h33b1!@bf9581=c-03%p'
|
||||
|
||||
# Your reCaptcha keys
|
||||
RECAPTCHA_PUBLIC_KEY = ''
|
||||
@@ -49,14 +66,14 @@ USE_RECAPTCHA = False
|
||||
# The site's URL (e.g. http://www.my-local-gym.com or http://localhost:8000)
|
||||
# This is needed for uploaded files and images (exercise images, etc.) to be
|
||||
# properly served.
|
||||
SITE_URL = '{siteurl}'
|
||||
SITE_URL = 'http://localhost:8000'
|
||||
|
||||
# Path to uploaded files
|
||||
# Absolute filesystem path to the directory that will hold user-uploaded files.
|
||||
MEDIA_ROOT = '{media_folder_path}'
|
||||
MEDIA_ROOT = env.str('DJANGO_MEDIA_ROOT', '/tmp/')
|
||||
MEDIA_URL = '/media/'
|
||||
|
||||
# Allow all hosts to access the application. Change if used in production.
|
||||
# Allow all hosts to access the application.
|
||||
ALLOWED_HOSTS = [
|
||||
'*',
|
||||
]
|
||||
@@ -78,23 +95,3 @@ EMAIL_PAGE_DOMAIN = SITE_URL
|
||||
# https://django-axes.readthedocs.io/en/latest/
|
||||
#
|
||||
AXES_ENABLED = False
|
||||
# AXES_FAILURE_LIMIT = 10
|
||||
# AXES_COOLOFF_TIME = timedelta(minutes=30)
|
||||
# AXES_HANDLER = 'axes.handlers.cache.AxesCacheHandler'
|
||||
|
||||
#
|
||||
# Sometimes needed if deployed behind a proxy with HTTPS enabled:
|
||||
# https://docs.djangoproject.com/en/4.1/ref/csrf/
|
||||
#
|
||||
# CSRF_TRUSTED_ORIGINS = ['http://127.0.0.1', 'https://my.domain.example.com']
|
||||
|
||||
# Alternative to above, needs changes to the reverse proxy's config
|
||||
# https://docs.djangoproject.com/en/4.1/ref/settings/#secure-proxy-ssl-header
|
||||
#
|
||||
# SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO, 'https')
|
||||
|
||||
#
|
||||
# Celery
|
||||
# Needed if you plan to use celery for background tasks
|
||||
# CELERY_BROKER_URL = "redis://localhost:6379/2"
|
||||
# CELERY_RESULT_BACKEND = "redis://localhost:6379/2"
|
||||
125
settings/local_dev.py
Normal file
125
settings/local_dev.py
Normal file
@@ -0,0 +1,125 @@
|
||||
"""Local development settings for wger"""
|
||||
|
||||
# ruff: noqa: F405
|
||||
# ruff: noqa: F403
|
||||
|
||||
# wger
|
||||
from .settings_global import *
|
||||
|
||||
DEBUG = True
|
||||
|
||||
# List of administrators
|
||||
ADMINS = (('Your name', 'your_email@example.com'),)
|
||||
MANAGERS = ADMINS
|
||||
|
||||
# Don't use this key in production!
|
||||
SECRET_KEY = 'wger-local-development-supersecret-key-1234567890!'
|
||||
|
||||
# Allow all hosts to access the application.
|
||||
ALLOWED_HOSTS = [
|
||||
'*',
|
||||
]
|
||||
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||
|
||||
# WGER application
|
||||
WGER_SETTINGS['ALLOW_UPLOAD_VIDEOS'] = True
|
||||
WGER_SETTINGS['ALLOW_GUEST_USERS'] = True
|
||||
WGER_SETTINGS['ALLOW_REGISTRATION'] = True
|
||||
WGER_SETTINGS['DOWNLOAD_INGREDIENTS_FROM'] = 'WGER' # or 'None' to disable
|
||||
WGER_SETTINGS['EMAIL_FROM'] = 'wger Workout Manager <wger@example.com>'
|
||||
WGER_SETTINGS['EXERCISE_CACHE_TTL'] = 500
|
||||
WGER_SETTINGS['INGREDIENT_CACHE_TTL'] = 500
|
||||
WGER_SETTINGS['SYNC_EXERCISES_CELERY'] = False
|
||||
WGER_SETTINGS['SYNC_EXERCISE_IMAGES_CELERY'] = True
|
||||
WGER_SETTINGS['SYNC_EXERCISE_VIDEOS_CELERY'] = False
|
||||
WGER_SETTINGS['SYNC_INGREDIENTS_CELERY'] = True
|
||||
WGER_SETTINGS['USE_CELERY'] = False
|
||||
WGER_SETTINGS['CACHE_API_EXERCISES_CELERY'] = True
|
||||
WGER_SETTINGS['CACHE_API_EXERCISES_CELERY_FORCE_UPDATE'] = True
|
||||
WGER_SETTINGS['ROUTINE_CACHE_TTL'] = 500
|
||||
DEFAULT_FROM_EMAIL = WGER_SETTINGS['EMAIL_FROM']
|
||||
|
||||
|
||||
# CELERY_BROKER_URL = "redis://localhost:6379/2"
|
||||
# CELERY_RESULT_BACKEND = "redis://localhost:6379/2"
|
||||
|
||||
CSRF_TRUSTED_ORIGINS = ['http://localhost:8000', 'http://127.0.0.1:8000']
|
||||
|
||||
EXPOSE_PROMETHEUS_METRICS = True
|
||||
|
||||
COMPRESS_ENABLED = False
|
||||
AXES_ENABLED = False
|
||||
|
||||
|
||||
# Does not really cache anything
|
||||
CACHES_DUMMY = {
|
||||
'default': {
|
||||
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
|
||||
'TIMEOUT': 100,
|
||||
}
|
||||
}
|
||||
|
||||
# In-memory cache, resets when the server restarts
|
||||
CACHE_LOCMEM = {
|
||||
'default': {
|
||||
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
|
||||
'LOCATION': 'wger-cache',
|
||||
'TIMEOUT': 100,
|
||||
}
|
||||
}
|
||||
|
||||
# Redis cache
|
||||
CACHE_REDIS = {
|
||||
'default': {
|
||||
'BACKEND': 'django_redis.cache.RedisCache',
|
||||
'LOCATION': 'redis://localhost:6379/1',
|
||||
'TIMEOUT': 5000,
|
||||
'OPTIONS': {'CLIENT_CLASS': 'django_redis.client.DefaultClient'},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# CACHES = CACHE_REDIS
|
||||
CACHES = CACHE_LOCMEM
|
||||
# CACHES = CACHES_DUMMY
|
||||
|
||||
|
||||
# Django Debug Toolbar
|
||||
# INSTALLED_APPS += ['django_extensions', 'debug_toolbar']
|
||||
# MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware", ]
|
||||
# INTERNAL_IPS = ["127.0.0.1", ]
|
||||
|
||||
# AUTH_PROXY_HEADER = 'HTTP_X_REMOTE_USER'
|
||||
# AUTH_PROXY_USER_EMAIL_HEADER = 'HTTP_X_REMOTE_USER_EMAIL'
|
||||
# AUTH_PROXY_USER_NAME_HEADER = 'HTTP_X_REMOTE_USER_NAME'
|
||||
# AUTH_PROXY_TRUSTED_IPS = ['127.0.0.1', ]
|
||||
# AUTH_PROXY_CREATE_UNKNOWN_USER = True
|
||||
|
||||
|
||||
DBCONFIG_PG = {
|
||||
'ENGINE': 'django_prometheus.db.backends.postgresql',
|
||||
'NAME': 'wger',
|
||||
'USER': 'wger',
|
||||
'PASSWORD': 'wger',
|
||||
'HOST': 'localhost',
|
||||
'PORT': '5432',
|
||||
}
|
||||
|
||||
|
||||
DBCONFIG_SQLITE = {
|
||||
'ENGINE': 'django_prometheus.db.backends.sqlite3',
|
||||
'NAME': BASE_DIR.parent / 'db' / 'database.sqlite',
|
||||
}
|
||||
|
||||
DATABASES = {
|
||||
# 'default': DBCONFIG_PG,
|
||||
'default': DBCONFIG_SQLITE,
|
||||
}
|
||||
|
||||
|
||||
# Import other local settings that are not in version control
|
||||
try:
|
||||
from .local_dev_extra import *
|
||||
except ImportError:
|
||||
pass
|
||||
277
settings/main.py
Normal file
277
settings/main.py
Normal file
@@ -0,0 +1,277 @@
|
||||
# This file is part of wger Workout Manager.
|
||||
#
|
||||
# wger Workout Manager is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# wger Workout Manager is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
|
||||
# ruff: noqa: F405
|
||||
|
||||
# Third Party
|
||||
import environ
|
||||
|
||||
# wger
|
||||
from .settings_global import * # noqa: F403
|
||||
|
||||
"""
|
||||
Main settings file for a production deployment of wger.
|
||||
|
||||
For a more commented version of the options used here, please refer to
|
||||
https://github.com/wger-project/docker/blob/master/config/prod.env
|
||||
"""
|
||||
|
||||
env = environ.Env(
|
||||
# set casting, default value
|
||||
DJANGO_DEBUG=(bool, False)
|
||||
)
|
||||
|
||||
# Use 'DEBUG = True' to get more details for server errors
|
||||
DEBUG = env('DJANGO_DEBUG')
|
||||
|
||||
if os.environ.get('DJANGO_ADMINS'):
|
||||
ADMINS = [
|
||||
env.tuple('DJANGO_ADMINS'),
|
||||
]
|
||||
MANAGERS = ADMINS
|
||||
|
||||
if os.environ.get('DJANGO_DB_ENGINE'):
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': env.str('DJANGO_DB_ENGINE'),
|
||||
'NAME': env.str('DJANGO_DB_DATABASE'),
|
||||
'USER': env.str('DJANGO_DB_USER'),
|
||||
'PASSWORD': env.str('DJANGO_DB_PASSWORD'),
|
||||
'HOST': env.str('DJANGO_DB_HOST'),
|
||||
'PORT': env.int('DJANGO_DB_PORT'),
|
||||
}
|
||||
}
|
||||
else:
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': env.str('DJANGO_DB_DATABASE', '/home/wger/db/database.sqlite'),
|
||||
}
|
||||
}
|
||||
|
||||
# Timezone for this installation. Consult settings_global.py for more information
|
||||
TIME_ZONE = env.str('TIME_ZONE', 'Europe/Berlin')
|
||||
|
||||
# Make this unique, and don't share it with anybody.
|
||||
# Generate e.g. with: python -c "import secrets; print(secrets.token_urlsafe(50))" or https://djecrety.ir/
|
||||
SECRET_KEY = env.str('SECRET_KEY', 'wger-docker-supersecret-key-1234567890!@#$%^&*(-_)')
|
||||
|
||||
# Your reCaptcha keys
|
||||
RECAPTCHA_PUBLIC_KEY = env.str('RECAPTCHA_PUBLIC_KEY', '')
|
||||
RECAPTCHA_PRIVATE_KEY = env.str('RECAPTCHA_PRIVATE_KEY', '')
|
||||
|
||||
# The site's URL (e.g. http://www.my-local-gym.com or http://localhost:8000)
|
||||
# This is needed for uploaded files and images (exercise images, etc.) to be
|
||||
# properly served.
|
||||
SITE_URL = env.str('SITE_URL', 'http://localhost:8000')
|
||||
|
||||
# Path to uploaded files
|
||||
# Absolute filesystem path to the directory that will hold user-uploaded files.
|
||||
MEDIA_ROOT = env.str('DJANGO_MEDIA_ROOT', '/home/wger/media')
|
||||
STATIC_ROOT = env.str('DJANGO_STATIC_ROOT', '/home/wger/static')
|
||||
|
||||
# If you change these, adjust nginx alias definitions as well
|
||||
MEDIA_URL = env.str('MEDIA_URL', '/media/')
|
||||
STATIC_URL = env.str('STATIC_URL', '/static/')
|
||||
|
||||
LOGIN_REDIRECT_URL = env.str('LOGIN_REDIRECT_URL', '/')
|
||||
|
||||
# Allow all hosts to access the application. Change if used in production.
|
||||
ALLOWED_HOSTS = [
|
||||
'*',
|
||||
]
|
||||
|
||||
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
|
||||
|
||||
# Configure a real backend in production
|
||||
if DEBUG:
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||
|
||||
if env.bool('ENABLE_EMAIL', False):
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
EMAIL_HOST = env.str('EMAIL_HOST')
|
||||
EMAIL_PORT = env.int('EMAIL_PORT')
|
||||
EMAIL_HOST_USER = env.str('EMAIL_HOST_USER')
|
||||
EMAIL_HOST_PASSWORD = env.str('EMAIL_HOST_PASSWORD')
|
||||
EMAIL_USE_TLS = env.bool('EMAIL_USE_TLS', True)
|
||||
EMAIL_USE_SSL = env.bool('EMAIL_USE_SSL', False)
|
||||
EMAIL_TIMEOUT = 60
|
||||
|
||||
# Sender address used for sent emails
|
||||
DEFAULT_FROM_EMAIL = env.str('FROM_EMAIL', 'wger Workout Manager <wger@example.com>')
|
||||
WGER_SETTINGS['EMAIL_FROM'] = DEFAULT_FROM_EMAIL
|
||||
SERVER_EMAIL = DEFAULT_FROM_EMAIL
|
||||
EMAIL_FROM_ADDRESS = DEFAULT_FROM_EMAIL
|
||||
|
||||
# Management
|
||||
WGER_SETTINGS['ALLOW_GUEST_USERS'] = env.bool('ALLOW_GUEST_USERS', True)
|
||||
WGER_SETTINGS['ALLOW_REGISTRATION'] = env.bool('ALLOW_REGISTRATION', True)
|
||||
WGER_SETTINGS['ALLOW_UPLOAD_VIDEOS'] = env.bool('ALLOW_UPLOAD_VIDEOS', True)
|
||||
WGER_SETTINGS['DOWNLOAD_INGREDIENTS_FROM'] = env.str('DOWNLOAD_INGREDIENTS_FROM', 'WGER')
|
||||
WGER_SETTINGS['EXERCISE_CACHE_TTL'] = env.int('EXERCISE_CACHE_TTL', 3600)
|
||||
WGER_SETTINGS['MIN_ACCOUNT_AGE_TO_TRUST'] = env.int('MIN_ACCOUNT_AGE_TO_TRUST', 21) # in days
|
||||
WGER_SETTINGS['SYNC_EXERCISES_CELERY'] = env.bool('SYNC_EXERCISES_CELERY', False)
|
||||
WGER_SETTINGS['SYNC_EXERCISE_IMAGES_CELERY'] = env.bool('SYNC_EXERCISE_IMAGES_CELERY', False)
|
||||
WGER_SETTINGS['SYNC_EXERCISE_VIDEOS_CELERY'] = env.bool('SYNC_EXERCISE_VIDEOS_CELERY', False)
|
||||
WGER_SETTINGS['SYNC_INGREDIENTS_CELERY'] = env.bool('SYNC_INGREDIENTS_CELERY', False)
|
||||
WGER_SETTINGS['SYNC_OFF_DAILY_DELTA_CELERY'] = env.bool('SYNC_OFF_DAILY_DELTA_CELERY', False)
|
||||
WGER_SETTINGS['USE_RECAPTCHA'] = env.bool('USE_RECAPTCHA', False)
|
||||
WGER_SETTINGS['USE_CELERY'] = env.bool('USE_CELERY', False)
|
||||
WGER_SETTINGS['CACHE_API_EXERCISES_CELERY'] = env.bool('CACHE_API_EXERCISES_CELERY', False)
|
||||
WGER_SETTINGS['CACHE_API_EXERCISES_CELERY_FORCE_UPDATE'] = env.bool(
|
||||
'CACHE_API_EXERCISES_CELERY_FORCE_UPDATE', False
|
||||
)
|
||||
|
||||
#
|
||||
# Auth Proxy Authentication
|
||||
# https://wger.readthedocs.io/en/latest/administration/auth_proxy.html
|
||||
AUTH_PROXY_HEADER = env.str('AUTH_PROXY_HEADER', '')
|
||||
AUTH_PROXY_TRUSTED_IPS = env.list('AUTH_PROXY_TRUSTED_IPS', default=[])
|
||||
AUTH_PROXY_CREATE_UNKNOWN_USER = env.bool('AUTH_PROXY_CREATE_UNKNOWN_USER', False)
|
||||
AUTH_PROXY_USER_EMAIL_HEADER = env.str('AUTH_PROXY_USER_EMAIL_HEADER', '')
|
||||
AUTH_PROXY_USER_NAME_HEADER = env.str('AUTH_PROXY_USER_NAME_HEADER', '')
|
||||
|
||||
# Cache
|
||||
if os.environ.get('DJANGO_CACHE_BACKEND'):
|
||||
CACHES = {
|
||||
'default': {
|
||||
'BACKEND': env.str('DJANGO_CACHE_BACKEND'),
|
||||
'LOCATION': env.str('DJANGO_CACHE_LOCATION', ''),
|
||||
'TIMEOUT': env.int('DJANGO_CACHE_TIMEOUT', 300),
|
||||
'OPTIONS': {'CLIENT_CLASS': env.str('DJANGO_CACHE_CLIENT_CLASS', '')},
|
||||
}
|
||||
}
|
||||
|
||||
if os.environ.get('DJANGO_CACHE_CLIENT_PASSWORD'):
|
||||
CACHES['default']['OPTIONS']['PASSWORD'] = env.str('DJANGO_CACHE_CLIENT_PASSWORD')
|
||||
|
||||
CONNECTION_POOL_KWARGS = dict()
|
||||
if 'DJANGO_CACHE_CLIENT_SSL_KEYFILE' in os.environ:
|
||||
CONNECTION_POOL_KWARGS['ssl_keyfile'] = env.str('DJANGO_CACHE_CLIENT_SSL_KEYFILE')
|
||||
|
||||
if 'DJANGO_CACHE_CLIENT_SSL_CERTFILE' in os.environ:
|
||||
CONNECTION_POOL_KWARGS['ssl_certfile'] = env.str('DJANGO_CACHE_CLIENT_SSL_CERTFILE')
|
||||
|
||||
if 'DJANGO_CACHE_CLIENT_SSL_CERT_REQS' in os.environ:
|
||||
CONNECTION_POOL_KWARGS['ssl_cert_reqs'] = env.str('DJANGO_CACHE_CLIENT_SSL_CERT_REQS')
|
||||
|
||||
if 'DJANGO_CACHE_CLIENT_SSL_CHECK_HOSTNAME' in os.environ:
|
||||
CONNECTION_POOL_KWARGS['ssl_check_hostname'] = env.bool(
|
||||
'DJANGO_CACHE_CLIENT_SSL_CHECK_HOSTNAME'
|
||||
)
|
||||
|
||||
if CONNECTION_POOL_KWARGS:
|
||||
CACHES['default']['OPTIONS']['CONNECTION_POOL_KWARGS'] = CONNECTION_POOL_KWARGS
|
||||
|
||||
#
|
||||
# Django Compressor
|
||||
# Consult https://django-compressor.readthedocs.io/en/stable/ for more information
|
||||
# (specially the offline compression part)
|
||||
#
|
||||
COMPRESS_ROOT = STATIC_ROOT
|
||||
COMPRESS_ENABLED = env.bool('COMPRESS_ENABLED', not DEBUG)
|
||||
COMPRESS_OFFLINE = env.bool('COMPRESS_OFFLINE', False)
|
||||
|
||||
# The site's domain as used by the email verification workflow
|
||||
EMAIL_PAGE_DOMAIN = SITE_URL
|
||||
|
||||
#
|
||||
# Django Axes
|
||||
#
|
||||
AXES_ENABLED = env.bool('AXES_ENABLED', True)
|
||||
AXES_LOCKOUT_PARAMETERS = env.list('AXES_LOCKOUT_PARAMETERS', default=['ip_address'])
|
||||
AXES_FAILURE_LIMIT = env.int('AXES_FAILURE_LIMIT', 10)
|
||||
AXES_COOLOFF_TIME = timedelta(minutes=env.float('AXES_COOLOFF_TIME', 30))
|
||||
AXES_HANDLER = env.str('AXES_HANDLER', 'axes.handlers.cache.AxesCacheHandler')
|
||||
AXES_IPWARE_PROXY_COUNT = env.int('AXES_IPWARE_PROXY_COUNT', 0)
|
||||
AXES_IPWARE_META_PRECEDENCE_ORDER = env.list(
|
||||
'AXES_IPWARE_META_PRECEDENCE_ORDER', default=['REMOTE_ADDR']
|
||||
)
|
||||
|
||||
#
|
||||
# Django Rest Framework SimpleJWT
|
||||
#
|
||||
SIMPLE_JWT['ACCESS_TOKEN_LIFETIME'] = timedelta(minutes=env.int('ACCESS_TOKEN_LIFETIME', 15))
|
||||
SIMPLE_JWT['REFRESH_TOKEN_LIFETIME'] = timedelta(hours=env.int('REFRESH_TOKEN_LIFETIME', 24))
|
||||
SIMPLE_JWT['SIGNING_KEY'] = env.str('SIGNING_KEY', SECRET_KEY)
|
||||
|
||||
#
|
||||
# https://docs.djangoproject.com/en/4.1/ref/csrf/
|
||||
#
|
||||
CSRF_TRUSTED_ORIGINS = env.list(
|
||||
'CSRF_TRUSTED_ORIGINS',
|
||||
default=['http://127.0.0.1', 'http://localhost', 'https://localhost'],
|
||||
)
|
||||
|
||||
if env.bool('X_FORWARDED_PROTO_HEADER_SET', False):
|
||||
SECURE_PROXY_SSL_HEADER = (
|
||||
env.str('SECURE_PROXY_SSL_HEADER', 'HTTP_X_FORWARDED_PROTO'),
|
||||
'https',
|
||||
)
|
||||
|
||||
REST_FRAMEWORK['NUM_PROXIES'] = env.int('NUMBER_OF_PROXIES', 1)
|
||||
|
||||
#
|
||||
# Celery message queue configuration
|
||||
#
|
||||
CELERY_BROKER_URL = env.str('CELERY_BROKER', 'redis://cache:6379/2')
|
||||
CELERY_RESULT_BACKEND = env.str('CELERY_BACKEND', 'redis://cache:6379/2')
|
||||
|
||||
#
|
||||
# Prometheus metrics
|
||||
#
|
||||
EXPOSE_PROMETHEUS_METRICS = env.bool('EXPOSE_PROMETHEUS_METRICS', False)
|
||||
PROMETHEUS_URL_PATH = env.str('PROMETHEUS_URL_PATH', 'super-secret-path')
|
||||
|
||||
#
|
||||
# Logging
|
||||
#
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'formatters': {
|
||||
'simple': {
|
||||
'format': 'level={levelname} ts={asctime} module={module} path={pathname} line={lineno} message={message}',
|
||||
'style': '{',
|
||||
},
|
||||
},
|
||||
'handlers': {
|
||||
'console': {'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'simple'},
|
||||
},
|
||||
'loggers': {
|
||||
'': {
|
||||
'handlers': ['console'],
|
||||
'level': env.str('LOG_LEVEL_PYTHON', 'INFO').upper(),
|
||||
'propagate': True,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
#
|
||||
# Storage options
|
||||
#
|
||||
STORAGES = {
|
||||
'default': {
|
||||
'BACKEND': env.str(
|
||||
'DJANGO_STORAGES_DEFAULT_BACKEND', 'django.core.files.storage.FileSystemStorage'
|
||||
),
|
||||
},
|
||||
# django.contrib.staticfiles.storage.StaticFilesStorage
|
||||
'staticfiles': {
|
||||
'BACKEND': env.str(
|
||||
'DJANGO_STORAGES_STATICFILES_BACKEND',
|
||||
'wger.core.storage.LenientManifestStaticFilesStorage',
|
||||
),
|
||||
},
|
||||
}
|
||||
@@ -18,20 +18,27 @@ import os
|
||||
import re
|
||||
import sys
|
||||
from datetime import timedelta
|
||||
from pathlib import Path
|
||||
|
||||
# wger
|
||||
from wger.utils.constants import DOWNLOAD_INGREDIENT_WGER
|
||||
from wger.version import get_version
|
||||
|
||||
|
||||
"""
|
||||
This file contains the global settings that don't usually need to be changed.
|
||||
For a full list of options, visit:
|
||||
https://docs.djangoproject.com/en/dev/ref/settings/
|
||||
"""
|
||||
|
||||
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
SITE_ROOT = os.path.realpath(os.path.dirname(__file__))
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent / 'wger'
|
||||
SITE_ROOT = Path(__file__).resolve().parent.parent / 'wger'
|
||||
|
||||
|
||||
# Static and media files (only during development)
|
||||
MEDIA_ROOT = BASE_DIR.parent / 'media'
|
||||
STATIC_ROOT = BASE_DIR.parent / 'static'
|
||||
MEDIA_URL = '/media/'
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
#
|
||||
# Application definition
|
||||
@@ -40,6 +47,7 @@ SITE_ID = 1
|
||||
ROOT_URLCONF = 'wger.urls'
|
||||
WSGI_APPLICATION = 'wger.wsgi.application'
|
||||
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
@@ -48,10 +56,8 @@ INSTALLED_APPS = [
|
||||
'django.contrib.sites',
|
||||
'django.contrib.staticfiles',
|
||||
'storages',
|
||||
|
||||
# Uncomment the next line to enable the admin:
|
||||
# 'django.contrib.admin',
|
||||
|
||||
# Apps from wger proper
|
||||
'wger.config',
|
||||
'wger.core',
|
||||
@@ -65,24 +71,16 @@ INSTALLED_APPS = [
|
||||
'wger.weight',
|
||||
'wger.gallery',
|
||||
'wger.measurements',
|
||||
# 'wger.trophies',
|
||||
|
||||
'wger.trophies',
|
||||
# reCaptcha support, see https://github.com/praekelt/django-recaptcha
|
||||
'django_recaptcha',
|
||||
|
||||
# The sitemaps app
|
||||
'django.contrib.sitemaps',
|
||||
|
||||
# thumbnails
|
||||
'easy_thumbnails',
|
||||
|
||||
# CSS/JS compressor
|
||||
'compressor',
|
||||
|
||||
# Form renderer helper
|
||||
'crispy_forms',
|
||||
'crispy_bootstrap5',
|
||||
|
||||
# REST-API
|
||||
'rest_framework',
|
||||
'rest_framework.authtoken',
|
||||
@@ -90,28 +88,20 @@ INSTALLED_APPS = [
|
||||
'rest_framework_simplejwt',
|
||||
'drf_spectacular',
|
||||
'drf_spectacular_sidecar',
|
||||
|
||||
# Breadcrumbs
|
||||
'django_bootstrap_breadcrumbs',
|
||||
|
||||
# CORS
|
||||
'corsheaders',
|
||||
|
||||
# Django Axes
|
||||
'axes',
|
||||
|
||||
# History keeping
|
||||
'simple_history',
|
||||
|
||||
# Django email verification
|
||||
'django_email_verification',
|
||||
|
||||
# Activity stream
|
||||
'actstream',
|
||||
|
||||
# Fontawesome
|
||||
'fontawesomefree',
|
||||
|
||||
# Prometheus
|
||||
'django_prometheus',
|
||||
]
|
||||
@@ -119,43 +109,33 @@ INSTALLED_APPS = [
|
||||
MIDDLEWARE = [
|
||||
# Prometheus
|
||||
'django_prometheus.middleware.PrometheusBeforeMiddleware',
|
||||
|
||||
'corsheaders.middleware.CorsMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
|
||||
# Django Admin
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
|
||||
# Auth proxy middleware
|
||||
'wger.core.middleware.AuthProxyHeaderMiddleware',
|
||||
|
||||
# Javascript Header. Sends helper headers for AJAX
|
||||
'wger.utils.middleware.JavascriptAJAXRedirectionMiddleware',
|
||||
|
||||
# Custom authentication middleware. Creates users on-the-fly for certain paths
|
||||
'wger.utils.middleware.WgerAuthenticationMiddleware',
|
||||
|
||||
# Send an appropriate Header so search engines don't index pages
|
||||
'wger.utils.middleware.RobotsExclusionMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
'django.middleware.locale.LocaleMiddleware',
|
||||
|
||||
# History keeping
|
||||
'simple_history.middleware.HistoryRequestMiddleware',
|
||||
|
||||
# Prometheus
|
||||
'django_prometheus.middleware.PrometheusAfterMiddleware',
|
||||
|
||||
# Django Axes
|
||||
'axes.middleware.AxesMiddleware', # should be the last one in the list
|
||||
]
|
||||
|
||||
AUTHENTICATION_BACKENDS = (
|
||||
'axes.backends.AxesStandaloneBackend', # should be the first one in the list
|
||||
|
||||
'wger.core.backends.AuthProxyUserBackend',
|
||||
'django.contrib.auth.backends.ModelBackend',
|
||||
'wger.utils.helpers.EmailAuthBackend',
|
||||
@@ -167,7 +147,6 @@ TEMPLATES = [
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'wger.utils.context_processor.processor',
|
||||
|
||||
# Django
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.template.context_processors.debug',
|
||||
@@ -176,15 +155,14 @@ TEMPLATES = [
|
||||
'django.template.context_processors.static',
|
||||
'django.template.context_processors.tz',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
|
||||
# Breadcrumbs
|
||||
'django.template.context_processors.request'
|
||||
'django.template.context_processors.request',
|
||||
],
|
||||
'loaders': [
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
'django.template.loaders.app_directories.Loader',
|
||||
],
|
||||
'debug': False
|
||||
'debug': False,
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -192,18 +170,15 @@ TEMPLATES = [
|
||||
# Store the user messages in the session
|
||||
MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'
|
||||
|
||||
# Static files
|
||||
# https://docs.djangoproject.com/en/6.0/ref/contrib/staticfiles/
|
||||
STATICFILES_FINDERS = (
|
||||
'django.contrib.staticfiles.finders.FileSystemFinder',
|
||||
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
|
||||
|
||||
# Django compressor
|
||||
'compressor.finders.CompressorFinder',
|
||||
)
|
||||
|
||||
# Additional places to copy to static files
|
||||
STATICFILES_DIRS = (
|
||||
('node', os.path.join(BASE_DIR, '..', 'node_modules')),
|
||||
)
|
||||
STATICFILES_DIRS = (('node', os.path.join(BASE_DIR, '..', 'node_modules')),)
|
||||
|
||||
|
||||
#
|
||||
# Email
|
||||
@@ -295,23 +270,17 @@ LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'formatters': {
|
||||
'simple': {
|
||||
'format': '%(levelname)s %(asctime)s %(module)s %(message)s'
|
||||
},
|
||||
'simple': {'format': '%(levelname)s %(asctime)s %(module)s %(message)s'},
|
||||
},
|
||||
'handlers': {
|
||||
'console': {
|
||||
'level': 'DEBUG',
|
||||
'class': 'logging.StreamHandler',
|
||||
'formatter': 'simple'
|
||||
},
|
||||
'console': {'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'simple'},
|
||||
},
|
||||
'loggers': {
|
||||
'wger': {
|
||||
'handlers': ['console'],
|
||||
'level': 'INFO',
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
#
|
||||
@@ -350,7 +319,7 @@ AXES_CACHE = 'default'
|
||||
#
|
||||
# Django Crispy Templates
|
||||
#
|
||||
CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"
|
||||
CRISPY_ALLOWED_TEMPLATE_PACKS = 'bootstrap5'
|
||||
CRISPY_TEMPLATE_PACK = 'bootstrap5'
|
||||
|
||||
#
|
||||
@@ -358,47 +327,19 @@ CRISPY_TEMPLATE_PACK = 'bootstrap5'
|
||||
#
|
||||
THUMBNAIL_ALIASES = {
|
||||
'': {
|
||||
'micro': {
|
||||
'size': (30, 30)
|
||||
},
|
||||
'micro_cropped': {
|
||||
'size': (30, 30),
|
||||
'crop': 'smart'
|
||||
},
|
||||
'thumbnail': {
|
||||
'size': (80, 80)
|
||||
},
|
||||
'thumbnail_cropped': {
|
||||
'size': (80, 80),
|
||||
'crop': 'smart'
|
||||
},
|
||||
'small': {
|
||||
'size': (200, 200)
|
||||
},
|
||||
'small_cropped': {
|
||||
'size': (200, 200),
|
||||
'crop': 'smart'
|
||||
},
|
||||
'medium': {
|
||||
'size': (400, 400)
|
||||
},
|
||||
'medium_cropped': {
|
||||
'size': (400, 400),
|
||||
'crop': 'smart'
|
||||
},
|
||||
'large': {
|
||||
'size': (800, 800),
|
||||
'quality': 90
|
||||
},
|
||||
'large_cropped': {
|
||||
'size': (800, 800),
|
||||
'crop': 'smart',
|
||||
'quality': 90
|
||||
},
|
||||
'micro': {'size': (30, 30)},
|
||||
'micro_cropped': {'size': (30, 30), 'crop': 'smart'},
|
||||
'thumbnail': {'size': (80, 80)},
|
||||
'thumbnail_cropped': {'size': (80, 80), 'crop': 'smart'},
|
||||
'small': {'size': (200, 200)},
|
||||
'small_cropped': {'size': (200, 200), 'crop': 'smart'},
|
||||
'medium': {'size': (400, 400)},
|
||||
'medium_cropped': {'size': (400, 400), 'crop': 'smart'},
|
||||
'large': {'size': (800, 800), 'quality': 90},
|
||||
'large_cropped': {'size': (800, 800), 'crop': 'smart', 'quality': 90},
|
||||
},
|
||||
}
|
||||
|
||||
STATIC_ROOT = ''
|
||||
USE_S3 = os.getenv('USE_S3') == 'TRUE'
|
||||
|
||||
if USE_S3:
|
||||
@@ -413,49 +354,14 @@ if USE_S3:
|
||||
AWS_LOCATION = 'static'
|
||||
STATIC_URL = 'https://%s/%s/' % (AWS_S3_CUSTOM_DOMAIN, AWS_LOCATION)
|
||||
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
|
||||
COMPRESS_URL = STATIC_URL
|
||||
COMPRESS_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
|
||||
COMPRESS_OFFLINE = True
|
||||
COMPRESS_OFFLINE_CONTEXT = [
|
||||
{
|
||||
'request': {
|
||||
'user_agent': {
|
||||
'is_mobile': True
|
||||
}
|
||||
},
|
||||
'STATIC_URL': STATIC_URL
|
||||
}, {
|
||||
'request': {
|
||||
'user_agent': {
|
||||
'is_mobile': False
|
||||
}
|
||||
},
|
||||
'STATIC_URL': STATIC_URL
|
||||
}
|
||||
]
|
||||
else:
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
#
|
||||
# Django compressor
|
||||
#
|
||||
|
||||
# The default is not DEBUG, override if needed
|
||||
# COMPRESS_ENABLED = True
|
||||
COMPRESS_CSS_FILTERS = (
|
||||
'compressor.filters.css_default.CssAbsoluteFilter',
|
||||
'compressor.filters.cssmin.rCSSMinFilter',
|
||||
)
|
||||
COMPRESS_JS_FILTERS = [
|
||||
'compressor.filters.jsmin.JSMinFilter',
|
||||
'compressor.filters.template.TemplateFilter',
|
||||
]
|
||||
COMPRESS_ROOT = STATIC_ROOT
|
||||
|
||||
#
|
||||
# Django Rest Framework
|
||||
# https://www.django-rest-framework.org/
|
||||
#
|
||||
# yapf: disable
|
||||
REST_FRAMEWORK = {
|
||||
'DEFAULT_PERMISSION_CLASSES': ('wger.utils.permissions.WgerPermission',),
|
||||
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
|
||||
@@ -472,16 +378,14 @@ REST_FRAMEWORK = {
|
||||
'rest_framework.filters.OrderingFilter',
|
||||
),
|
||||
'DEFAULT_THROTTLE_CLASSES': ['rest_framework.throttling.ScopedRateThrottle'],
|
||||
'DEFAULT_THROTTLE_RATES': {
|
||||
'login': '10/min',
|
||||
'registration': '5/min'
|
||||
},
|
||||
'DEFAULT_THROTTLE_RATES': {'login': '10/min', 'registration': '5/min'},
|
||||
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
|
||||
}
|
||||
# yapf: enable
|
||||
|
||||
# Api docs
|
||||
# yapf: disable
|
||||
#
|
||||
# API docs
|
||||
# https://drf-spectacular.readthedocs.io/en/latest/
|
||||
#
|
||||
SPECTACULAR_SETTINGS = {
|
||||
'TITLE': 'wger',
|
||||
'SERVERS': [
|
||||
@@ -495,9 +399,8 @@ SPECTACULAR_SETTINGS = {
|
||||
'SWAGGER_UI_DIST': 'SIDECAR',
|
||||
'SWAGGER_UI_FAVICON_HREF': 'SIDECAR',
|
||||
'REDOC_DIST': 'SIDECAR',
|
||||
'COMPONENT_SPLIT_REQUEST': True
|
||||
'COMPONENT_SPLIT_REQUEST': True,
|
||||
}
|
||||
# yapf: enable
|
||||
|
||||
#
|
||||
# Django Rest Framework SimpleJWT
|
||||
@@ -569,7 +472,6 @@ WGER_SETTINGS = {
|
||||
'USE_CELERY': False,
|
||||
'USE_RECAPTCHA': False,
|
||||
'WGER_INSTANCE': 'https://wger.de',
|
||||
|
||||
# Trophy system settings
|
||||
'TROPHIES_ENABLED': True, # Global toggle to enable/disable trophy system
|
||||
'TROPHIES_INACTIVE_USER_DAYS': 30, # Days of inactivity before skipping trophy evaluation
|
||||
@@ -620,3 +522,8 @@ ACTSTREAM_SETTINGS = {
|
||||
|
||||
# Whether the application is being run regularly or during tests
|
||||
TESTING = len(sys.argv) > 1 and sys.argv[1] == 'test'
|
||||
|
||||
# Your reCaptcha keys
|
||||
RECAPTCHA_PUBLIC_KEY = ''
|
||||
RECAPTCHA_PRIVATE_KEY = ''
|
||||
NOCAPTCHA = True
|
||||
578
uv.lock
generated
578
uv.lock
generated
@@ -81,7 +81,7 @@ css = [
|
||||
|
||||
[[package]]
|
||||
name = "celery"
|
||||
version = "5.6.0"
|
||||
version = "5.6.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "billiard" },
|
||||
@@ -89,15 +89,15 @@ dependencies = [
|
||||
{ name = "click-didyoumean" },
|
||||
{ name = "click-plugins" },
|
||||
{ name = "click-repl" },
|
||||
{ name = "exceptiongroup" },
|
||||
{ name = "exceptiongroup", marker = "python_full_version < '3.11'" },
|
||||
{ name = "kombu" },
|
||||
{ name = "python-dateutil" },
|
||||
{ name = "tzlocal" },
|
||||
{ name = "vine" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ad/5f/b681ae3c89290d2ea6562ea96b40f5af6f6fc5f7743e2cd1a19e47721548/celery-5.6.0.tar.gz", hash = "sha256:641405206042d52ae460e4e9751a2e31b06cf80ab836fcf92e0b9311d7ea8113", size = 1712522, upload-time = "2025-11-30T17:39:46.282Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/8f/9d/3d13596519cfa7207a6f9834f4b082554845eb3cd2684b5f8535d50c7c44/celery-5.6.2.tar.gz", hash = "sha256:4a8921c3fcf2ad76317d3b29020772103581ed2454c4c042cc55dcc43585009b", size = 1718802, upload-time = "2026-01-04T12:35:58.012Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/01/4e/53a125038d6a814491a0ae3457435c13cf8821eb602292cf9db37ce35f62/celery-5.6.0-py3-none-any.whl", hash = "sha256:33cf01477b175017fc8f22c5ee8a65157591043ba8ca78a443fe703aa910f581", size = 444561, upload-time = "2025-11-30T17:39:44.314Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/dd/bd/9ecd619e456ae4ba73b6583cc313f26152afae13e9a82ac4fe7f8856bfd1/celery-5.6.2-py3-none-any.whl", hash = "sha256:3ffafacbe056951b629c7abcf9064c4a2366de0bdfc9fdba421b97ebb68619a5", size = 445502, upload-time = "2026-01-04T12:35:55.894Z" },
|
||||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
@@ -107,11 +107,11 @@ redis = [
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2025.11.12"
|
||||
version = "2026.1.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/8c/58f469717fa48465e4a50c014a0400602d3c437d7c0c468e17ada824da3a/certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316", size = 160538, upload-time = "2025-11-12T02:54:51.517Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120", size = 154268, upload-time = "2026-01-04T02:42:41.825Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload-time = "2025-11-12T02:54:49.735Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c", size = 152900, upload-time = "2026-01-04T02:42:40.15Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -345,101 +345,101 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "coverage"
|
||||
version = "7.13.0"
|
||||
version = "7.13.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b6/45/2c665ca77ec32ad67e25c77daf1cee28ee4558f3bc571cdbaf88a00b9f23/coverage-7.13.0.tar.gz", hash = "sha256:a394aa27f2d7ff9bc04cf703817773a59ad6dfbd577032e690f961d2460ee936", size = 820905, upload-time = "2025-12-08T13:14:38.055Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/23/f9/e92df5e07f3fc8d4c7f9a0f146ef75446bf870351cd37b788cf5897f8079/coverage-7.13.1.tar.gz", hash = "sha256:b7593fe7eb5feaa3fbb461ac79aac9f9fc0387a5ca8080b0c6fe2ca27b091afd", size = 825862, upload-time = "2025-12-28T15:42:56.969Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/db/08/bdd7ccca14096f7eb01412b87ac11e5d16e4cb54b6e328afc9dee8bdaec1/coverage-7.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:02d9fb9eccd48f6843c98a37bd6817462f130b86da8660461e8f5e54d4c06070", size = 217979, upload-time = "2025-12-08T13:12:14.505Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/f0/d1302e3416298a28b5663ae1117546a745d9d19fde7e28402b2c5c3e2109/coverage-7.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:367449cf07d33dc216c083f2036bb7d976c6e4903ab31be400ad74ad9f85ce98", size = 218496, upload-time = "2025-12-08T13:12:16.237Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/07/26/d36c354c8b2a320819afcea6bffe72839efd004b98d1d166b90801d49d57/coverage-7.13.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cdb3c9f8fef0a954c632f64328a3935988d33a6604ce4bf67ec3e39670f12ae5", size = 245237, upload-time = "2025-12-08T13:12:17.858Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/91/52/be5e85631e0eec547873d8b08dd67a5f6b111ecfe89a86e40b89b0c1c61c/coverage-7.13.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d10fd186aac2316f9bbb46ef91977f9d394ded67050ad6d84d94ed6ea2e8e54e", size = 247061, upload-time = "2025-12-08T13:12:19.132Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/45/a5e8fa0caf05fbd8fa0402470377bff09cc1f026d21c05c71e01295e55ab/coverage-7.13.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f88ae3e69df2ab62fb0bc5219a597cb890ba5c438190ffa87490b315190bb33", size = 248928, upload-time = "2025-12-08T13:12:20.702Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/42/ffb5069b6fd1b95fae482e02f3fecf380d437dd5a39bae09f16d2e2e7e01/coverage-7.13.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c4be718e51e86f553bcf515305a158a1cd180d23b72f07ae76d6017c3cc5d791", size = 245931, upload-time = "2025-12-08T13:12:22.243Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/6e/73e809b882c2858f13e55c0c36e94e09ce07e6165d5644588f9517efe333/coverage-7.13.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a00d3a393207ae12f7c49bb1c113190883b500f48979abb118d8b72b8c95c032", size = 246968, upload-time = "2025-12-08T13:12:23.52Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/08/64ebd9e64b6adb8b4a4662133d706fbaccecab972e0b3ccc23f64e2678ad/coverage-7.13.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a7b1cd820e1b6116f92c6128f1188e7afe421c7e1b35fa9836b11444e53ebd9", size = 244972, upload-time = "2025-12-08T13:12:24.781Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/97/f4d27c6fe0cb375a5eced4aabcaef22de74766fb80a3d5d2015139e54b22/coverage-7.13.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:37eee4e552a65866f15dedd917d5e5f3d59805994260720821e2c1b51ac3248f", size = 245241, upload-time = "2025-12-08T13:12:28.041Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/94/42f8ae7f633bf4c118bf1038d80472f9dade88961a466f290b81250f7ab7/coverage-7.13.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:62d7c4f13102148c78d7353c6052af6d899a7f6df66a32bddcc0c0eb7c5326f8", size = 245847, upload-time = "2025-12-08T13:12:29.337Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/2f/6369ca22b6b6d933f4f4d27765d313d8914cc4cce84f82a16436b1a233db/coverage-7.13.0-cp310-cp310-win32.whl", hash = "sha256:24e4e56304fdb56f96f80eabf840eab043b3afea9348b88be680ec5986780a0f", size = 220573, upload-time = "2025-12-08T13:12:30.905Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/dc/a6a741e519acceaeccc70a7f4cfe5d030efc4b222595f0677e101af6f1f3/coverage-7.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:74c136e4093627cf04b26a35dab8cbfc9b37c647f0502fc313376e11726ba303", size = 221509, upload-time = "2025-12-08T13:12:32.09Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/dc/888bf90d8b1c3d0b4020a40e52b9f80957d75785931ec66c7dfaccc11c7d/coverage-7.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0dfa3855031070058add1a59fdfda0192fd3e8f97e7c81de0596c145dea51820", size = 218104, upload-time = "2025-12-08T13:12:33.333Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/ea/069d51372ad9c380214e86717e40d1a743713a2af191cfba30a0911b0a4a/coverage-7.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4fdb6f54f38e334db97f72fa0c701e66d8479af0bc3f9bfb5b90f1c30f54500f", size = 218606, upload-time = "2025-12-08T13:12:34.498Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/09/77b1c3a66c2aa91141b6c4471af98e5b1ed9b9e6d17255da5eb7992299e3/coverage-7.13.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7e442c013447d1d8d195be62852270b78b6e255b79b8675bad8479641e21fd96", size = 248999, upload-time = "2025-12-08T13:12:36.02Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0a/32/2e2f96e9d5691eaf1181d9040f850b8b7ce165ea10810fd8e2afa534cef7/coverage-7.13.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1ed5630d946859de835a85e9a43b721123a8a44ec26e2830b296d478c7fd4259", size = 250925, upload-time = "2025-12-08T13:12:37.221Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/45/b88ddac1d7978859b9a39a8a50ab323186148f1d64bc068f86fc77706321/coverage-7.13.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f15a931a668e58087bc39d05d2b4bf4b14ff2875b49c994bbdb1c2217a8daeb", size = 253032, upload-time = "2025-12-08T13:12:38.763Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/cb/e15513f94c69d4820a34b6bf3d2b1f9f8755fa6021be97c7065442d7d653/coverage-7.13.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:30a3a201a127ea57f7e14ba43c93c9c4be8b7d17a26e03bb49e6966d019eede9", size = 249134, upload-time = "2025-12-08T13:12:40.382Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/09/61/d960ff7dc9e902af3310ce632a875aaa7860f36d2bc8fc8b37ee7c1b82a5/coverage-7.13.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a485ff48fbd231efa32d58f479befce52dcb6bfb2a88bb7bf9a0b89b1bc8030", size = 250731, upload-time = "2025-12-08T13:12:41.992Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/34/c7c72821794afc7c7c2da1db8f00c2c98353078aa7fb6b5ff36aac834b52/coverage-7.13.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:22486cdafba4f9e471c816a2a5745337742a617fef68e890d8baf9f3036d7833", size = 248795, upload-time = "2025-12-08T13:12:43.331Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0a/5b/e0f07107987a43b2def9aa041c614ddb38064cbf294a71ef8c67d43a0cdd/coverage-7.13.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:263c3dbccc78e2e331e59e90115941b5f53e85cfcc6b3b2fbff1fd4e3d2c6ea8", size = 248514, upload-time = "2025-12-08T13:12:44.546Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/c2/c949c5d3b5e9fc6dd79e1b73cdb86a59ef14f3709b1d72bf7668ae12e000/coverage-7.13.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e5330fa0cc1f5c3c4c3bb8e101b742025933e7848989370a1d4c8c5e401ea753", size = 249424, upload-time = "2025-12-08T13:12:45.759Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/11/f1/bbc009abd6537cec0dffb2cc08c17a7f03de74c970e6302db4342a6e05af/coverage-7.13.0-cp311-cp311-win32.whl", hash = "sha256:0f4872f5d6c54419c94c25dd6ae1d015deeb337d06e448cd890a1e89a8ee7f3b", size = 220597, upload-time = "2025-12-08T13:12:47.378Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/f6/d9977f2fb51c10fbaed0718ce3d0a8541185290b981f73b1d27276c12d91/coverage-7.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51a202e0f80f241ccb68e3e26e19ab5b3bf0f813314f2c967642f13ebcf1ddfe", size = 221536, upload-time = "2025-12-08T13:12:48.7Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/ad/3fcf43fd96fb43e337a3073dea63ff148dcc5c41ba7a14d4c7d34efb2216/coverage-7.13.0-cp311-cp311-win_arm64.whl", hash = "sha256:d2a9d7f1c11487b1c69367ab3ac2d81b9b3721f097aa409a3191c3e90f8f3dd7", size = 220206, upload-time = "2025-12-08T13:12:50.365Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/f1/2619559f17f31ba00fc40908efd1fbf1d0a5536eb75dc8341e7d660a08de/coverage-7.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0b3d67d31383c4c68e19a88e28fc4c2e29517580f1b0ebec4a069d502ce1e0bf", size = 218274, upload-time = "2025-12-08T13:12:52.095Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/11/30d71ae5d6e949ff93b2a79a2c1b4822e00423116c5c6edfaeef37301396/coverage-7.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:581f086833d24a22c89ae0fe2142cfaa1c92c930adf637ddf122d55083fb5a0f", size = 218638, upload-time = "2025-12-08T13:12:53.418Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/c2/fce80fc6ded8d77e53207489d6065d0fed75db8951457f9213776615e0f5/coverage-7.13.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0a3a30f0e257df382f5f9534d4ce3d4cf06eafaf5192beb1a7bd066cb10e78fb", size = 250129, upload-time = "2025-12-08T13:12:54.744Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5b/b6/51b5d1eb6fcbb9a1d5d6984e26cbe09018475c2922d554fd724dd0f056ee/coverage-7.13.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:583221913fbc8f53b88c42e8dbb8fca1d0f2e597cb190ce45916662b8b9d9621", size = 252885, upload-time = "2025-12-08T13:12:56.401Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/f8/972a5affea41de798691ab15d023d3530f9f56a72e12e243f35031846ff7/coverage-7.13.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f5d9bd30756fff3e7216491a0d6d520c448d5124d3d8e8f56446d6412499e74", size = 253974, upload-time = "2025-12-08T13:12:57.718Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/56/116513aee860b2c7968aa3506b0f59b22a959261d1dbf3aea7b4450a7520/coverage-7.13.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a23e5a1f8b982d56fa64f8e442e037f6ce29322f1f9e6c2344cd9e9f4407ee57", size = 250538, upload-time = "2025-12-08T13:12:59.254Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/75/074476d64248fbadf16dfafbf93fdcede389ec821f74ca858d7c87d2a98c/coverage-7.13.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9b01c22bc74a7fb44066aaf765224c0d933ddf1f5047d6cdfe4795504a4493f8", size = 251912, upload-time = "2025-12-08T13:13:00.604Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/d2/aa4f8acd1f7c06024705c12609d8698c51b27e4d635d717cd1934c9668e2/coverage-7.13.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:898cce66d0836973f48dda4e3514d863d70142bdf6dfab932b9b6a90ea5b222d", size = 250054, upload-time = "2025-12-08T13:13:01.892Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/98/8df9e1af6a493b03694a1e8070e024e7d2cdc77adedc225a35e616d505de/coverage-7.13.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:3ab483ea0e251b5790c2aac03acde31bff0c736bf8a86829b89382b407cd1c3b", size = 249619, upload-time = "2025-12-08T13:13:03.236Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/71/f8679231f3353018ca66ef647fa6fe7b77e6bff7845be54ab84f86233363/coverage-7.13.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1d84e91521c5e4cb6602fe11ece3e1de03b2760e14ae4fcf1a4b56fa3c801fcd", size = 251496, upload-time = "2025-12-08T13:13:04.511Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/86/9cb406388034eaf3c606c22094edbbb82eea1fa9d20c0e9efadff20d0733/coverage-7.13.0-cp312-cp312-win32.whl", hash = "sha256:193c3887285eec1dbdb3f2bd7fbc351d570ca9c02ca756c3afbc71b3c98af6ef", size = 220808, upload-time = "2025-12-08T13:13:06.422Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/59/af483673df6455795daf5f447c2f81a3d2fcfc893a22b8ace983791f6f34/coverage-7.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:4f3e223b2b2db5e0db0c2b97286aba0036ca000f06aca9b12112eaa9af3d92ae", size = 221616, upload-time = "2025-12-08T13:13:07.95Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/b0/959d582572b30a6830398c60dd419c1965ca4b5fb38ac6b7093a0d50ca8d/coverage-7.13.0-cp312-cp312-win_arm64.whl", hash = "sha256:086cede306d96202e15a4b77ace8472e39d9f4e5f9fd92dd4fecdfb2313b2080", size = 220261, upload-time = "2025-12-08T13:13:09.581Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/cc/bce226595eb3bf7d13ccffe154c3c487a22222d87ff018525ab4dd2e9542/coverage-7.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:28ee1c96109974af104028a8ef57cec21447d42d0e937c0275329272e370ebcf", size = 218297, upload-time = "2025-12-08T13:13:10.977Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/9f/73c4d34600aae03447dff3d7ad1d0ac649856bfb87d1ca7d681cfc913f9e/coverage-7.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d1e97353dcc5587b85986cda4ff3ec98081d7e84dd95e8b2a6d59820f0545f8a", size = 218673, upload-time = "2025-12-08T13:13:12.562Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/63/ab/8fa097db361a1e8586535ae5073559e6229596b3489ec3ef2f5b38df8cb2/coverage-7.13.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:99acd4dfdfeb58e1937629eb1ab6ab0899b131f183ee5f23e0b5da5cba2fec74", size = 249652, upload-time = "2025-12-08T13:13:13.909Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/90/3a/9bfd4de2ff191feb37ef9465855ca56a6f2f30a3bca172e474130731ac3d/coverage-7.13.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ff45e0cd8451e293b63ced93161e189780baf444119391b3e7d25315060368a6", size = 252251, upload-time = "2025-12-08T13:13:15.553Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/61/b5d8105f016e1b5874af0d7c67542da780ccd4a5f2244a433d3e20ceb1ad/coverage-7.13.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f4f72a85316d8e13234cafe0a9f81b40418ad7a082792fa4165bd7d45d96066b", size = 253492, upload-time = "2025-12-08T13:13:16.849Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/b8/0fad449981803cc47a4694768b99823fb23632150743f9c83af329bb6090/coverage-7.13.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:11c21557d0e0a5a38632cbbaca5f008723b26a89d70db6315523df6df77d6232", size = 249850, upload-time = "2025-12-08T13:13:18.142Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/e9/8d68337c3125014d918cf4327d5257553a710a2995a6a6de2ac77e5aa429/coverage-7.13.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:76541dc8d53715fb4f7a3a06b34b0dc6846e3c69bc6204c55653a85dd6220971", size = 251633, upload-time = "2025-12-08T13:13:19.56Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/55/14/d4112ab26b3a1bc4b3c1295d8452dcf399ed25be4cf649002fb3e64b2d93/coverage-7.13.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6e9e451dee940a86789134b6b0ffbe31c454ade3b849bb8a9d2cca2541a8e91d", size = 249586, upload-time = "2025-12-08T13:13:20.883Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/a9/22b0000186db663b0d82f86c2f1028099ae9ac202491685051e2a11a5218/coverage-7.13.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:5c67dace46f361125e6b9cace8fe0b729ed8479f47e70c89b838d319375c8137", size = 249412, upload-time = "2025-12-08T13:13:22.22Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a1/2e/42d8e0d9e7527fba439acdc6ed24a2b97613b1dc85849b1dd935c2cffef0/coverage-7.13.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f59883c643cb19630500f57016f76cfdcd6845ca8c5b5ea1f6e17f74c8e5f511", size = 251191, upload-time = "2025-12-08T13:13:23.899Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/af/8c7af92b1377fd8860536aadd58745119252aaaa71a5213e5a8e8007a9f5/coverage-7.13.0-cp313-cp313-win32.whl", hash = "sha256:58632b187be6f0be500f553be41e277712baa278147ecb7559983c6d9faf7ae1", size = 220829, upload-time = "2025-12-08T13:13:25.182Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/58/f9/725e8bf16f343d33cbe076c75dc8370262e194ff10072c0608b8e5cf33a3/coverage-7.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:73419b89f812f498aca53f757dd834919b48ce4799f9d5cad33ca0ae442bdb1a", size = 221640, upload-time = "2025-12-08T13:13:26.836Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/ff/e98311000aa6933cc79274e2b6b94a2fe0fe3434fca778eba82003675496/coverage-7.13.0-cp313-cp313-win_arm64.whl", hash = "sha256:eb76670874fdd6091eedcc856128ee48c41a9bbbb9c3f1c7c3cf169290e3ffd6", size = 220269, upload-time = "2025-12-08T13:13:28.116Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cf/cf/bbaa2e1275b300343ea865f7d424cc0a2e2a1df6925a070b2b2d5d765330/coverage-7.13.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:6e63ccc6e0ad8986386461c3c4b737540f20426e7ec932f42e030320896c311a", size = 218990, upload-time = "2025-12-08T13:13:29.463Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/21/1d/82f0b3323b3d149d7672e7744c116e9c170f4957e0c42572f0366dbb4477/coverage-7.13.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:494f5459ffa1bd45e18558cd98710c36c0b8fbfa82a5eabcbe671d80ecffbfe8", size = 219340, upload-time = "2025-12-08T13:13:31.524Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/e3/fe3fd4702a3832a255f4d43013eacb0ef5fc155a5960ea9269d8696db28b/coverage-7.13.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:06cac81bf10f74034e055e903f5f946e3e26fc51c09fc9f584e4a1605d977053", size = 260638, upload-time = "2025-12-08T13:13:32.965Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/01/63186cb000307f2b4da463f72af9b85d380236965574c78e7e27680a2593/coverage-7.13.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f2ffc92b46ed6e6760f1d47a71e56b5664781bc68986dbd1836b2b70c0ce2071", size = 262705, upload-time = "2025-12-08T13:13:34.378Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/a1/c0dacef0cc865f2455d59eed3548573ce47ed603205ffd0735d1d78b5906/coverage-7.13.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0602f701057c6823e5db1b74530ce85f17c3c5be5c85fc042ac939cbd909426e", size = 265125, upload-time = "2025-12-08T13:13:35.73Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/92/82b99223628b61300bd382c205795533bed021505eab6dd86e11fb5d7925/coverage-7.13.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:25dc33618d45456ccb1d37bce44bc78cf269909aa14c4db2e03d63146a8a1493", size = 259844, upload-time = "2025-12-08T13:13:37.69Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cf/2c/89b0291ae4e6cd59ef042708e1c438e2290f8c31959a20055d8768349ee2/coverage-7.13.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:71936a8b3b977ddd0b694c28c6a34f4fff2e9dd201969a4ff5d5fc7742d614b0", size = 262700, upload-time = "2025-12-08T13:13:39.525Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/f9/a5f992efae1996245e796bae34ceb942b05db275e4b34222a9a40b9fbd3b/coverage-7.13.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:936bc20503ce24770c71938d1369461f0c5320830800933bc3956e2a4ded930e", size = 260321, upload-time = "2025-12-08T13:13:41.172Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4c/89/a29f5d98c64fedbe32e2ac3c227fbf78edc01cc7572eee17d61024d89889/coverage-7.13.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:af0a583efaacc52ae2521f8d7910aff65cdb093091d76291ac5820d5e947fc1c", size = 259222, upload-time = "2025-12-08T13:13:43.282Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/c3/940fe447aae302a6701ee51e53af7e08b86ff6eed7631e5740c157ee22b9/coverage-7.13.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f1c23e24a7000da892a312fb17e33c5f94f8b001de44b7cf8ba2e36fbd15859e", size = 261411, upload-time = "2025-12-08T13:13:44.72Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/31/12a4aec689cb942a89129587860ed4d0fd522d5fda81237147fde554b8ae/coverage-7.13.0-cp313-cp313t-win32.whl", hash = "sha256:5f8a0297355e652001015e93be345ee54393e45dc3050af4a0475c5a2b767d46", size = 221505, upload-time = "2025-12-08T13:13:46.332Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/65/8c/3b5fe3259d863572d2b0827642c50c3855d26b3aefe80bdc9eba1f0af3b0/coverage-7.13.0-cp313-cp313t-win_amd64.whl", hash = "sha256:6abb3a4c52f05e08460bd9acf04fec027f8718ecaa0d09c40ffbc3fbd70ecc39", size = 222569, upload-time = "2025-12-08T13:13:47.79Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/39/f71fa8316a96ac72fc3908839df651e8eccee650001a17f2c78cdb355624/coverage-7.13.0-cp313-cp313t-win_arm64.whl", hash = "sha256:3ad968d1e3aa6ce5be295ab5fe3ae1bf5bb4769d0f98a80a0252d543a2ef2e9e", size = 220841, upload-time = "2025-12-08T13:13:49.243Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/4b/9b54bedda55421449811dcd5263a2798a63f48896c24dfb92b0f1b0845bd/coverage-7.13.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:453b7ec753cf5e4356e14fe858064e5520c460d3bbbcb9c35e55c0d21155c256", size = 218343, upload-time = "2025-12-08T13:13:50.811Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/59/df/c3a1f34d4bba2e592c8979f924da4d3d4598b0df2392fbddb7761258e3dc/coverage-7.13.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:af827b7cbb303e1befa6c4f94fd2bf72f108089cfa0f8abab8f4ca553cf5ca5a", size = 218672, upload-time = "2025-12-08T13:13:52.284Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/07/62/eec0659e47857698645ff4e6ad02e30186eb8afd65214fd43f02a76537cb/coverage-7.13.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9987a9e4f8197a1000280f7cc089e3ea2c8b3c0a64d750537809879a7b4ceaf9", size = 249715, upload-time = "2025-12-08T13:13:53.791Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/2d/3c7ff8b2e0e634c1f58d095f071f52ed3c23ff25be524b0ccae8b71f99f8/coverage-7.13.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3188936845cd0cb114fa6a51842a304cdbac2958145d03be2377ec41eb285d19", size = 252225, upload-time = "2025-12-08T13:13:55.274Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/ac/fb03b469d20e9c9a81093575003f959cf91a4a517b783aab090e4538764b/coverage-7.13.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2bdb3babb74079f021696cb46b8bb5f5661165c385d3a238712b031a12355be", size = 253559, upload-time = "2025-12-08T13:13:57.161Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/29/62/14afa9e792383c66cc0a3b872a06ded6e4ed1079c7d35de274f11d27064e/coverage-7.13.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7464663eaca6adba4175f6c19354feea61ebbdd735563a03d1e472c7072d27bb", size = 249724, upload-time = "2025-12-08T13:13:58.692Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/b7/333f3dab2939070613696ab3ee91738950f0467778c6e5a5052e840646b7/coverage-7.13.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8069e831f205d2ff1f3d355e82f511eb7c5522d7d413f5db5756b772ec8697f8", size = 251582, upload-time = "2025-12-08T13:14:00.642Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/81/cb/69162bda9381f39b2287265d7e29ee770f7c27c19f470164350a38318764/coverage-7.13.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:6fb2d5d272341565f08e962cce14cdf843a08ac43bd621783527adb06b089c4b", size = 249538, upload-time = "2025-12-08T13:14:02.556Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e0/76/350387b56a30f4970abe32b90b2a434f87d29f8b7d4ae40d2e8a85aacfb3/coverage-7.13.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:5e70f92ef89bac1ac8a99b3324923b4749f008fdbd7aa9cb35e01d7a284a04f9", size = 249349, upload-time = "2025-12-08T13:14:04.015Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/0d/7f6c42b8d59f4c7e43ea3059f573c0dcfed98ba46eb43c68c69e52ae095c/coverage-7.13.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4b5de7d4583e60d5fd246dd57fcd3a8aa23c6e118a8c72b38adf666ba8e7e927", size = 251011, upload-time = "2025-12-08T13:14:05.505Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/f1/4bb2dff379721bb0b5c649d5c5eaf438462cad824acf32eb1b7ca0c7078e/coverage-7.13.0-cp314-cp314-win32.whl", hash = "sha256:a6c6e16b663be828a8f0b6c5027d36471d4a9f90d28444aa4ced4d48d7d6ae8f", size = 221091, upload-time = "2025-12-08T13:14:07.127Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/44/c239da52f373ce379c194b0ee3bcc121020e397242b85f99e0afc8615066/coverage-7.13.0-cp314-cp314-win_amd64.whl", hash = "sha256:0900872f2fdb3ee5646b557918d02279dc3af3dfb39029ac4e945458b13f73bc", size = 221904, upload-time = "2025-12-08T13:14:08.542Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/1f/b9f04016d2a29c2e4a0307baefefad1a4ec5724946a2b3e482690486cade/coverage-7.13.0-cp314-cp314-win_arm64.whl", hash = "sha256:3a10260e6a152e5f03f26db4a407c4c62d3830b9af9b7c0450b183615f05d43b", size = 220480, upload-time = "2025-12-08T13:14:10.958Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/d4/364a1439766c8e8647860584171c36010ca3226e6e45b1753b1b249c5161/coverage-7.13.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:9097818b6cc1cfb5f174e3263eba4a62a17683bcfe5c4b5d07f4c97fa51fbf28", size = 219074, upload-time = "2025-12-08T13:14:13.345Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/f4/71ba8be63351e099911051b2089662c03d5671437a0ec2171823c8e03bec/coverage-7.13.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0018f73dfb4301a89292c73be6ba5f58722ff79f51593352759c1790ded1cabe", size = 219342, upload-time = "2025-12-08T13:14:15.02Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/25/127d8ed03d7711a387d96f132589057213e3aef7475afdaa303412463f22/coverage-7.13.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:166ad2a22ee770f5656e1257703139d3533b4a0b6909af67c6b4a3adc1c98657", size = 260713, upload-time = "2025-12-08T13:14:16.907Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/db/559fbb6def07d25b2243663b46ba9eb5a3c6586c0c6f4e62980a68f0ee1c/coverage-7.13.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f6aaef16d65d1787280943f1c8718dc32e9cf141014e4634d64446702d26e0ff", size = 262825, upload-time = "2025-12-08T13:14:18.68Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/37/99/6ee5bf7eff884766edb43bd8736b5e1c5144d0fe47498c3779326fe75a35/coverage-7.13.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e999e2dcc094002d6e2c7bbc1fb85b58ba4f465a760a8014d97619330cdbbbf3", size = 265233, upload-time = "2025-12-08T13:14:20.55Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/90/92f18fe0356ea69e1f98f688ed80cec39f44e9f09a1f26a1bbf017cc67f2/coverage-7.13.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:00c3d22cf6fb1cf3bf662aaaa4e563be8243a5ed2630339069799835a9cc7f9b", size = 259779, upload-time = "2025-12-08T13:14:22.367Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/90/5d/b312a8b45b37a42ea7d27d7d3ff98ade3a6c892dd48d1d503e773503373f/coverage-7.13.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22ccfe8d9bb0d6134892cbe1262493a8c70d736b9df930f3f3afae0fe3ac924d", size = 262700, upload-time = "2025-12-08T13:14:24.309Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/63/f8/b1d0de5c39351eb71c366f872376d09386640840a2e09b0d03973d791e20/coverage-7.13.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:9372dff5ea15930fea0445eaf37bbbafbc771a49e70c0aeed8b4e2c2614cc00e", size = 260302, upload-time = "2025-12-08T13:14:26.068Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/7c/d42f4435bc40c55558b3109a39e2d456cddcec37434f62a1f1230991667a/coverage-7.13.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:69ac2c492918c2461bc6ace42d0479638e60719f2a4ef3f0815fa2df88e9f940", size = 259136, upload-time = "2025-12-08T13:14:27.604Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/d3/23413241dc04d47cfe19b9a65b32a2edd67ecd0b817400c2843ebc58c847/coverage-7.13.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:739c6c051a7540608d097b8e13c76cfa85263ced467168dc6b477bae3df7d0e2", size = 261467, upload-time = "2025-12-08T13:14:29.09Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/e6/6e063174500eee216b96272c0d1847bf215926786f85c2bd024cf4d02d2f/coverage-7.13.0-cp314-cp314t-win32.whl", hash = "sha256:fe81055d8c6c9de76d60c94ddea73c290b416e061d40d542b24a5871bad498b7", size = 221875, upload-time = "2025-12-08T13:14:31.106Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/46/f4fb293e4cbe3620e3ac2a3e8fd566ed33affb5861a9b20e3dd6c1896cbc/coverage-7.13.0-cp314-cp314t-win_amd64.whl", hash = "sha256:445badb539005283825959ac9fa4a28f712c214b65af3a2c464f1adc90f5fcbc", size = 222982, upload-time = "2025-12-08T13:14:33.1Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/62/5b3b9018215ed9733fbd1ae3b2ed75c5de62c3b55377a52cae732e1b7805/coverage-7.13.0-cp314-cp314t-win_arm64.whl", hash = "sha256:de7f6748b890708578fc4b7bb967d810aeb6fcc9bff4bb77dbca77dab2f9df6a", size = 221016, upload-time = "2025-12-08T13:14:34.601Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/4c/1968f32fb9a2604645827e11ff84a31e59d532e01995f904723b4f5328b3/coverage-7.13.0-py3-none-any.whl", hash = "sha256:850d2998f380b1e266459ca5b47bc9e7daf9af1d070f66317972f382d46f1904", size = 210068, upload-time = "2025-12-08T13:14:36.236Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2d/9a/3742e58fd04b233df95c012ee9f3dfe04708a5e1d32613bd2d47d4e1be0d/coverage-7.13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e1fa280b3ad78eea5be86f94f461c04943d942697e0dac889fa18fff8f5f9147", size = 218633, upload-time = "2025-12-28T15:40:10.165Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/45/7e6bdc94d89cd7c8017ce735cf50478ddfe765d4fbf0c24d71d30ea33d7a/coverage-7.13.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c3d8c679607220979434f494b139dfb00131ebf70bb406553d69c1ff01a5c33d", size = 219147, upload-time = "2025-12-28T15:40:12.069Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f7/38/0d6a258625fd7f10773fe94097dc16937a5f0e3e0cdf3adef67d3ac6baef/coverage-7.13.1-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:339dc63b3eba969067b00f41f15ad161bf2946613156fb131266d8debc8e44d0", size = 245894, upload-time = "2025-12-28T15:40:13.556Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/27/58/409d15ea487986994cbd4d06376e9860e9b157cfbfd402b1236770ab8dd2/coverage-7.13.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:db622b999ffe49cb891f2fff3b340cdc2f9797d01a0a202a0973ba2562501d90", size = 247721, upload-time = "2025-12-28T15:40:15.37Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/da/bf/6e8056a83fd7a96c93341f1ffe10df636dd89f26d5e7b9ca511ce3bcf0df/coverage-7.13.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1443ba9acbb593fa7c1c29e011d7c9761545fe35e7652e85ce7f51a16f7e08d", size = 249585, upload-time = "2025-12-28T15:40:17.226Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/15/e1daff723f9f5959acb63cbe35b11203a9df77ee4b95b45fffd38b318390/coverage-7.13.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c832ec92c4499ac463186af72f9ed4d8daec15499b16f0a879b0d1c8e5cf4a3b", size = 246597, upload-time = "2025-12-28T15:40:19.028Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/74/a6/1efd31c5433743a6ddbc9d37ac30c196bb07c7eab3d74fbb99b924c93174/coverage-7.13.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:562ec27dfa3f311e0db1ba243ec6e5f6ab96b1edfcfc6cf86f28038bc4961ce6", size = 247626, upload-time = "2025-12-28T15:40:20.846Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/9f/1609267dd3e749f57fdd66ca6752567d1c13b58a20a809dc409b263d0b5f/coverage-7.13.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4de84e71173d4dada2897e5a0e1b7877e5eefbfe0d6a44edee6ce31d9b8ec09e", size = 245629, upload-time = "2025-12-28T15:40:22.397Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/f6/6815a220d5ec2466383d7cc36131b9fa6ecbe95c50ec52a631ba733f306a/coverage-7.13.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:a5a68357f686f8c4d527a2dc04f52e669c2fc1cbde38f6f7eb6a0e58cbd17cae", size = 245901, upload-time = "2025-12-28T15:40:23.836Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/58/40576554cd12e0872faf6d2c0eb3bc85f71d78427946ddd19ad65201e2c0/coverage-7.13.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:77cc258aeb29a3417062758975521eae60af6f79e930d6993555eeac6a8eac29", size = 246505, upload-time = "2025-12-28T15:40:25.421Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/77/9233a90253fba576b0eee81707b5781d0e21d97478e5377b226c5b096c0f/coverage-7.13.1-cp310-cp310-win32.whl", hash = "sha256:bb4f8c3c9a9f34423dba193f241f617b08ffc63e27f67159f60ae6baf2dcfe0f", size = 221257, upload-time = "2025-12-28T15:40:27.217Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e0/43/e842ff30c1a0a623ec80db89befb84a3a7aad7bfe44a6ea77d5a3e61fedd/coverage-7.13.1-cp310-cp310-win_amd64.whl", hash = "sha256:c8e2706ceb622bc63bac98ebb10ef5da80ed70fbd8a7999a5076de3afaef0fb1", size = 222191, upload-time = "2025-12-28T15:40:28.916Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/9b/77baf488516e9ced25fc215a6f75d803493fc3f6a1a1227ac35697910c2a/coverage-7.13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a55d509a1dc5a5b708b5dad3b5334e07a16ad4c2185e27b40e4dba796ab7f88", size = 218755, upload-time = "2025-12-28T15:40:30.812Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/cd/7ab01154e6eb79ee2fab76bf4d89e94c6648116557307ee4ebbb85e5c1bf/coverage-7.13.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4d010d080c4888371033baab27e47c9df7d6fb28d0b7b7adf85a4a49be9298b3", size = 219257, upload-time = "2025-12-28T15:40:32.333Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/01/d5/b11ef7863ffbbdb509da0023fad1e9eda1c0eaea61a6d2ea5b17d4ac706e/coverage-7.13.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d938b4a840fb1523b9dfbbb454f652967f18e197569c32266d4d13f37244c3d9", size = 249657, upload-time = "2025-12-28T15:40:34.1Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f7/7c/347280982982383621d29b8c544cf497ae07ac41e44b1ca4903024131f55/coverage-7.13.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bf100a3288f9bb7f919b87eb84f87101e197535b9bd0e2c2b5b3179633324fee", size = 251581, upload-time = "2025-12-28T15:40:36.131Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/f6/ebcfed11036ade4c0d75fa4453a6282bdd225bc073862766eec184a4c643/coverage-7.13.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef6688db9bf91ba111ae734ba6ef1a063304a881749726e0d3575f5c10a9facf", size = 253691, upload-time = "2025-12-28T15:40:37.626Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/92/af8f5582787f5d1a8b130b2dcba785fa5e9a7a8e121a0bb2220a6fdbdb8a/coverage-7.13.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0b609fc9cdbd1f02e51f67f51e5aee60a841ef58a68d00d5ee2c0faf357481a3", size = 249799, upload-time = "2025-12-28T15:40:39.47Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/24/aa/0e39a2a3b16eebf7f193863323edbff38b6daba711abaaf807d4290cf61a/coverage-7.13.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c43257717611ff5e9a1d79dce8e47566235ebda63328718d9b65dd640bc832ef", size = 251389, upload-time = "2025-12-28T15:40:40.954Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/46/7f0c13111154dc5b978900c0ccee2e2ca239b910890e674a77f1363d483e/coverage-7.13.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e09fbecc007f7b6afdfb3b07ce5bd9f8494b6856dd4f577d26c66c391b829851", size = 249450, upload-time = "2025-12-28T15:40:42.489Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/ca/e80da6769e8b669ec3695598c58eef7ad98b0e26e66333996aee6316db23/coverage-7.13.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:a03a4f3a19a189919c7055098790285cc5c5b0b3976f8d227aea39dbf9f8bfdb", size = 249170, upload-time = "2025-12-28T15:40:44.279Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/18/9e29baabdec1a8644157f572541079b4658199cfd372a578f84228e860de/coverage-7.13.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3820778ea1387c2b6a818caec01c63adc5b3750211af6447e8dcfb9b6f08dbba", size = 250081, upload-time = "2025-12-28T15:40:45.748Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/f8/c3021625a71c3b2f516464d322e41636aea381018319050a8114105872ee/coverage-7.13.1-cp311-cp311-win32.whl", hash = "sha256:ff10896fa55167371960c5908150b434b71c876dfab97b69478f22c8b445ea19", size = 221281, upload-time = "2025-12-28T15:40:47.232Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/27/56/c216625f453df6e0559ed666d246fcbaaa93f3aa99eaa5080cea1229aa3d/coverage-7.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:a998cc0aeeea4c6d5622a3754da5a493055d2d95186bad877b0a34ea6e6dbe0a", size = 222215, upload-time = "2025-12-28T15:40:49.19Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/9a/be342e76f6e531cae6406dc46af0d350586f24d9b67fdfa6daee02df71af/coverage-7.13.1-cp311-cp311-win_arm64.whl", hash = "sha256:fea07c1a39a22614acb762e3fbbb4011f65eedafcb2948feeef641ac78b4ee5c", size = 220886, upload-time = "2025-12-28T15:40:51.067Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/8a/87af46cccdfa78f53db747b09f5f9a21d5fc38d796834adac09b30a8ce74/coverage-7.13.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6f34591000f06e62085b1865c9bc5f7858df748834662a51edadfd2c3bfe0dd3", size = 218927, upload-time = "2025-12-28T15:40:52.814Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/a8/6e22fdc67242a4a5a153f9438d05944553121c8f4ba70cb072af4c41362e/coverage-7.13.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b67e47c5595b9224599016e333f5ec25392597a89d5744658f837d204e16c63e", size = 219288, upload-time = "2025-12-28T15:40:54.262Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/0a/853a76e03b0f7c4375e2ca025df45c918beb367f3e20a0a8e91967f6e96c/coverage-7.13.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3e7b8bd70c48ffb28461ebe092c2345536fb18bbbf19d287c8913699735f505c", size = 250786, upload-time = "2025-12-28T15:40:56.059Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/b4/694159c15c52b9f7ec7adf49d50e5f8ee71d3e9ef38adb4445d13dd56c20/coverage-7.13.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c223d078112e90dc0e5c4e35b98b9584164bea9fbbd221c0b21c5241f6d51b62", size = 253543, upload-time = "2025-12-28T15:40:57.585Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/b2/7f1f0437a5c855f87e17cf5d0dc35920b6440ff2b58b1ba9788c059c26c8/coverage-7.13.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:794f7c05af0763b1bbd1b9e6eff0e52ad068be3b12cd96c87de037b01390c968", size = 254635, upload-time = "2025-12-28T15:40:59.443Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/d1/73c3fdb8d7d3bddd9473c9c6a2e0682f09fc3dfbcb9c3f36412a7368bcab/coverage-7.13.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0642eae483cc8c2902e4af7298bf886d605e80f26382124cddc3967c2a3df09e", size = 251202, upload-time = "2025-12-28T15:41:01.328Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/3c/f0edf75dcc152f145d5598329e864bbbe04ab78660fe3e8e395f9fff010f/coverage-7.13.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9f5e772ed5fef25b3de9f2008fe67b92d46831bd2bc5bdc5dd6bfd06b83b316f", size = 252566, upload-time = "2025-12-28T15:41:03.319Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/17/b3/e64206d3c5f7dcbceafd14941345a754d3dbc78a823a6ed526e23b9cdaab/coverage-7.13.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:45980ea19277dc0a579e432aef6a504fe098ef3a9032ead15e446eb0f1191aee", size = 250711, upload-time = "2025-12-28T15:41:06.411Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/dc/ad/28a3eb970a8ef5b479ee7f0c484a19c34e277479a5b70269dc652b730733/coverage-7.13.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e4f18eca6028ffa62adbd185a8f1e1dd242f2e68164dba5c2b74a5204850b4cf", size = 250278, upload-time = "2025-12-28T15:41:08.285Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/e3/c8f0f1a93133e3e1291ca76cbb63565bd4b5c5df63b141f539d747fff348/coverage-7.13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f8dca5590fec7a89ed6826fce625595279e586ead52e9e958d3237821fbc750c", size = 252154, upload-time = "2025-12-28T15:41:09.969Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/bf/9939c5d6859c380e405b19e736321f1c7d402728792f4c752ad1adcce005/coverage-7.13.1-cp312-cp312-win32.whl", hash = "sha256:ff86d4e85188bba72cfb876df3e11fa243439882c55957184af44a35bd5880b7", size = 221487, upload-time = "2025-12-28T15:41:11.468Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/dc/7282856a407c621c2aad74021680a01b23010bb8ebf427cf5eacda2e876f/coverage-7.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:16cc1da46c04fb0fb128b4dc430b78fa2aba8a6c0c9f8eb391fd5103409a6ac6", size = 222299, upload-time = "2025-12-28T15:41:13.386Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/79/176a11203412c350b3e9578620013af35bcdb79b651eb976f4a4b32044fa/coverage-7.13.1-cp312-cp312-win_arm64.whl", hash = "sha256:8d9bc218650022a768f3775dd7fdac1886437325d8d295d923ebcfef4892ad5c", size = 220941, upload-time = "2025-12-28T15:41:14.975Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/a4/e98e689347a1ff1a7f67932ab535cef82eb5e78f32a9e4132e114bbb3a0a/coverage-7.13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:cb237bfd0ef4d5eb6a19e29f9e528ac67ac3be932ea6b44fb6cc09b9f3ecff78", size = 218951, upload-time = "2025-12-28T15:41:16.653Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/33/7cbfe2bdc6e2f03d6b240d23dc45fdaf3fd270aaf2d640be77b7f16989ab/coverage-7.13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1dcb645d7e34dcbcc96cd7c132b1fc55c39263ca62eb961c064eb3928997363b", size = 219325, upload-time = "2025-12-28T15:41:18.609Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/59/f6/efdabdb4929487baeb7cb2a9f7dac457d9356f6ad1b255be283d58b16316/coverage-7.13.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3d42df8201e00384736f0df9be2ced39324c3907607d17d50d50116c989d84cd", size = 250309, upload-time = "2025-12-28T15:41:20.629Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/da/91a52516e9d5aea87d32d1523f9cdcf7a35a3b298e6be05d6509ba3cfab2/coverage-7.13.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fa3edde1aa8807de1d05934982416cb3ec46d1d4d91e280bcce7cca01c507992", size = 252907, upload-time = "2025-12-28T15:41:22.257Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/38/f1ea837e3dc1231e086db1638947e00d264e7e8c41aa8ecacf6e1e0c05f4/coverage-7.13.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9edd0e01a343766add6817bc448408858ba6b489039eaaa2018474e4001651a4", size = 254148, upload-time = "2025-12-28T15:41:23.87Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/43/f4f16b881aaa34954ba446318dea6b9ed5405dd725dd8daac2358eda869a/coverage-7.13.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:985b7836931d033570b94c94713c6dba5f9d3ff26045f72c3e5dbc5fe3361e5a", size = 250515, upload-time = "2025-12-28T15:41:25.437Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/34/8cba7f00078bd468ea914134e0144263194ce849ec3baad187ffb6203d1c/coverage-7.13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ffed1e4980889765c84a5d1a566159e363b71d6b6fbaf0bebc9d3c30bc016766", size = 252292, upload-time = "2025-12-28T15:41:28.459Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/a4/cffac66c7652d84ee4ac52d3ccb94c015687d3b513f9db04bfcac2ac800d/coverage-7.13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8842af7f175078456b8b17f1b73a0d16a65dcbdc653ecefeb00a56b3c8c298c4", size = 250242, upload-time = "2025-12-28T15:41:30.02Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/78/9a64d462263dde416f3c0067efade7b52b52796f489b1037a95b0dc389c9/coverage-7.13.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:ccd7a6fca48ca9c131d9b0a2972a581e28b13416fc313fb98b6d24a03ce9a398", size = 250068, upload-time = "2025-12-28T15:41:32.007Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/c8/a8994f5fece06db7c4a97c8fc1973684e178599b42e66280dded0524ef00/coverage-7.13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0403f647055de2609be776965108447deb8e384fe4a553c119e3ff6bfbab4784", size = 251846, upload-time = "2025-12-28T15:41:33.946Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cc/f7/91fa73c4b80305c86598a2d4e54ba22df6bf7d0d97500944af7ef155d9f7/coverage-7.13.1-cp313-cp313-win32.whl", hash = "sha256:549d195116a1ba1e1ae2f5ca143f9777800f6636eab917d4f02b5310d6d73461", size = 221512, upload-time = "2025-12-28T15:41:35.519Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/45/0b/0768b4231d5a044da8f75e097a8714ae1041246bb765d6b5563bab456735/coverage-7.13.1-cp313-cp313-win_amd64.whl", hash = "sha256:5899d28b5276f536fcf840b18b61a9fce23cc3aec1d114c44c07fe94ebeaa500", size = 222321, upload-time = "2025-12-28T15:41:37.371Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/b8/bdcb7253b7e85157282450262008f1366aa04663f3e3e4c30436f596c3e2/coverage-7.13.1-cp313-cp313-win_arm64.whl", hash = "sha256:868a2fae76dfb06e87291bcbd4dcbcc778a8500510b618d50496e520bd94d9b9", size = 220949, upload-time = "2025-12-28T15:41:39.553Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/52/f2be52cc445ff75ea8397948c96c1b4ee14f7f9086ea62fc929c5ae7b717/coverage-7.13.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:67170979de0dacac3f3097d02b0ad188d8edcea44ccc44aaa0550af49150c7dc", size = 219643, upload-time = "2025-12-28T15:41:41.567Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/79/c85e378eaa239e2edec0c5523f71542c7793fe3340954eafb0bc3904d32d/coverage-7.13.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f80e2bb21bfab56ed7405c2d79d34b5dc0bc96c2c1d2a067b643a09fb756c43a", size = 219997, upload-time = "2025-12-28T15:41:43.418Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/9b/b1ade8bfb653c0bbce2d6d6e90cc6c254cbb99b7248531cc76253cb4da6d/coverage-7.13.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f83351e0f7dcdb14d7326c3d8d8c4e915fa685cbfdc6281f9470d97a04e9dfe4", size = 261296, upload-time = "2025-12-28T15:41:45.207Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/af/ebf91e3e1a2473d523e87e87fd8581e0aa08741b96265730e2d79ce78d8d/coverage-7.13.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bb3f6562e89bad0110afbe64e485aac2462efdce6232cdec7862a095dc3412f6", size = 263363, upload-time = "2025-12-28T15:41:47.163Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/8b/fb2423526d446596624ac7fde12ea4262e66f86f5120114c3cfd0bb2befa/coverage-7.13.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77545b5dcda13b70f872c3b5974ac64c21d05e65b1590b441c8560115dc3a0d1", size = 265783, upload-time = "2025-12-28T15:41:49.03Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/26/ef2adb1e22674913b89f0fe7490ecadcef4a71fa96f5ced90c60ec358789/coverage-7.13.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a4d240d260a1aed814790bbe1f10a5ff31ce6c21bc78f0da4a1e8268d6c80dbd", size = 260508, upload-time = "2025-12-28T15:41:51.035Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/7d/f0f59b3404caf662e7b5346247883887687c074ce67ba453ea08c612b1d5/coverage-7.13.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d2287ac9360dec3837bfdad969963a5d073a09a85d898bd86bea82aa8876ef3c", size = 263357, upload-time = "2025-12-28T15:41:52.631Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/b1/29896492b0b1a047604d35d6fa804f12818fa30cdad660763a5f3159e158/coverage-7.13.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:0d2c11f3ea4db66b5cbded23b20185c35066892c67d80ec4be4bab257b9ad1e0", size = 260978, upload-time = "2025-12-28T15:41:54.589Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/48/f2/971de1238a62e6f0a4128d37adadc8bb882ee96afbe03ff1570291754629/coverage-7.13.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:3fc6a169517ca0d7ca6846c3c5392ef2b9e38896f61d615cb75b9e7134d4ee1e", size = 259877, upload-time = "2025-12-28T15:41:56.263Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/fc/0474efcbb590ff8628830e9aaec5f1831594874360e3251f1fdec31d07a3/coverage-7.13.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d10a2ed46386e850bb3de503a54f9fe8192e5917fcbb143bfef653a9355e9a53", size = 262069, upload-time = "2025-12-28T15:41:58.093Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/88/4f/3c159b7953db37a7b44c0eab8a95c37d1aa4257c47b4602c04022d5cb975/coverage-7.13.1-cp313-cp313t-win32.whl", hash = "sha256:75a6f4aa904301dab8022397a22c0039edc1f51e90b83dbd4464b8a38dc87842", size = 222184, upload-time = "2025-12-28T15:41:59.763Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/58/a5/6b57d28f81417f9335774f20679d9d13b9a8fb90cd6160957aa3b54a2379/coverage-7.13.1-cp313-cp313t-win_amd64.whl", hash = "sha256:309ef5706e95e62578cda256b97f5e097916a2c26247c287bbe74794e7150df2", size = 223250, upload-time = "2025-12-28T15:42:01.52Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/81/7c/160796f3b035acfbb58be80e02e484548595aa67e16a6345e7910ace0a38/coverage-7.13.1-cp313-cp313t-win_arm64.whl", hash = "sha256:92f980729e79b5d16d221038dbf2e8f9a9136afa072f9d5d6ed4cb984b126a09", size = 221521, upload-time = "2025-12-28T15:42:03.275Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/8e/ba0e597560c6563fc0adb902fda6526df5d4aa73bb10adf0574d03bd2206/coverage-7.13.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:97ab3647280d458a1f9adb85244e81587505a43c0c7cff851f5116cd2814b894", size = 218996, upload-time = "2025-12-28T15:42:04.978Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/8e/764c6e116f4221dc7aa26c4061181ff92edb9c799adae6433d18eeba7a14/coverage-7.13.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8f572d989142e0908e6acf57ad1b9b86989ff057c006d13b76c146ec6a20216a", size = 219326, upload-time = "2025-12-28T15:42:06.691Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/a6/6130dc6d8da28cdcbb0f2bf8865aeca9b157622f7c0031e48c6cf9a0e591/coverage-7.13.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d72140ccf8a147e94274024ff6fd8fb7811354cf7ef88b1f0a988ebaa5bc774f", size = 250374, upload-time = "2025-12-28T15:42:08.786Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/2b/783ded568f7cd6b677762f780ad338bf4b4750205860c17c25f7c708995e/coverage-7.13.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d3c9f051b028810f5a87c88e5d6e9af3c0ff32ef62763bf15d29f740453ca909", size = 252882, upload-time = "2025-12-28T15:42:10.515Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cd/b2/9808766d082e6a4d59eb0cc881a57fc1600eb2c5882813eefff8254f71b5/coverage-7.13.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f398ba4df52d30b1763f62eed9de5620dcde96e6f491f4c62686736b155aa6e4", size = 254218, upload-time = "2025-12-28T15:42:12.208Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/ea/52a985bb447c871cb4d2e376e401116520991b597c85afdde1ea9ef54f2c/coverage-7.13.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:132718176cc723026d201e347f800cd1a9e4b62ccd3f82476950834dad501c75", size = 250391, upload-time = "2025-12-28T15:42:14.21Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/1d/125b36cc12310718873cfc8209ecfbc1008f14f4f5fa0662aa608e579353/coverage-7.13.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9e549d642426e3579b3f4b92d0431543b012dcb6e825c91619d4e93b7363c3f9", size = 252239, upload-time = "2025-12-28T15:42:16.292Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/16/10c1c164950cade470107f9f14bbac8485f8fb8515f515fca53d337e4a7f/coverage-7.13.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:90480b2134999301eea795b3a9dbf606c6fbab1b489150c501da84a959442465", size = 250196, upload-time = "2025-12-28T15:42:18.54Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/c6/cd860fac08780c6fd659732f6ced1b40b79c35977c1356344e44d72ba6c4/coverage-7.13.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e825dbb7f84dfa24663dd75835e7257f8882629fc11f03ecf77d84a75134b864", size = 250008, upload-time = "2025-12-28T15:42:20.365Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/3a/a8c58d3d38f82a5711e1e0a67268362af48e1a03df27c03072ac30feefcf/coverage-7.13.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:623dcc6d7a7ba450bbdbeedbaa0c42b329bdae16491af2282f12a7e809be7eb9", size = 251671, upload-time = "2025-12-28T15:42:22.114Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/bc/fd4c1da651d037a1e3d53e8cb3f8182f4b53271ffa9a95a2e211bacc0349/coverage-7.13.1-cp314-cp314-win32.whl", hash = "sha256:6e73ebb44dca5f708dc871fe0b90cf4cff1a13f9956f747cc87b535a840386f5", size = 221777, upload-time = "2025-12-28T15:42:23.919Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/50/71acabdc8948464c17e90b5ffd92358579bd0910732c2a1c9537d7536aa6/coverage-7.13.1-cp314-cp314-win_amd64.whl", hash = "sha256:be753b225d159feb397bd0bf91ae86f689bad0da09d3b301478cd39b878ab31a", size = 222592, upload-time = "2025-12-28T15:42:25.619Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f7/c8/a6fb943081bb0cc926499c7907731a6dc9efc2cbdc76d738c0ab752f1a32/coverage-7.13.1-cp314-cp314-win_arm64.whl", hash = "sha256:228b90f613b25ba0019361e4ab81520b343b622fc657daf7e501c4ed6a2366c0", size = 221169, upload-time = "2025-12-28T15:42:27.629Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/61/d5b7a0a0e0e40d62e59bc8c7aa1afbd86280d82728ba97f0673b746b78e2/coverage-7.13.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:60cfb538fe9ef86e5b2ab0ca8fc8d62524777f6c611dcaf76dc16fbe9b8e698a", size = 219730, upload-time = "2025-12-28T15:42:29.306Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/2c/8881326445fd071bb49514d1ce97d18a46a980712b51fee84f9ab42845b4/coverage-7.13.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:57dfc8048c72ba48a8c45e188d811e5efd7e49b387effc8fb17e97936dde5bf6", size = 220001, upload-time = "2025-12-28T15:42:31.319Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/d7/50de63af51dfa3a7f91cc37ad8fcc1e244b734232fbc8b9ab0f3c834a5cd/coverage-7.13.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3f2f725aa3e909b3c5fdb8192490bdd8e1495e85906af74fe6e34a2a77ba0673", size = 261370, upload-time = "2025-12-28T15:42:32.992Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/2c/d31722f0ec918fd7453b2758312729f645978d212b410cd0f7c2aed88a94/coverage-7.13.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9ee68b21909686eeb21dfcba2c3b81fee70dcf38b140dcd5aa70680995fa3aa5", size = 263485, upload-time = "2025-12-28T15:42:34.759Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/7a/2c114fa5c5fc08ba0777e4aec4c97e0b4a1afcb69c75f1f54cff78b073ab/coverage-7.13.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:724b1b270cb13ea2e6503476e34541a0b1f62280bc997eab443f87790202033d", size = 265890, upload-time = "2025-12-28T15:42:36.517Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/65/d9/f0794aa1c74ceabc780fe17f6c338456bbc4e96bd950f2e969f48ac6fb20/coverage-7.13.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:916abf1ac5cf7eb16bc540a5bf75c71c43a676f5c52fcb9fe75a2bd75fb944e8", size = 260445, upload-time = "2025-12-28T15:42:38.646Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/23/184b22a00d9bb97488863ced9454068c79e413cb23f472da6cbddc6cfc52/coverage-7.13.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:776483fd35b58d8afe3acbd9988d5de592ab6da2d2a865edfdbc9fdb43e7c486", size = 263357, upload-time = "2025-12-28T15:42:40.788Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/bd/58af54c0c9199ea4190284f389005779d7daf7bf3ce40dcd2d2b2f96da69/coverage-7.13.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:b6f3b96617e9852703f5b633ea01315ca45c77e879584f283c44127f0f1ec564", size = 260959, upload-time = "2025-12-28T15:42:42.808Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/2a/6839294e8f78a4891bf1df79d69c536880ba2f970d0ff09e7513d6e352e9/coverage-7.13.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd63e7b74661fed317212fab774e2a648bc4bb09b35f25474f8e3325d2945cd7", size = 259792, upload-time = "2025-12-28T15:42:44.818Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/c3/528674d4623283310ad676c5af7414b9850ab6d55c2300e8aa4b945ec554/coverage-7.13.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:933082f161bbb3e9f90d00990dc956120f608cdbcaeea15c4d897f56ef4fe416", size = 262123, upload-time = "2025-12-28T15:42:47.108Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/06/c5/8c0515692fb4c73ac379d8dc09b18eaf0214ecb76ea6e62467ba7a1556ff/coverage-7.13.1-cp314-cp314t-win32.whl", hash = "sha256:18be793c4c87de2965e1c0f060f03d9e5aff66cfeae8e1dbe6e5b88056ec153f", size = 222562, upload-time = "2025-12-28T15:42:49.144Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/0e/c0a0c4678cb30dac735811db529b321d7e1c9120b79bd728d4f4d6b010e9/coverage-7.13.1-cp314-cp314t-win_amd64.whl", hash = "sha256:0e42e0ec0cd3e0d851cb3c91f770c9301f48647cb2877cb78f74bdaa07639a79", size = 223670, upload-time = "2025-12-28T15:42:51.218Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/5f/b177aa0011f354abf03a8f30a85032686d290fdeed4222b27d36b4372a50/coverage-7.13.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eaecf47ef10c72ece9a2a92118257da87e460e113b83cc0d2905cbbe931792b4", size = 221707, upload-time = "2025-12-28T15:42:53.034Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cc/48/d9f421cb8da5afaa1a64570d9989e00fb7955e6acddc5a12979f7666ef60/coverage-7.13.1-py3-none-any.whl", hash = "sha256:2016745cb3ba554469d02819d78958b571792bb68e31302610e898f80dd3a573", size = 210722, upload-time = "2025-12-28T15:42:54.901Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -534,16 +534,16 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "django"
|
||||
version = "5.2.9"
|
||||
version = "5.2.10"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "asgiref" },
|
||||
{ name = "sqlparse" },
|
||||
{ name = "tzdata", marker = "sys_platform == 'win32'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/eb/1c/188ce85ee380f714b704283013434976df8d3a2df8e735221a02605b6794/django-5.2.9.tar.gz", hash = "sha256:16b5ccfc5e8c27e6c0561af551d2ea32852d7352c67d452ae3e76b4f6b2ca495", size = 10848762, upload-time = "2025-12-02T14:01:08.418Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e6/e5/2671df24bf0ded831768ef79532e5a7922485411a5696f6d979568591a37/django-5.2.10.tar.gz", hash = "sha256:74df100784c288c50a2b5cad59631d71214f40f72051d5af3fdf220c20bdbbbe", size = 10880754, upload-time = "2026-01-06T18:55:26.817Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/17/b0/7f42bfc38b8f19b78546d47147e083ed06e12fc29c42da95655e0962c6c2/django-5.2.9-py3-none-any.whl", hash = "sha256:3a4ea88a70370557ab1930b332fd2887a9f48654261cdffda663fef5976bb00a", size = 8290652, upload-time = "2025-12-02T14:01:03.485Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/de/f1a7cd896daec85832136ab509d9b2a6daed4939dbe26313af3e95fc5f5e/django-5.2.10-py3-none-any.whl", hash = "sha256:cf85067a64250c95d5f9067b056c5eaa80591929f7e16fbcd997746e40d6c45c", size = 8290820, upload-time = "2026-01-06T18:55:20.009Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -558,18 +558,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/a5/24dee73df5206e71020ab5e530b8687fb2073a7c95542d145f6bbaabd86d/django_activity_stream-2.0.0-py3-none-any.whl", hash = "sha256:e7b86e637e419d068d9a5b4f3bacfec5ae231f412c2bda0ad686a1e47d4424ef", size = 50731, upload-time = "2023-10-04T07:51:20.479Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "django-appconf"
|
||||
version = "1.2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "django" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d1/a2/e58bec8d7941b914af52a67c35b5709eceed2caa2848f28437f1666ed668/django_appconf-1.2.0.tar.gz", hash = "sha256:15a88d60dd942d6059f467412fe4581db632ef03018a3c183fb415d6fc9e5cec", size = 16127, upload-time = "2025-11-08T15:46:27.304Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e8/e6/4c34d94dfb74bbcbc489606e61f1924933de30d22c593dd1f429f35fbd7f/django_appconf-1.2.0-py3-none-any.whl", hash = "sha256:b81bce5ef0ceb9d84df48dfb623a32235d941c78cc5e45dbb6947f154ea277f4", size = 6500, upload-time = "2025-11-08T15:46:25.957Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "django-axes"
|
||||
version = "8.0.0"
|
||||
@@ -600,21 +588,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/61/9c/77ca6760f722cb577ae263131274b8a3126c92293d13a144fb8385811f07/django_bootstrap_breadcrumbs2-1.0.0-py3-none-any.whl", hash = "sha256:a8b9b59d8d7487211c642baffef6a071039de55c6f82d050f9e3353c98da60fc", size = 7109, upload-time = "2022-01-29T15:27:12.046Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "django-compressor"
|
||||
version = "4.6.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "django" },
|
||||
{ name = "django-appconf" },
|
||||
{ name = "rcssmin" },
|
||||
{ name = "rjsmin" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/e4/c6d87b1341d744ceafa85eeceb2adabb1c62b795b8207cbc580fb70df8f4/django_compressor-4.6.0.tar.gz", hash = "sha256:c7478feab98f3368780591f9ee28a433350f5277dd28811f7f710f5bc6dff3c0", size = 99735, upload-time = "2025-11-10T13:12:11.439Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d5/9d/9a0ba39f33574994e5b33aea55a68e8fad72b8dd923a82300e4e91774f59/django_compressor-4.6.0-py3-none-any.whl", hash = "sha256:6e7b21020a0d86272c5e37000c33accc4ebeb77394a3dd86d775a09aae7aade4", size = 96828, upload-time = "2025-11-10T13:12:10.001Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "django-cors-headers"
|
||||
version = "4.9.0"
|
||||
@@ -849,14 +822,14 @@ sidecar = [
|
||||
|
||||
[[package]]
|
||||
name = "drf-spectacular-sidecar"
|
||||
version = "2025.12.1"
|
||||
version = "2026.1.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "django" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/5d/9a/5f1a83bd7bb1937a6347e148fbd116195abb16f7179f7c1b34b3ad2befd8/drf_spectacular_sidecar-2025.12.1.tar.gz", hash = "sha256:d25d82ea2e6176ce4583812f73ac9f177dcd56141c11a9e9bf35f1b1878d5044", size = 2460914, upload-time = "2025-12-01T11:26:59.798Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1e/81/c7b0e3ccbd5a039c4f4fcfecf88391a666ca1406a953886e2f39295b1c90/drf_spectacular_sidecar-2026.1.1.tar.gz", hash = "sha256:6f7c173a8ddbbbdafc7a27e028614b65f07a89ca90f996a432d57460463b56be", size = 2468060, upload-time = "2026-01-01T11:27:12.682Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2f/03/0c6d70dcf24c4af0648bd0e8543fb9ad6c1952d9dcf01df729e4f4458d4c/drf_spectacular_sidecar-2025.12.1-py3-none-any.whl", hash = "sha256:dd28870327b92a0e3c9b6809147fd3e74ec449176daeae291af34eda176236c1", size = 2482183, upload-time = "2025-12-01T11:26:58.176Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/db/96/38725edda526f3e9e597f531beeec94b0ef433d9494f06a13b7636eecb6e/drf_spectacular_sidecar-2026.1.1-py3-none-any.whl", hash = "sha256:af8df62f1b594ec280351336d837eaf2402ab25a6bc2a1fad7aee9935821070f", size = 2489520, upload-time = "2026-01-01T11:27:11.056Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1057,11 +1030,11 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "humanize"
|
||||
version = "4.14.0"
|
||||
version = "4.15.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b6/43/50033d25ad96a7f3845f40999b4778f753c3901a11808a584fed7c00d9f5/humanize-4.14.0.tar.gz", hash = "sha256:2fa092705ea640d605c435b1ca82b2866a1b601cdf96f076d70b79a855eba90d", size = 82939, upload-time = "2025-10-15T13:04:51.214Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ba/66/a3921783d54be8a6870ac4ccffcd15c4dc0dd7fcce51c6d63b8c63935276/humanize-4.15.0.tar.gz", hash = "sha256:1dd098483eb1c7ee8e32eb2e99ad1910baefa4b75c3aff3a82f4d78688993b10", size = 83599, upload-time = "2025-12-20T20:16:13.19Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/5b/9512c5fb6c8218332b530f13500c6ff5f3ce3342f35e0dd7be9ac3856fd3/humanize-4.14.0-py3-none-any.whl", hash = "sha256:d57701248d040ad456092820e6fde56c930f17749956ac47f4f655c0c547bfff", size = 132092, upload-time = "2025-10-15T13:04:49.404Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c5/7b/bca5613a0c3b542420cf92bd5e5fb8ebd5435ce1011a091f66bb7693285e/humanize-4.15.0-py3-none-any.whl", hash = "sha256:b1186eb9f5a9749cd9cb8565aee77919dd7c8d076161cf44d70e59e3301e1769", size = 132203, upload-time = "2025-12-20T20:16:11.67Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1115,7 +1088,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "jsonschema"
|
||||
version = "4.25.1"
|
||||
version = "4.26.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "attrs" },
|
||||
@@ -1123,9 +1096,9 @@ dependencies = [
|
||||
{ name = "referencing" },
|
||||
{ name = "rpds-py" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/74/69/f7185de793a29082a9f3c7728268ffb31cb5095131a9c139a74078e27336/jsonschema-4.25.1.tar.gz", hash = "sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85", size = 357342, upload-time = "2025-08-18T17:03:50.038Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/9c/8c95d856233c1f82500c2450b8c68576b4cf1c871db3afac5c34ff84e6fd/jsonschema-4.25.1-py3-none-any.whl", hash = "sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63", size = 90040, upload-time = "2025-08-18T17:03:48.373Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1142,7 +1115,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "kombu"
|
||||
version = "5.6.1"
|
||||
version = "5.6.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "amqp" },
|
||||
@@ -1150,9 +1123,9 @@ dependencies = [
|
||||
{ name = "tzdata" },
|
||||
{ name = "vine" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ac/05/749ada8e51718445d915af13f1d18bc4333848e8faa0cb234028a3328ec8/kombu-5.6.1.tar.gz", hash = "sha256:90f1febb57ad4f53ca327a87598191b2520e0c793c75ea3b88d98e3b111282e4", size = 471548, upload-time = "2025-11-25T11:07:33.504Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b6/a5/607e533ed6c83ae1a696969b8e1c137dfebd5759a2e9682e26ff1b97740b/kombu-5.6.2.tar.gz", hash = "sha256:8060497058066c6f5aed7c26d7cd0d3b574990b09de842a8c5aaed0b92cc5a55", size = 472594, upload-time = "2025-12-29T20:30:07.779Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/14/d6/943cf84117cd9ddecf6e1707a3f712a49fc64abdb8ac31b19132871af1dd/kombu-5.6.1-py3-none-any.whl", hash = "sha256:b69e3f5527ec32fc5196028a36376501682973e9620d6175d1c3d4eaf7e95409", size = 214141, upload-time = "2025-11-25T11:07:31.54Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/0f/834427d8c03ff1d7e867d3db3d176470c64871753252b21b4f4897d1fa45/kombu-5.6.2-py3-none-any.whl", hash = "sha256:efcfc559da324d41d61ca311b0c64965ea35b4c55cc04ee36e55386145dace93", size = 214219, upload-time = "2025-12-29T20:30:05.74Z" },
|
||||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
@@ -1232,11 +1205,11 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "pathspec"
|
||||
version = "0.12.1"
|
||||
version = "1.0.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/4c/b2/bb8e495d5262bfec41ab5cb18f522f1012933347fb5d9e62452d446baca2/pathspec-1.0.3.tar.gz", hash = "sha256:bac5cf97ae2c2876e2d25ebb15078eb04d76e4b98921ee31c6f85ade8b59444d", size = 130841, upload-time = "2026-01-09T15:46:46.009Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/2b/121e912bd60eebd623f873fd090de0e84f322972ab25a7f9044c056804ed/pathspec-1.0.3-py3-none-any.whl", hash = "sha256:e80767021c1cc524aa3fb14bedda9c34406591343cc42797b386ce7b9354fb6c", size = 55021, upload-time = "2026-01-09T15:46:44.652Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1625,56 +1598,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rcssmin"
|
||||
version = "1.2.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/81/af/c9654b4f9b054ec163ed7cb20d8db0e5ae05e2e9ce99a4c11d91a2180b3f/rcssmin-1.2.2.tar.gz", hash = "sha256:806986eaf7414545edc28a1d29523e9560e49e151ff4a337d9d1f0271d6e1cc4", size = 587012, upload-time = "2025-10-12T10:48:08.932Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/6d/962701850f54cd0a5555259c4fe6606e152e5172c988d71a63455c6d6a48/rcssmin-1.2.2-cp310-cp310-manylinux1_i686.whl", hash = "sha256:4f2229ffb96abafd3120006bce9d448eb8dd0331fc30ab203066d8e63d3c7f34", size = 51397, upload-time = "2025-10-12T10:48:17.875Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2d/ce/2fbe738f6956a96c4e54af411a01da3b991885417feffcf11c2b5ffd1a12/rcssmin-1.2.2-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:dce0f0230c6ac8579cf3b1e557ec1699fe0d931e5e64789c48ff76df2957a937", size = 51303, upload-time = "2025-10-12T10:48:18.934Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/5a/9daa32f73c1fefc28ebaa1092d2c28d56b0fe31152d0b661033540232deb/rcssmin-1.2.2-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:292dc265fb95bcd3765040627713db574a96f8d55035b95c7ccdd4c587844d69", size = 49051, upload-time = "2025-10-12T10:48:19.885Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/10/a407b884699cd5e0fc0bbe3e7a9d57e9425dc804067b0b246175509007e4/rcssmin-1.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cf625985ee18bcc554afaae5b42501c71a167cc79ffe8fd782b32bacab2aee68", size = 51744, upload-time = "2025-10-12T10:48:20.966Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6e/ee/4da5450ea5e3e91976e5d669e7e36300bcaba16daa232b88b4f07d1af9b2/rcssmin-1.2.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:1dab9b6b0e667570d4362ced81015e68bf462537dde151f9f908e1d5382fefb7", size = 51525, upload-time = "2025-10-12T10:48:22.06Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/89/6dabbc7e96aaf7a9b3e7c63311c93568d694348be4312ea93b3d4f48c858/rcssmin-1.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ace9b2c30eb02bff32ce5d6657f5ee04ae866e1bc55d3e28009325fc8b62de4e", size = 51336, upload-time = "2025-10-12T10:48:23.274Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/3b/d4db4a2fb0d0033d222b56526bb1935e892e2560516b0378b4ccffec8d9c/rcssmin-1.2.2-cp311-cp311-manylinux1_i686.whl", hash = "sha256:da4801f4f429d66f9922871a7c71dee54c87f0ea5666cae6f1eb84c3fbc4e1f4", size = 49090, upload-time = "2025-10-12T10:48:24.827Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/f3/aeed5758339ccba61a82de12897762bad8f4317883a20de2dcc78842afda/rcssmin-1.2.2-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:e6b5913f3e8cb249044e916bc6ddcb5158815121548686a0fc8e2b8a5961a62e", size = 49368, upload-time = "2025-10-12T10:48:26.237Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/7b/e4206002c8c1bdcac6905ad7b200d62662d20d2b23f3d3e7df4e89447fdd/rcssmin-1.2.2-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:1472a98142d10d6c6772d96424ddcaf99d7e1d3217475f7f28f7d40dd84f24a2", size = 50714, upload-time = "2025-10-12T10:48:27.305Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/7c/e1cd335ce659af50a2c16dad37eee4b166536d73a463cdfeab5bb8e0833b/rcssmin-1.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b6c91878a7e6f708f90c1bbc1a02729f45b2e5dee89045b395e997aa71744ee4", size = 53376, upload-time = "2025-10-12T10:48:28.374Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/0b/9071882a74df398bf40e668a89cf2dd7eb95ff2e02c111c4c156aaad745a/rcssmin-1.2.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:844227668a235451eb544455b911067ba5495d680857d4bad2b0b78878f30a5c", size = 53194, upload-time = "2025-10-12T10:48:29.331Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/03/48/295e57fbb4767226b5231ee99c056eab5447845259e4172e2db76f07c26d/rcssmin-1.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc866e23121bc4e29014b588fb67c8242a80ce053196f511c4c806b30ca6a393", size = 52998, upload-time = "2025-10-12T10:48:30.266Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/5c/29af37ffb21a3069d108902868262b25fbbf731821cf5c7de76bba986dd1/rcssmin-1.2.2-cp312-cp312-manylinux1_i686.whl", hash = "sha256:78249189d39344a1e9d813c51362831537500e104c5bdce4ff24fe59010e9ee1", size = 48819, upload-time = "2025-10-12T10:48:31.3Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/dc/b522a5e1a0a8ef8af50adbb3bdd9f5a059a9890b9fc5ce3f44a37a996a74/rcssmin-1.2.2-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:217efed0dff304d503bf481068ddb13ae72176ed5970f1011fb1a1e379308d9c", size = 49248, upload-time = "2025-10-12T10:48:32.254Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/0b/7c0018793080ed26939d9beaf09591cf58fb9cda3253a891137b841a902a/rcssmin-1.2.2-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:c51aa47b1752ae55ad4cf4332e7316c5206a6a686d65bc15431a6bfea393e665", size = 50723, upload-time = "2025-10-12T10:48:33.398Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/52/b4/c8b0d2588719af2b9c454e6e95f18bd60b0c474da4b65af61bb6457a7555/rcssmin-1.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:354215283f32413ced87b358934ebbb7c5529f51f5d316e80bc2889486d388b3", size = 53302, upload-time = "2025-10-12T10:48:34.452Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/cb/1a8d6ace1ff845d57fa31087510a88dc10ac01cea41317e976bbf2413f91/rcssmin-1.2.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:265b57de87949b505bcd658f4f5bbfc1f077390108cd12e288ba2f7824bee52c", size = 53001, upload-time = "2025-10-12T10:48:35.389Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/25/2d97155edb351a28e5a46a35f7b4e54bfe3933847bd2ba6674216a817d9e/rcssmin-1.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:83ecd3093640d69f7582839788e012ecf9a85faeb95760032626977a7d3904b2", size = 53285, upload-time = "2025-10-12T10:48:36.513Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/ae/3a7911e1c773f3deb039a42588ae6cee59d6bcec07b5081db376677b293a/rcssmin-1.2.2-cp313-cp313-manylinux1_i686.whl", hash = "sha256:e91449b612a08e5e80df3487e941c86e2c73c5088169588c31c382eb94da0521", size = 48764, upload-time = "2025-10-12T10:48:37.45Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/a7/6d311986d76da0a538bae3f584d2b7579dd11648e74f539b177d8af51f6b/rcssmin-1.2.2-cp313-cp313-manylinux1_x86_64.whl", hash = "sha256:20a32c49d65b65c3ac80305d8a31b98f3d92b1b052dd63b57fbebc7003f9ae38", size = 49175, upload-time = "2025-10-12T10:48:39.601Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/9b/ceb12f3397695d075a1f3e12e295d84f021562540a6579144cb985d80ccb/rcssmin-1.2.2-cp313-cp313-manylinux2014_aarch64.whl", hash = "sha256:cd0a5ca4a0fc3b193ab0dcd251bd2463900558108cc4306a5cc4ab77c6bfffde", size = 50675, upload-time = "2025-10-12T10:48:40.664Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/8c/efb41baaea20567fa0c335705bff1f187e35301b684891d26282a16aff1b/rcssmin-1.2.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:2b008aa77a92f9db2d88f7e7ab45b81f37253cb0baafda59dd5b857c2de9b09f", size = 52999, upload-time = "2025-10-12T10:48:41.749Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4d/f6/cf692cca8837375fd21bf31cd134e10684fc11283a68c04160619aa826dc/rcssmin-1.2.2-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:b3843e0501fa45d7c911dd7b3b78fd5f51c8159dd36d780ee12060da2d526aa0", size = 52752, upload-time = "2025-10-12T10:48:42.823Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/fa/5b0f1df380f598a397414dfaba74b05901379918f4d6b1746462190ae011/rcssmin-1.2.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:bb75b0e412a5419d62f39d89d0b3920a6697d2b12c8dad57f8bde1c76332c640", size = 52994, upload-time = "2025-10-12T10:48:44.023Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/df/7157985ff9e2f3fecb15b03370ee0c8de42fd5a07c4b54e0be2c0f3f8133/rcssmin-1.2.2-cp313-cp313t-manylinux1_i686.whl", hash = "sha256:dd192a876a7af9a14628ff20818df80187294db96d86ddccf72371a6ae3e7ce7", size = 51314, upload-time = "2025-10-12T10:48:45.569Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/56/d5/e6c176b8d39faf0fac3a6896022febb00d0ac5c4b99d4924572c579af210/rcssmin-1.2.2-cp313-cp313t-manylinux1_x86_64.whl", hash = "sha256:5724ed426c1444c35584f0bcda43c81ac47da769228722207aea7b8eedf31224", size = 51509, upload-time = "2025-10-12T10:48:47.03Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/3e/493ef8b7ce621b45f1be4505295fe604280918f67a01a28c82f9d0621a3f/rcssmin-1.2.2-cp313-cp313t-manylinux2014_aarch64.whl", hash = "sha256:228cc8d192ba4bd82305c085cbb5594d45d8dc6605d4eddc319543fb9f47b319", size = 52730, upload-time = "2025-10-12T10:48:48.13Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/90/77cf149fac7f247dac530a96beac7c52cea9fab928b5c3e2a45c6da86147/rcssmin-1.2.2-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:714390aac7c4cb611eecc845a5d9bb01495a3c9fccf9d8a2d6aa75a109276f7b", size = 54939, upload-time = "2025-10-12T10:48:49.423Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/35/37/b8347b3a817b99eab9cc987f1090c7192d9d5f077fdc84c04d12f5186b87/rcssmin-1.2.2-cp313-cp313t-musllinux_1_1_i686.whl", hash = "sha256:64ec506fce7a3f1e993f4c4b55c7b3d9ad8259191cf20d986aa1d1a13e920fe8", size = 55108, upload-time = "2025-10-12T10:48:50.463Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/e1/fb555f831d5e5674a91444007434ba85b4ae98cfd97dd7bc9c2962c0f56b/rcssmin-1.2.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:742bb522d1efe0f1d362d81e00b5dc93ca2ddd1e435ed2d921cfa84fbb9f6887", size = 54858, upload-time = "2025-10-12T10:48:51.941Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/40/9c4cb3133f6d4ddfbeada76988a10ff2a974706fd6fcbb97edd8c0f4cc76/rcssmin-1.2.2-cp314-cp314-manylinux1_i686.whl", hash = "sha256:540dd3aa586b5f8f4c4b90db37e6a31c04718cdf90dbe9bec43c3b4dd50519e7", size = 49032, upload-time = "2025-10-12T10:48:53.014Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/07/84/a411a48fd4179a88c68a2ad3649b408fa7887a421d3435c10ae6f5724e3a/rcssmin-1.2.2-cp314-cp314-manylinux1_x86_64.whl", hash = "sha256:6ea38a38eec263858b70bed6715478dcfed7fbc5d63333a8c512631ee22baad9", size = 49497, upload-time = "2025-10-12T10:48:54.009Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a1/32/5663a71a9304e0c9f33b765264508229d026359cfff746e1d0a593d809ea/rcssmin-1.2.2-cp314-cp314-manylinux2014_aarch64.whl", hash = "sha256:07dc7d352e8eb08de82fc4c545dd04f9f487466c8370051e0bee4eb1e4dc85d0", size = 50382, upload-time = "2025-10-12T10:48:55.079Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/28/e411eb191ffff7bd712f2eb0f691cb7ca514b1876d6bff2f5ae61359b8db/rcssmin-1.2.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:cdccb0e08281f0dd5d463c16ec61a06bd1534de50206dc72918be3c10dcb82e5", size = 50962, upload-time = "2025-10-12T10:48:56.494Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/3f/cdb99526d294c5dd4b919dc4ef492b7bd11e08b585d15ec641dfb9423493/rcssmin-1.2.2-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:2b6d5e2e2fd65738d57ef65aaaed2cff2288eccff7f704bf3d579e6f451cb60a", size = 52504, upload-time = "2025-10-12T10:48:57.886Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e8/60/a8183401fa64e93e1d52b2cdf275a2c11e0993f5f3162c573a67872b535d/rcssmin-1.2.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7018d4197713c7797d1a67ed47ab53d4706c2e9ed134123c30a47d389dda5386", size = 50561, upload-time = "2025-10-12T10:48:58.935Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/5e/496d6c9c309e2fe79e6a69f25f7a6d18f545edb4ea3584f461b9f84b0d60/rcssmin-1.2.2-cp314-cp314t-manylinux1_i686.whl", hash = "sha256:0162c32ce946978edc834d4fba705ac5f9422d7f556f3264cc4fc67c7ee39171", size = 51214, upload-time = "2025-10-12T10:49:00.021Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/78/87da6706d5856ceee71421ba831d2f5d93c3e6865acfbb56ace8d54587cc/rcssmin-1.2.2-cp314-cp314t-manylinux1_x86_64.whl", hash = "sha256:f17dc92553a46412c49f972f0ab31088032b9482a9c421bc2d39691a5d8842aa", size = 51608, upload-time = "2025-10-12T10:49:01.422Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cd/6c/204b0262c11ac2da2b8df2d8fed76f1959273fbc8376450d0ac022d754b7/rcssmin-1.2.2-cp314-cp314t-manylinux2014_aarch64.whl", hash = "sha256:40c7dfba098bbd129d8c35dd8b604275585f9dc0496e5d17dbe7fd6b873b0233", size = 53349, upload-time = "2025-10-12T10:49:02.512Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/7b/9aae16756d3f33cbc512760ba3e69c3856a51aa293e463f2ca97760d1b1b/rcssmin-1.2.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d0197fab78ebbe33f5df9caf2572ef2d44bbe243a9130881a0c5c53ba03641fa", size = 53066, upload-time = "2025-10-12T10:49:03.589Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/18/b06fadfa9b85e486bb1571050217cb539c062d1ae4cd32b1a31c36f67fd4/rcssmin-1.2.2-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:19e53c58768369366fdaef00da59f275f724f229994ea885309df6ca368ff3c8", size = 54271, upload-time = "2025-10-12T10:49:04.735Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/55/f29ce21f8e5a1f3c19d43b67b907268d227b7edcda2ca200ca0028734a5e/rcssmin-1.2.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8d3de1a870e00d157f3a7b1797498fdc09a3774629079572350f75783bb94b9a", size = 52423, upload-time = "2025-10-12T10:49:06.04Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redis"
|
||||
version = "6.4.0"
|
||||
@@ -1703,15 +1626,15 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "reportlab"
|
||||
version = "4.4.6"
|
||||
version = "4.4.7"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "charset-normalizer" },
|
||||
{ name = "pillow" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/35/ec/f7a50b3cbee58407090bd1f2a9db2f1a23052c5de3bc7408024ca776ee02/reportlab-4.4.6.tar.gz", hash = "sha256:8792c87c23dd034d17530e6ebe4164d61bcc8f7b0eac203fe13cc03cc2c1c607", size = 3910805, upload-time = "2025-12-10T12:37:21.17Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f8/a7/4600cb1cfc975a06552e8927844ddcb8fd90217e9a6068f5c7aa76c3f221/reportlab-4.4.7.tar.gz", hash = "sha256:41e8287af965e5996764933f3e75e7f363c3b6f252ba172f9429e81658d7b170", size = 3714000, upload-time = "2025-12-21T11:50:11.336Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/ee/5f7a31ab05cf817e0cc70ae6df51a1a4fda188c899790a3131a24dd78d18/reportlab-4.4.6-py3-none-any.whl", hash = "sha256:c7c31d5c815bae7c76fc17f64ffc417e68992901acddb24504296cc39b065424", size = 1954259, upload-time = "2025-12-10T12:37:18.428Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e7/bf/a29507386366ab17306b187ad247dd78e4599be9032cb5f44c940f547fc0/reportlab-4.4.7-py3-none-any.whl", hash = "sha256:8fa05cbf468e0e76745caf2029a4770276edb3c8e86a0b71e0398926baf50673", size = 1954263, upload-time = "2025-12-21T11:50:08.93Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1729,56 +1652,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rjsmin"
|
||||
version = "1.2.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/59/16/14288d309d0f42c6586440c47bf6ec1a880218f698f30293fa3782db4008/rjsmin-1.2.5.tar.gz", hash = "sha256:a3f8040b0273dec773e0e807e86a4d0a9535516c0a0a35aa1bb6de6e15bb1f09", size = 427399, upload-time = "2025-10-12T10:50:27.422Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/dc/1dc7a3ce4d8a5ca864ee6622f90ae8aa205f7398f73a5ce8da6b6fb052af/rjsmin-1.2.5-cp310-cp310-manylinux1_i686.whl", hash = "sha256:4dda87501a36b24c0db3bcfd274f31e04bbe96c9514bb5e168d83923dac56c08", size = 35143, upload-time = "2025-10-12T10:50:35.849Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/0a/0bfb6cfcaeec254901e559c0d5e82854905356b79e845225662980c209dc/rjsmin-1.2.5-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:5b1d470fb25b9485a63dd292f7eefbff1daca3cbc7fec1132d13bc5c3e6a6b35", size = 35156, upload-time = "2025-10-12T10:50:36.84Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/81/a54e7cd4bf6b3089a7dc6f54c827ba06584cfde8b2750fc1046336d3b7c8/rjsmin-1.2.5-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:2af254854f5e06f42c05d2baa0e78742204bbe8891d69dcaba287449a7cd11de", size = 30788, upload-time = "2025-10-12T10:50:37.749Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/8a/8dd2bdb164da59bf2a552a9a46771421e7313dc0da4330350ef161613f34/rjsmin-1.2.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5975cdb5cb38bd8ddd124e9f6b4e9cd25a0e2a4fa0a3cd5604ad349f0317df7f", size = 34437, upload-time = "2025-10-12T10:50:39.03Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/a5/e7ac68344e2ee0b3fc89b4863718771da123797b5fbd954e7abea43d282b/rjsmin-1.2.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4e2ed013704e01b8bbe82eb58f83241c33b198d96fef792f389de415b32af260", size = 34553, upload-time = "2025-10-12T10:50:40.07Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/91/d609e0c91b1a77aab559869cd53d8dc08128e36b2cce55a361d7b53774a8/rjsmin-1.2.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3b64aba17f9caa7d66f6fd9e08d7c2010ece06df2b518e0a48fbdc0482c5f9f9", size = 34451, upload-time = "2025-10-12T10:50:41.07Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/83/30c8a74c3f837d22ac14a20da562f2922cda87228cb88553dbe967f10d89/rjsmin-1.2.5-cp311-cp311-manylinux1_i686.whl", hash = "sha256:82bac9710030b61dd1cf442724431d29b1fec7cd708c541cb2042e38763fd610", size = 31978, upload-time = "2025-10-12T10:50:42.312Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/7c/e215e4e52f4b0f354731bd808292c5cb01c2eeba8cb310e3f099ab97d479/rjsmin-1.2.5-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:5626644872f3ad10b8334ec3383aad0906d36a085c04c608a400ed30be4d03a4", size = 31782, upload-time = "2025-10-12T10:50:43.471Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/e7/d5590391d2c98389ab119e4500a6d96cf6174159295d9a2cc34dec2eb73d/rjsmin-1.2.5-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:2d0b8aaa98e51c8ae176b9a94e91f19d3043d7d328431d3d2c459b57a90c0c87", size = 32369, upload-time = "2025-10-12T10:50:45.222Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/ad/81bcfe46cf42ea3c8a0b9505654f413c06932c8ea43556b83404a016ddb6/rjsmin-1.2.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0df172044912ca2f5f04c711ded75c784fba8dc6c7a1f7f831ac831562102aa2", size = 36091, upload-time = "2025-10-12T10:50:46.243Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/9e/833455223063a52ee0b0aa2cef44080677db840d9fbae5c78f027547af5a/rjsmin-1.2.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a9208911d2f04dc3bec33df7486dbd7ecfc900b0d1ead9841bbd94a382f33f00", size = 36232, upload-time = "2025-10-12T10:50:47.277Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/21/e4ffb7b5c3313f9d5137867f113ec9241b84e50e1d69ce979efdbffe07ed/rjsmin-1.2.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8b7cf8ce9022d381bfa700ae116e5f78698f486558a0fe23c57f158ba3229629", size = 36168, upload-time = "2025-10-12T10:50:48.611Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/f3/143727b02b5c5fdc08335be8b2184f19b762ee7d184bb4459e94ed668ae0/rjsmin-1.2.5-cp312-cp312-manylinux1_i686.whl", hash = "sha256:d8b6ddaaa78fd2d3243da11c13033946d211d37729c64814cefe32dba02d9921", size = 31838, upload-time = "2025-10-12T10:50:49.553Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/dc/72ca27c526925e88e273c3af6848777b289e4eb0854afcd7c6dbbfd4d196/rjsmin-1.2.5-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:2f46270969613de2292a7f747c31cabd9354cc49f6cd23f9cc8688d3af9f889e", size = 31795, upload-time = "2025-10-12T10:50:50.459Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/1e/f8bfe2f6949b31adb66563ceca84d9d38f32867aad303cf4311b12534487/rjsmin-1.2.5-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:6e7b1bb52665894d8cba84144ee91723475948d5d1a54d7f0b25a1cdce8c5921", size = 32085, upload-time = "2025-10-12T10:50:51.704Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/d0/239d16374e9e3e0aba2e4924175f2401f21126a1c2df83f5fb18af3ec808/rjsmin-1.2.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f68dd62707d62fc1771be4407892cb932d48fa19a51e7a0e35a11b00e427e3f7", size = 35995, upload-time = "2025-10-12T10:50:52.714Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/61/179f5ef72a688cf290acdbcdfcbacc4af297751af1b10d4097af03cb31eb/rjsmin-1.2.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:73b6b099f8afb8aa7ff9ddfbfd4d6ae6540dfe7630833a04a26f1d9f67528eaf", size = 36200, upload-time = "2025-10-12T10:50:54.065Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/3b/42bb50ee0bb3a4baa8f435ad6bfca48ed5a5b46e4b614e1f4d320ce729d2/rjsmin-1.2.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:372d57835014a332dbf227b6de284ea3ee052600ab0f176df959c75a33f0690e", size = 36110, upload-time = "2025-10-12T10:50:55.393Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/14/c3/0e1c211625d44f6ccad2286547ec420d07c5ca8a82098795deb2a96467e4/rjsmin-1.2.5-cp313-cp313-manylinux1_i686.whl", hash = "sha256:2967e468df0bedaff71693b96ff42b46805cc7027146323a8e47c85c5ea53ac5", size = 31883, upload-time = "2025-10-12T10:50:56.329Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/49/58c90614c9df3e074be3e5f960cfadc9f9ab501659b7fca3bb8326d27b07/rjsmin-1.2.5-cp313-cp313-manylinux1_x86_64.whl", hash = "sha256:3d68251d1f68c07500f1c062d9dfa16e799f8971aed1312b9584739c03d9f44b", size = 31785, upload-time = "2025-10-12T10:50:57.689Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/88/aa/bfc350c353d2eada2eb125ad13d1d1f5a0f6543a96d0fe8759cd440c1921/rjsmin-1.2.5-cp313-cp313-manylinux2014_aarch64.whl", hash = "sha256:3bce037bc2ed784143f90637230c0dad6b59d18e01d66ec41ab0fc988cb98266", size = 32104, upload-time = "2025-10-12T10:50:58.78Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/fc/eead6c42da1c51d6d3200411debbc5f03bf3e2d5e5061b39e8953484d1b6/rjsmin-1.2.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:d206f730a003cbfc8ba5d70e06e9d20318d5dfc2d9220f6dab4fc708b621de15", size = 35718, upload-time = "2025-10-12T10:51:00.146Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/ec/10537f3280cdb3eb712746677a9601d40760509f876ab107f2cbdcce56c0/rjsmin-1.2.5-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:9ec9e902dfe04e791d056eb649805e4dc8a480c170e296b2dfbffb646425acdd", size = 35980, upload-time = "2025-10-12T10:51:02.53Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/0e/11406ff7c711e3c7d4ec30a2f7998293bf157b9e0451a5f6ce6b8505e1b6/rjsmin-1.2.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7926b946de481766d4da5f669da2e3ce8491e750f32f48745d7413a92c810ead", size = 35869, upload-time = "2025-10-12T10:51:03.616Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/8e/8102b9324a3b1a7ad5262824537ee7dad18325d457ff0b3806c9f88d7bfa/rjsmin-1.2.5-cp313-cp313t-manylinux1_i686.whl", hash = "sha256:57d0935b2675644d80ea33b611d6752a33af8e1a62baa5adff0a0b8d43981732", size = 33656, upload-time = "2025-10-12T10:51:04.656Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/4a/94dbe6a90b9c5ab9dfdcfe2e8ae2c106c990c96f759c6396621eabcfe503/rjsmin-1.2.5-cp313-cp313t-manylinux1_x86_64.whl", hash = "sha256:d283452b6684bd6f422eea783e5f5f16b564727652398bb71ad5adc001613765", size = 33500, upload-time = "2025-10-12T10:51:05.808Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/f7/8f8a6cf1b1394ce61ac0a491dbf22237734d472e80feea715ec1ca580de8/rjsmin-1.2.5-cp313-cp313t-manylinux2014_aarch64.whl", hash = "sha256:8a3c43e43c06afa7e8a36b22a1247ae58d2eebfe0aea7af5cd83f68fd7360ddc", size = 34125, upload-time = "2025-10-12T10:51:06.829Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/b0/7562103d5241a7b57cf93e7047ee00889b67eabb99df0af03105f2224142/rjsmin-1.2.5-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:85aa826fca5aaf6f0f0f287f986e0f79c0f8953bab5090fed17a4f35f7ada65a", size = 37468, upload-time = "2025-10-12T10:51:07.936Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/80/0a56f415aa2d92898388df8447270c3813c13eefdace54d44d12b21aba39/rjsmin-1.2.5-cp313-cp313t-musllinux_1_1_i686.whl", hash = "sha256:d68cb778e25393adb84e1844aac6f132f72055a6cf4463bae560858300ca500c", size = 37850, upload-time = "2025-10-12T10:51:09.28Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bb/eb/9c3dc7763519ed69a50641be920f3f40c286022d7ebd5a62fa4434996806/rjsmin-1.2.5-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:a86825ff7846a5c2f21a71d669b96d1b52237fb668f0243fa4f4f40a2ad93ff7", size = 37645, upload-time = "2025-10-12T10:51:10.304Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/ed/b472d5a3fd7d63c016893f7d438e677901fea28089b5d30cd1a115bcc887/rjsmin-1.2.5-cp314-cp314-manylinux1_i686.whl", hash = "sha256:7096357ed596fdfe0acb750f8cbfca338f3c845cc12def3861e23ed811589d15", size = 31983, upload-time = "2025-10-12T10:51:11.361Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/e8/e76fa527fde17fd08288e4efef25c0aba7979ed5740eeab7bdff507bdeba/rjsmin-1.2.5-cp314-cp314-manylinux1_x86_64.whl", hash = "sha256:4e80b05803749502995fe33b6f5fd589b51dc46e50d873baf0b515c8f6e7b668", size = 32002, upload-time = "2025-10-12T10:51:12.257Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/6c/ee395ef8ee117ba2d158a23a9502bc4a706e02f63bfdf6d01b802ae6ee9a/rjsmin-1.2.5-cp314-cp314-manylinux2014_aarch64.whl", hash = "sha256:b6d0bc092acc3f54ea63ec1dcb808edaac5e956141d89fd0d038e80de5322052", size = 32435, upload-time = "2025-10-12T10:51:13.147Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/78/c157d33aa6148f0e8c57bb91a41969e1a4aab929f3bb0a8d9ff3b5e21556/rjsmin-1.2.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1e2943259be7beafdcb0847c2a901f223bf9044bdfa8105e1be1ad67d6c47795", size = 32877, upload-time = "2025-10-12T10:51:14.545Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/49/6252145bf85d87c815aaf441c5efdf1ce918db5ab6e915cf6d0d99ca3969/rjsmin-1.2.5-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:e0387568c27fb49e55c1d0dfc27b54fc63d04b7756b1fed9743078130262907f", size = 32957, upload-time = "2025-10-12T10:51:15.964Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/15/7e/c321c047b1a2fb7fa5ac818c37c1a15d348e1c12a1148de8ca5192a83b8f/rjsmin-1.2.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8196f1ecb0dff6c8647d4622e496869e94f1be92567ea2e941aa18d49a1a4347", size = 32456, upload-time = "2025-10-12T10:51:16.885Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5b/d7/2d190ce5ad10832df62edd4d9b1ae7092fd259ca58b39a1e202337f511a9/rjsmin-1.2.5-cp314-cp314t-manylinux1_i686.whl", hash = "sha256:9dd9f66568be9c8676278f140aa54102fab9af7feb59adf0c7a85bef49fe70df", size = 34115, upload-time = "2025-10-12T10:51:17.911Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/ab/e7bcf261ede4cef7a0693927d7dcd1612bb59ba6c05191f58a92deec9f01/rjsmin-1.2.5-cp314-cp314t-manylinux1_x86_64.whl", hash = "sha256:5b8f72f7d96e5e1d30a33182cb39d4eb4516ddcd9b2f984813a9eefe66f8e180", size = 33977, upload-time = "2025-10-12T10:51:18.996Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/75/f1ff5f2199437b534204b40aa46c55c703489063cf7806c948a1a665575e/rjsmin-1.2.5-cp314-cp314t-manylinux2014_aarch64.whl", hash = "sha256:8c5906bd8830f616e992ad5e7277d0ea12c530110da188b2b9da23e9524a7cbc", size = 34604, upload-time = "2025-10-12T10:51:20.031Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d2/dc/acd463d88c56476cc683f1c6cce893c590007dccd390747e824b8e923d63/rjsmin-1.2.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8207bac0d3bab7791fd667f0863b5f32e51047845179b94b28c716e6514a9234", size = 34775, upload-time = "2025-10-12T10:51:21.364Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/56/e6f61718d1c36e646aabe552ad1f8f77744a4c57524eaa782b5b44eba220/rjsmin-1.2.5-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:1e3ab93a51d7581ba0a3b6a383df2929b86d9d55f9516764678f9b4e409826e8", size = 34682, upload-time = "2025-10-12T10:51:22.755Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/f3/37a4672ddb1307eb57d9b54ba89a48f483a04a63cac4e1471fdb4cba76e6/rjsmin-1.2.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:47dad1732a2c4779bdc76d5b3183fdf2ec27838f31071fa9dfcc79483d3480e2", size = 34161, upload-time = "2025-10-12T10:51:23.761Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rpds-py"
|
||||
version = "0.30.0"
|
||||
@@ -1903,28 +1776,28 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.14.9"
|
||||
version = "0.14.11"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f6/1b/ab712a9d5044435be8e9a2beb17cbfa4c241aa9b5e4413febac2a8b79ef2/ruff-0.14.9.tar.gz", hash = "sha256:35f85b25dd586381c0cc053f48826109384c81c00ad7ef1bd977bfcc28119d5b", size = 5809165, upload-time = "2025-12-11T21:39:47.381Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d4/77/9a7fe084d268f8855d493e5031ea03fa0af8cc05887f638bf1c4e3363eb8/ruff-0.14.11.tar.gz", hash = "sha256:f6dc463bfa5c07a59b1ff2c3b9767373e541346ea105503b4c0369c520a66958", size = 5993417, upload-time = "2026-01-08T19:11:58.322Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/1c/d1b1bba22cffec02351c78ab9ed4f7d7391876e12720298448b29b7229c1/ruff-0.14.9-py3-none-linux_armv6l.whl", hash = "sha256:f1ec5de1ce150ca6e43691f4a9ef5c04574ad9ca35c8b3b0e18877314aba7e75", size = 13576541, upload-time = "2025-12-11T21:39:14.806Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/ab/ffe580e6ea1fca67f6337b0af59fc7e683344a43642d2d55d251ff83ceae/ruff-0.14.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ed9d7417a299fc6030b4f26333bf1117ed82a61ea91238558c0268c14e00d0c2", size = 13779363, upload-time = "2025-12-11T21:39:20.29Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/f8/2be49047f929d6965401855461e697ab185e1a6a683d914c5c19c7962d9e/ruff-0.14.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d5dc3473c3f0e4a1008d0ef1d75cee24a48e254c8bed3a7afdd2b4392657ed2c", size = 12925292, upload-time = "2025-12-11T21:39:38.757Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/e9/08840ff5127916bb989c86f18924fd568938b06f58b60e206176f327c0fe/ruff-0.14.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84bf7c698fc8f3cb8278830fb6b5a47f9bcc1ed8cb4f689b9dd02698fa840697", size = 13362894, upload-time = "2025-12-11T21:39:02.524Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/1c/5b4e8e7750613ef43390bb58658eaf1d862c0cc3352d139cd718a2cea164/ruff-0.14.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aa733093d1f9d88a5d98988d8834ef5d6f9828d03743bf5e338bf980a19fce27", size = 13311482, upload-time = "2025-12-11T21:39:17.51Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5b/3a/459dce7a8cb35ba1ea3e9c88f19077667a7977234f3b5ab197fad240b404/ruff-0.14.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a1cfb04eda979b20c8c19550c8b5f498df64ff8da151283311ce3199e8b3648", size = 14016100, upload-time = "2025-12-11T21:39:41.948Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/31/f064f4ec32524f9956a0890fc6a944e5cf06c63c554e39957d208c0ffc45/ruff-0.14.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1e5cb521e5ccf0008bd74d5595a4580313844a42b9103b7388eca5a12c970743", size = 15477729, upload-time = "2025-12-11T21:39:23.279Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/6d/f364252aad36ccd443494bc5f02e41bf677f964b58902a17c0b16c53d890/ruff-0.14.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd429a8926be6bba4befa8cdcf3f4dd2591c413ea5066b1e99155ed245ae42bb", size = 15122386, upload-time = "2025-12-11T21:39:33.125Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/20/02/e848787912d16209aba2799a4d5a1775660b6a3d0ab3944a4ccc13e64a02/ruff-0.14.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab208c1b7a492e37caeaf290b1378148f75e13c2225af5d44628b95fd7834273", size = 14497124, upload-time = "2025-12-11T21:38:59.33Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/51/0489a6a5595b7760b5dbac0dd82852b510326e7d88d51dbffcd2e07e3ff3/ruff-0.14.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72034534e5b11e8a593f517b2f2f2b273eb68a30978c6a2d40473ad0aaa4cb4a", size = 14195343, upload-time = "2025-12-11T21:39:44.866Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/53/3bb8d2fa73e4c2f80acc65213ee0830fa0c49c6479313f7a68a00f39e208/ruff-0.14.9-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:712ff04f44663f1b90a1195f51525836e3413c8a773574a7b7775554269c30ed", size = 14346425, upload-time = "2025-12-11T21:39:05.927Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/04/bdb1d0ab876372da3e983896481760867fc84f969c5c09d428e8f01b557f/ruff-0.14.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a111fee1db6f1d5d5810245295527cda1d367c5aa8f42e0fca9a78ede9b4498b", size = 13258768, upload-time = "2025-12-11T21:39:08.691Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/d9/8bf8e1e41a311afd2abc8ad12be1b6c6c8b925506d9069b67bb5e9a04af3/ruff-0.14.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8769efc71558fecc25eb295ddec7d1030d41a51e9dcf127cbd63ec517f22d567", size = 13326939, upload-time = "2025-12-11T21:39:53.842Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/56/a213fa9edb6dd849f1cfbc236206ead10913693c72a67fb7ddc1833bf95d/ruff-0.14.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:347e3bf16197e8a2de17940cd75fd6491e25c0aa7edf7d61aa03f146a1aa885a", size = 13578888, upload-time = "2025-12-11T21:39:35.988Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/33/09/6a4a67ffa4abae6bf44c972a4521337ffce9cbc7808faadede754ef7a79c/ruff-0.14.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7715d14e5bccf5b660f54516558aa94781d3eb0838f8e706fb60e3ff6eff03a8", size = 14314473, upload-time = "2025-12-11T21:39:50.78Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/0d/15cc82da5d83f27a3c6b04f3a232d61bc8c50d38a6cd8da79228e5f8b8d6/ruff-0.14.9-py3-none-win32.whl", hash = "sha256:df0937f30aaabe83da172adaf8937003ff28172f59ca9f17883b4213783df197", size = 13202651, upload-time = "2025-12-11T21:39:26.628Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/f7/c78b060388eefe0304d9d42e68fab8cffd049128ec466456cef9b8d4f06f/ruff-0.14.9-py3-none-win_amd64.whl", hash = "sha256:c0b53a10e61df15a42ed711ec0bda0c582039cf6c754c49c020084c55b5b0bc2", size = 14702079, upload-time = "2025-12-11T21:39:11.954Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/09/7a9520315decd2334afa65ed258fed438f070e31f05a2e43dd480a5e5911/ruff-0.14.9-py3-none-win_arm64.whl", hash = "sha256:8e821c366517a074046d92f0e9213ed1c13dbc5b37a7fc20b07f79b64d62cc84", size = 13744730, upload-time = "2025-12-11T21:39:29.659Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/a6/a4c40a5aaa7e331f245d2dc1ac8ece306681f52b636b40ef87c88b9f7afd/ruff-0.14.11-py3-none-linux_armv6l.whl", hash = "sha256:f6ff2d95cbd335841a7217bdfd9c1d2e44eac2c584197ab1385579d55ff8830e", size = 12951208, upload-time = "2026-01-08T19:12:09.218Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/5c/360a35cb7204b328b685d3129c08aca24765ff92b5a7efedbdd6c150d555/ruff-0.14.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6f6eb5c1c8033680f4172ea9c8d3706c156223010b8b97b05e82c59bdc774ee6", size = 13330075, upload-time = "2026-01-08T19:12:02.549Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1b/9e/0cc2f1be7a7d33cae541824cf3f95b4ff40d03557b575912b5b70273c9ec/ruff-0.14.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f2fc34cc896f90080fca01259f96c566f74069a04b25b6205d55379d12a6855e", size = 12257809, upload-time = "2026-01-08T19:12:00.366Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/e5/5faab97c15bb75228d9f74637e775d26ac703cc2b4898564c01ab3637c02/ruff-0.14.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53386375001773ae812b43205d6064dae49ff0968774e6befe16a994fc233caa", size = 12678447, upload-time = "2026-01-08T19:12:13.899Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1b/33/e9767f60a2bef779fb5855cab0af76c488e0ce90f7bb7b8a45c8a2ba4178/ruff-0.14.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a697737dce1ca97a0a55b5ff0434ee7205943d4874d638fe3ae66166ff46edbe", size = 12758560, upload-time = "2026-01-08T19:11:42.55Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/84/4c6cf627a21462bb5102f7be2a320b084228ff26e105510cd2255ea868e5/ruff-0.14.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6845ca1da8ab81ab1dce755a32ad13f1db72e7fba27c486d5d90d65e04d17b8f", size = 13599296, upload-time = "2026-01-08T19:11:30.371Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/88/e1/92b5ed7ea66d849f6157e695dc23d5d6d982bd6aa8d077895652c38a7cae/ruff-0.14.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e36ce2fd31b54065ec6f76cb08d60159e1b32bdf08507862e32f47e6dde8bcbf", size = 15048981, upload-time = "2026-01-08T19:12:04.742Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/61/df/c1bd30992615ac17c2fb64b8a7376ca22c04a70555b5d05b8f717163cf9f/ruff-0.14.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:590bcc0e2097ecf74e62a5c10a6b71f008ad82eb97b0a0079e85defe19fe74d9", size = 14633183, upload-time = "2026-01-08T19:11:40.069Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/e9/fe552902f25013dd28a5428a42347d9ad20c4b534834a325a28305747d64/ruff-0.14.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:53fe71125fc158210d57fe4da26e622c9c294022988d08d9347ec1cf782adafe", size = 14050453, upload-time = "2026-01-08T19:11:37.555Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/93/f36d89fa021543187f98991609ce6e47e24f35f008dfe1af01379d248a41/ruff-0.14.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a35c9da08562f1598ded8470fcfef2afb5cf881996e6c0a502ceb61f4bc9c8a3", size = 13757889, upload-time = "2026-01-08T19:12:07.094Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/9f/c7fb6ecf554f28709a6a1f2a7f74750d400979e8cd47ed29feeaa1bd4db8/ruff-0.14.11-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:0f3727189a52179393ecf92ec7057c2210203e6af2676f08d92140d3e1ee72c1", size = 13955832, upload-time = "2026-01-08T19:11:55.064Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/db/a0/153315310f250f76900a98278cf878c64dfb6d044e184491dd3289796734/ruff-0.14.11-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:eb09f849bd37147a789b85995ff734a6c4a095bed5fd1608c4f56afc3634cde2", size = 12586522, upload-time = "2026-01-08T19:11:35.356Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2f/2b/a73a2b6e6d2df1d74bf2b78098be1572191e54bec0e59e29382d13c3adc5/ruff-0.14.11-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:c61782543c1231bf71041461c1f28c64b961d457d0f238ac388e2ab173d7ecb7", size = 12724637, upload-time = "2026-01-08T19:11:47.796Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/41/09100590320394401cd3c48fc718a8ba71c7ddb1ffd07e0ad6576b3a3df2/ruff-0.14.11-py3-none-musllinux_1_2_i686.whl", hash = "sha256:82ff352ea68fb6766140381748e1f67f83c39860b6446966cff48a315c3e2491", size = 13145837, upload-time = "2026-01-08T19:11:32.87Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/d8/e035db859d1d3edf909381eb8ff3e89a672d6572e9454093538fe6f164b0/ruff-0.14.11-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:728e56879df4ca5b62a9dde2dd0eb0edda2a55160c0ea28c4025f18c03f86984", size = 13850469, upload-time = "2026-01-08T19:12:11.694Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/02/bb3ff8b6e6d02ce9e3740f4c17dfbbfb55f34c789c139e9cd91985f356c7/ruff-0.14.11-py3-none-win32.whl", hash = "sha256:337c5dd11f16ee52ae217757d9b82a26400be7efac883e9e852646f1557ed841", size = 12851094, upload-time = "2026-01-08T19:11:45.163Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/58/f1/90ddc533918d3a2ad628bc3044cdfc094949e6d4b929220c3f0eb8a1c998/ruff-0.14.11-py3-none-win_amd64.whl", hash = "sha256:f981cea63d08456b2c070e64b79cb62f951aa1305282974d4d5216e6e0178ae6", size = 14001379, upload-time = "2026-01-08T19:11:52.591Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/1c/1dbe51782c0e1e9cfce1d1004752672d2d4629ea46945d19d731ad772b3b/ruff-0.14.11-py3-none-win_arm64.whl", hash = "sha256:649fb6c9edd7f751db276ef42df1f3df41c38d67d199570ae2a7bd6cbc3590f0", size = 12938644, upload-time = "2026-01-08T19:11:50.027Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1938,11 +1811,11 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "sqlparse"
|
||||
version = "0.5.4"
|
||||
version = "0.5.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/18/67/701f86b28d63b2086de47c942eccf8ca2208b3be69715a1119a4e384415a/sqlparse-0.5.4.tar.gz", hash = "sha256:4396a7d3cf1cd679c1be976cf3dc6e0a51d0111e87787e7a8d780e7d5a998f9e", size = 120112, upload-time = "2025-11-28T07:10:18.377Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/90/76/437d71068094df0726366574cf3432a4ed754217b436eb7429415cf2d480/sqlparse-0.5.5.tar.gz", hash = "sha256:e20d4a9b0b8585fdf63b10d30066c7c94c5d7a7ec47c889a2d83a3caa93ff28e", size = 120815, upload-time = "2025-12-19T07:17:45.073Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/25/70/001ee337f7aa888fb2e3f5fd7592a6afc5283adb1ed44ce8df5764070f22/sqlparse-0.5.4-py3-none-any.whl", hash = "sha256:99a9f0314977b76d776a0fcb8554de91b9bb8a18560631d6bc48721d07023dcb", size = 45933, upload-time = "2025-11-28T07:10:19.73Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/4b/359f28a903c13438ef59ebeee215fb25da53066db67b305c125f1c6d2a25/sqlparse-0.5.5-py3-none-any.whl", hash = "sha256:12a08b3bf3eec877c519589833aed092e2444e68240a3577e8e26148acc7b1ba", size = 46138, upload-time = "2025-12-19T07:17:46.573Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1968,51 +1841,56 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "tomli"
|
||||
version = "2.3.0"
|
||||
version = "2.4.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/52/ed/3f73f72945444548f33eba9a87fc7a6e969915e7b1acc8260b30e1f76a2f/tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549", size = 17392, upload-time = "2025-10-08T22:01:47.119Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/82/30/31573e9457673ab10aa432461bee537ce6cef177667deca369efb79df071/tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c", size = 17477, upload-time = "2026-01-11T11:22:38.165Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/2e/299f62b401438d5fe1624119c723f5d877acc86a4c2492da405626665f12/tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45", size = 153236, upload-time = "2025-10-08T22:01:00.137Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/7f/d8fffe6a7aefdb61bced88fcb5e280cfd71e08939da5894161bd71bea022/tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba", size = 148084, upload-time = "2025-10-08T22:01:01.63Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/5c/24935fb6a2ee63e86d80e4d3b58b222dafaf438c416752c8b58537c8b89a/tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf", size = 234832, upload-time = "2025-10-08T22:01:02.543Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/da/75dfd804fc11e6612846758a23f13271b76d577e299592b4371a4ca4cd09/tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441", size = 242052, upload-time = "2025-10-08T22:01:03.836Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/8c/f48ac899f7b3ca7eb13af73bacbc93aec37f9c954df3c08ad96991c8c373/tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845", size = 239555, upload-time = "2025-10-08T22:01:04.834Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/28/72f8afd73f1d0e7829bfc093f4cb98ce0a40ffc0cc997009ee1ed94ba705/tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c", size = 245128, upload-time = "2025-10-08T22:01:05.84Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/eb/a7679c8ac85208706d27436e8d421dfa39d4c914dcf5fa8083a9305f58d9/tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456", size = 96445, upload-time = "2025-10-08T22:01:06.896Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0a/fe/3d3420c4cb1ad9cb462fb52967080575f15898da97e21cb6f1361d505383/tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be", size = 107165, upload-time = "2025-10-08T22:01:08.107Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/b7/40f36368fcabc518bb11c8f06379a0fd631985046c038aca08c6d6a43c6e/tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac", size = 154891, upload-time = "2025-10-08T22:01:09.082Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/3f/d9dd692199e3b3aab2e4e4dd948abd0f790d9ded8cd10cbaae276a898434/tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22", size = 148796, upload-time = "2025-10-08T22:01:10.266Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/60/83/59bff4996c2cf9f9387a0f5a3394629c7efa5ef16142076a23a90f1955fa/tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f", size = 242121, upload-time = "2025-10-08T22:01:11.332Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/45/e5/7c5119ff39de8693d6baab6c0b6dcb556d192c165596e9fc231ea1052041/tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52", size = 250070, upload-time = "2025-10-08T22:01:12.498Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/45/12/ad5126d3a278f27e6701abde51d342aa78d06e27ce2bb596a01f7709a5a2/tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8", size = 245859, upload-time = "2025-10-08T22:01:13.551Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/a1/4d6865da6a71c603cfe6ad0e6556c73c76548557a8d658f9e3b142df245f/tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6", size = 250296, upload-time = "2025-10-08T22:01:14.614Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/b7/a7a7042715d55c9ba6e8b196d65d2cb662578b4d8cd17d882d45322b0d78/tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876", size = 97124, upload-time = "2025-10-08T22:01:15.629Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/06/1e/f22f100db15a68b520664eb3328fb0ae4e90530887928558112c8d1f4515/tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878", size = 107698, upload-time = "2025-10-08T22:01:16.51Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/48/06ee6eabe4fdd9ecd48bf488f4ac783844fd777f547b8d1b61c11939974e/tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b", size = 154819, upload-time = "2025-10-08T22:01:17.964Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/01/88793757d54d8937015c75dcdfb673c65471945f6be98e6a0410fba167ed/tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae", size = 148766, upload-time = "2025-10-08T22:01:18.959Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/42/17/5e2c956f0144b812e7e107f94f1cc54af734eb17b5191c0bbfb72de5e93e/tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b", size = 240771, upload-time = "2025-10-08T22:01:20.106Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d5/f4/0fbd014909748706c01d16824eadb0307115f9562a15cbb012cd9b3512c5/tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf", size = 248586, upload-time = "2025-10-08T22:01:21.164Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/77/fed85e114bde5e81ecf9bc5da0cc69f2914b38f4708c80ae67d0c10180c5/tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f", size = 244792, upload-time = "2025-10-08T22:01:22.417Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/55/92/afed3d497f7c186dc71e6ee6d4fcb0acfa5f7d0a1a2878f8beae379ae0cc/tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05", size = 248909, upload-time = "2025-10-08T22:01:23.859Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/84/ef50c51b5a9472e7265ce1ffc7f24cd4023d289e109f669bdb1553f6a7c2/tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606", size = 96946, upload-time = "2025-10-08T22:01:24.893Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/b7/718cd1da0884f281f95ccfa3a6cc572d30053cba64603f79d431d3c9b61b/tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999", size = 107705, upload-time = "2025-10-08T22:01:26.153Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/94/aeafa14a52e16163008060506fcb6aa1949d13548d13752171a755c65611/tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e", size = 154244, upload-time = "2025-10-08T22:01:27.06Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/db/e4/1e58409aa78eefa47ccd19779fc6f36787edbe7d4cd330eeeedb33a4515b/tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3", size = 148637, upload-time = "2025-10-08T22:01:28.059Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/b6/d1eccb62f665e44359226811064596dd6a366ea1f985839c566cd61525ae/tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc", size = 241925, upload-time = "2025-10-08T22:01:29.066Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/91/7cdab9a03e6d3d2bb11beae108da5bdc1c34bdeb06e21163482544ddcc90/tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0", size = 249045, upload-time = "2025-10-08T22:01:31.98Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/15/1b/8c26874ed1f6e4f1fcfeb868db8a794cbe9f227299402db58cfcc858766c/tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879", size = 245835, upload-time = "2025-10-08T22:01:32.989Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/42/8e3c6a9a4b1a1360c1a2a39f0b972cef2cc9ebd56025168c4137192a9321/tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005", size = 253109, upload-time = "2025-10-08T22:01:34.052Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/0c/b4da635000a71b5f80130937eeac12e686eefb376b8dee113b4a582bba42/tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463", size = 97930, upload-time = "2025-10-08T22:01:35.082Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b9/74/cb1abc870a418ae99cd5c9547d6bce30701a954e0e721821df483ef7223c/tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8", size = 107964, upload-time = "2025-10-08T22:01:36.057Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/78/5c46fff6432a712af9f792944f4fcd7067d8823157949f4e40c56b8b3c83/tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77", size = 163065, upload-time = "2025-10-08T22:01:37.27Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/39/67/f85d9bd23182f45eca8939cd2bc7050e1f90c41f4a2ecbbd5963a1d1c486/tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf", size = 159088, upload-time = "2025-10-08T22:01:38.235Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/5a/4b546a0405b9cc0659b399f12b6adb750757baf04250b148d3c5059fc4eb/tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530", size = 268193, upload-time = "2025-10-08T22:01:39.712Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/42/4f/2c12a72ae22cf7b59a7fe75b3465b7aba40ea9145d026ba41cb382075b0e/tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b", size = 275488, upload-time = "2025-10-08T22:01:40.773Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/04/a038d65dbe160c3aa5a624e93ad98111090f6804027d474ba9c37c8ae186/tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67", size = 272669, upload-time = "2025-10-08T22:01:41.824Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/2f/8b7c60a9d1612a7cbc39ffcca4f21a73bf368a80fc25bccf8253e2563267/tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f", size = 279709, upload-time = "2025-10-08T22:01:43.177Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/46/cc36c679f09f27ded940281c38607716c86cf8ba4a518d524e349c8b4874/tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0", size = 107563, upload-time = "2025-10-08T22:01:44.233Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/ff/426ca8683cf7b753614480484f6437f568fd2fda2edbdf57a2d3d8b27a0b/tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba", size = 119756, upload-time = "2025-10-08T22:01:45.234Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/b8/0135fadc89e73be292b473cb820b4f5a08197779206b33191e801feeae40/tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b", size = 14408, upload-time = "2025-10-08T22:01:46.04Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/d9/3dc2289e1f3b32eb19b9785b6a006b28ee99acb37d1d47f78d4c10e28bf8/tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867", size = 153663, upload-time = "2026-01-11T11:21:45.27Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/51/32/ef9f6845e6b9ca392cd3f64f9ec185cc6f09f0a2df3db08cbe8809d1d435/tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9", size = 148469, upload-time = "2026-01-11T11:21:46.873Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/c2/506e44cce89a8b1b1e047d64bd495c22c9f71f21e05f380f1a950dd9c217/tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95", size = 236039, upload-time = "2026-01-11T11:21:48.503Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/40/e1b65986dbc861b7e986e8ec394598187fa8aee85b1650b01dd925ca0be8/tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76", size = 243007, upload-time = "2026-01-11T11:21:49.456Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/6f/6e39ce66b58a5b7ae572a0f4352ff40c71e8573633deda43f6a379d56b3e/tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d", size = 240875, upload-time = "2026-01-11T11:21:50.755Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/ad/cb089cb190487caa80204d503c7fd0f4d443f90b95cf4ef5cf5aa0f439b0/tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576", size = 246271, upload-time = "2026-01-11T11:21:51.81Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/63/69125220e47fd7a3a27fd0de0c6398c89432fec41bc739823bcc66506af6/tomli-2.4.0-cp311-cp311-win32.whl", hash = "sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a", size = 96770, upload-time = "2026-01-11T11:21:52.647Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/0d/a22bb6c83f83386b0008425a6cd1fa1c14b5f3dd4bad05e98cf3dbbf4a64/tomli-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa", size = 107626, upload-time = "2026-01-11T11:21:53.459Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2f/6d/77be674a3485e75cacbf2ddba2b146911477bd887dda9d8c9dfb2f15e871/tomli-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614", size = 94842, upload-time = "2026-01-11T11:21:54.831Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/43/7389a1869f2f26dba52404e1ef13b4784b6b37dac93bac53457e3ff24ca3/tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1", size = 154894, upload-time = "2026-01-11T11:21:56.07Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/05/2f9bf110b5294132b2edf13fe6ca6ae456204f3d749f623307cbb7a946f2/tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8", size = 149053, upload-time = "2026-01-11T11:21:57.467Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e8/41/1eda3ca1abc6f6154a8db4d714a4d35c4ad90adc0bcf700657291593fbf3/tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a", size = 243481, upload-time = "2026-01-11T11:21:58.661Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d2/6d/02ff5ab6c8868b41e7d4b987ce2b5f6a51d3335a70aa144edd999e055a01/tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1", size = 251720, upload-time = "2026-01-11T11:22:00.178Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/57/0405c59a909c45d5b6f146107c6d997825aa87568b042042f7a9c0afed34/tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b", size = 247014, upload-time = "2026-01-11T11:22:01.238Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/0e/2e37568edd944b4165735687cbaf2fe3648129e440c26d02223672ee0630/tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51", size = 251820, upload-time = "2026-01-11T11:22:02.727Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/1c/ee3b707fdac82aeeb92d1a113f803cf6d0f37bdca0849cb489553e1f417a/tomli-2.4.0-cp312-cp312-win32.whl", hash = "sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729", size = 97712, upload-time = "2026-01-11T11:22:03.777Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/13/c07a9177d0b3bab7913299b9278845fc6eaaca14a02667c6be0b0a2270c8/tomli-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da", size = 108296, upload-time = "2026-01-11T11:22:04.86Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/18/27/e267a60bbeeee343bcc279bb9e8fbed0cbe224bc7b2a3dc2975f22809a09/tomli-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3", size = 94553, upload-time = "2026-01-11T11:22:05.854Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/34/91/7f65f9809f2936e1f4ce6268ae1903074563603b2a2bd969ebbda802744f/tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0", size = 154915, upload-time = "2026-01-11T11:22:06.703Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/20/aa/64dd73a5a849c2e8f216b755599c511badde80e91e9bc2271baa7b2cdbb1/tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e", size = 149038, upload-time = "2026-01-11T11:22:07.56Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/8a/6d38870bd3d52c8d1505ce054469a73f73a0fe62c0eaf5dddf61447e32fa/tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4", size = 242245, upload-time = "2026-01-11T11:22:08.344Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/59/bb/8002fadefb64ab2669e5b977df3f5e444febea60e717e755b38bb7c41029/tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e", size = 250335, upload-time = "2026-01-11T11:22:09.951Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a5/3d/4cdb6f791682b2ea916af2de96121b3cb1284d7c203d97d92d6003e91c8d/tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c", size = 245962, upload-time = "2026-01-11T11:22:11.27Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/4a/5f25789f9a460bd858ba9756ff52d0830d825b458e13f754952dd15fb7bb/tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f", size = 250396, upload-time = "2026-01-11T11:22:12.325Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/2f/b73a36fea58dfa08e8b3a268750e6853a6aac2a349241a905ebd86f3047a/tomli-2.4.0-cp313-cp313-win32.whl", hash = "sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86", size = 97530, upload-time = "2026-01-11T11:22:13.865Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/af/ca18c134b5d75de7e8dc551c5234eaba2e8e951f6b30139599b53de9c187/tomli-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87", size = 108227, upload-time = "2026-01-11T11:22:15.224Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/c3/b386b832f209fee8073c8138ec50f27b4460db2fdae9ffe022df89a57f9b/tomli-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132", size = 94748, upload-time = "2026-01-11T11:22:16.009Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/c4/84047a97eb1004418bc10bdbcfebda209fca6338002eba2dc27cc6d13563/tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6", size = 154725, upload-time = "2026-01-11T11:22:17.269Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/5d/d39038e646060b9d76274078cddf146ced86dc2b9e8bbf737ad5983609a0/tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc", size = 148901, upload-time = "2026-01-11T11:22:18.287Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/e5/383be1724cb30f4ce44983d249645684a48c435e1cd4f8b5cded8a816d3c/tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66", size = 243375, upload-time = "2026-01-11T11:22:19.154Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/f0/bea80c17971c8d16d3cc109dc3585b0f2ce1036b5f4a8a183789023574f2/tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d", size = 250639, upload-time = "2026-01-11T11:22:20.168Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/8f/2853c36abbb7608e3f945d8a74e32ed3a74ee3a1f468f1ffc7d1cb3abba6/tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702", size = 246897, upload-time = "2026-01-11T11:22:21.544Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/f0/6c05e3196ed5337b9fe7ea003e95fd3819a840b7a0f2bf5a408ef1dad8ed/tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8", size = 254697, upload-time = "2026-01-11T11:22:23.058Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/f5/2922ef29c9f2951883525def7429967fc4d8208494e5ab524234f06b688b/tomli-2.4.0-cp314-cp314-win32.whl", hash = "sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776", size = 98567, upload-time = "2026-01-11T11:22:24.033Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/31/22b52e2e06dd2a5fdbc3ee73226d763b184ff21fc24e20316a44ccc4d96b/tomli-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475", size = 108556, upload-time = "2026-01-11T11:22:25.378Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/48/3d/5058dff3255a3d01b705413f64f4306a141a8fd7a251e5a495e3f192a998/tomli-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2", size = 96014, upload-time = "2026-01-11T11:22:26.138Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/4e/75dab8586e268424202d3a1997ef6014919c941b50642a1682df43204c22/tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9", size = 163339, upload-time = "2026-01-11T11:22:27.143Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/06/e3/b904d9ab1016829a776d97f163f183a48be6a4deb87304d1e0116a349519/tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0", size = 159490, upload-time = "2026-01-11T11:22:28.399Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/5a/fc3622c8b1ad823e8ea98a35e3c632ee316d48f66f80f9708ceb4f2a0322/tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df", size = 269398, upload-time = "2026-01-11T11:22:29.345Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/33/62bd6152c8bdd4c305ad9faca48f51d3acb2df1f8791b1477d46ff86e7f8/tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d", size = 276515, upload-time = "2026-01-11T11:22:30.327Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/ff/ae53619499f5235ee4211e62a8d7982ba9e439a0fb4f2f351a93d67c1dd2/tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f", size = 273806, upload-time = "2026-01-11T11:22:32.56Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/71/cbca7787fa68d4d0a9f7072821980b39fbb1b6faeb5f5cf02f4a5559fa28/tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b", size = 281340, upload-time = "2026-01-11T11:22:33.505Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/00/d595c120963ad42474cf6ee7771ad0d0e8a49d0f01e29576ee9195d9ecdf/tomli-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087", size = 108106, upload-time = "2026-01-11T11:22:34.451Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/de/69/9aa0c6a505c2f80e519b43764f8b4ba93b5a0bbd2d9a9de6e2b24271b9a5/tomli-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd", size = 120504, upload-time = "2026-01-11T11:22:35.764Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/9f/f1668c281c58cfae01482f7114a4b88d345e4c140386241a1a24dcc9e7bc/tomli-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4", size = 99561, upload-time = "2026-01-11T11:22:36.624Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a", size = 14477, upload-time = "2026-01-11T11:22:37.446Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2108,11 +1986,11 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.6.2"
|
||||
version = "2.6.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1e/24/a2a2ed9addd907787d7aa0355ba36a6cadf1768b934c652ea78acbd59dcd/urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797", size = 432930, upload-time = "2025-12-11T15:56:40.252Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd", size = 131182, upload-time = "2025-12-11T15:56:38.584Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2162,7 +2040,6 @@ dependencies = [
|
||||
{ name = "django-activity-stream" },
|
||||
{ name = "django-axes", extra = ["ipware"] },
|
||||
{ name = "django-bootstrap-breadcrumbs2" },
|
||||
{ name = "django-compressor" },
|
||||
{ name = "django-cors-headers" },
|
||||
{ name = "django-crispy-forms" },
|
||||
{ name = "django-email-verification" },
|
||||
@@ -2220,7 +2097,6 @@ requires-dist = [
|
||||
{ name = "django-activity-stream", specifier = "~=2.0.0" },
|
||||
{ name = "django-axes", extras = ["ipware"], specifier = "~=8.0.0" },
|
||||
{ name = "django-bootstrap-breadcrumbs2", specifier = "==1.0.0" },
|
||||
{ name = "django-compressor", specifier = "~=4.6.0" },
|
||||
{ name = "django-cors-headers", specifier = "~=4.9.0" },
|
||||
{ name = "django-crispy-forms", specifier = "~=2.5" },
|
||||
{ name = "django-email-verification", specifier = "~=0.3.3" },
|
||||
@@ -2287,38 +2163,38 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "zope-interface"
|
||||
version = "8.1.1"
|
||||
version = "8.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/71/c9/5ec8679a04d37c797d343f650c51ad67d178f0001c363e44b6ac5f97a9da/zope_interface-8.1.1.tar.gz", hash = "sha256:51b10e6e8e238d719636a401f44f1e366146912407b58453936b781a19be19ec", size = 254748, upload-time = "2025-11-15T08:32:52.404Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/86/a4/77daa5ba398996d16bb43fc721599d27d03eae68fe3c799de1963c72e228/zope_interface-8.2.tar.gz", hash = "sha256:afb20c371a601d261b4f6edb53c3c418c249db1a9717b0baafc9a9bb39ba1224", size = 254019, upload-time = "2026-01-09T07:51:07.253Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/ca/77df8f9bcbd8a5e29913c7fef14ff0aadac9448e78dc2606a85d7a23ec6c/zope_interface-8.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c6b12b656c7d7e3d79cad8e2afc4a37eae6b6076e2c209a33345143148e435e", size = 207415, upload-time = "2025-11-15T08:36:36.508Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/1f/f1c7828ba3d9b34e65c7e498216fc37ca6e69f1ff1918cca37cd1d895682/zope_interface-8.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:557c0f1363c300db406e9eeaae8ab6d1ba429d4fed60d8ab7dadab5ca66ccd35", size = 207951, upload-time = "2025-11-15T08:36:38.468Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/9e/e079035812f06fe1feede1bef753f537fb33d5480d05107f65a51d94e7b3/zope_interface-8.1.1-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:127b0e4c873752b777721543cf8525b3db5e76b88bd33bab807f03c568e9003f", size = 249409, upload-time = "2025-11-15T08:36:40.148Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/09/b7f5a33bd3a17efb31e9e14496e600ab550ab0e38829dcda8a73f017fbfe/zope_interface-8.1.1-cp310-cp310-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e0892c9d2dd47b45f62d1861bcae8b427fcc49b4a04fff67f12c5c55e56654d7", size = 254527, upload-time = "2025-11-15T08:36:41.552Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/90/0eecd1eab6b62d296dff8445f051e4aa6bd91b67d71cfe9ff9d270b64dbe/zope_interface-8.1.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ff8a92dc8c8a2c605074e464984e25b9b5a8ac9b2a0238dd73a0f374df59a77e", size = 254963, upload-time = "2025-11-15T08:36:42.708Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/ff/2fe84fadd13e8adb7b2fb542311c27bad15881be26e37f403df3d0279c74/zope_interface-8.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:54627ddf6034aab1f506ba750dd093f67d353be6249467d720e9f278a578efe5", size = 211809, upload-time = "2025-11-15T08:36:44.43Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/fc/d84bac27332bdefe8c03f7289d932aeb13a5fd6aeedba72b0aa5b18276ff/zope_interface-8.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e8a0fdd5048c1bb733e4693eae9bc4145a19419ea6a1c95299318a93fe9f3d72", size = 207955, upload-time = "2025-11-15T08:36:45.902Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/52/02/e1234eb08b10b5cf39e68372586acc7f7bbcd18176f6046433a8f6b8b263/zope_interface-8.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a4cb0ea75a26b606f5bc8524fbce7b7d8628161b6da002c80e6417ce5ec757c0", size = 208398, upload-time = "2025-11-15T08:36:47.016Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/be/aabda44d4bc490f9966c2b77fa7822b0407d852cb909b723f2d9e05d2427/zope_interface-8.1.1-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:c267b00b5a49a12743f5e1d3b4beef45479d696dab090f11fe3faded078a5133", size = 255079, upload-time = "2025-11-15T08:36:48.157Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/7f/4fbc7c2d7cb310e5a91b55db3d98e98d12b262014c1fcad9714fe33c2adc/zope_interface-8.1.1-cp311-cp311-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e25d3e2b9299e7ec54b626573673bdf0d740cf628c22aef0a3afef85b438aa54", size = 259850, upload-time = "2025-11-15T08:36:49.544Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/2c/dc573fffe59cdbe8bbbdd2814709bdc71c4870893e7226700bc6a08c5e0c/zope_interface-8.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:63db1241804417aff95ac229c13376c8c12752b83cc06964d62581b493e6551b", size = 261033, upload-time = "2025-11-15T08:36:51.061Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/51/1ac50e5ee933d9e3902f3400bda399c128a5c46f9f209d16affe3d4facc5/zope_interface-8.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:9639bf4ed07b5277fb231e54109117c30d608254685e48a7104a34618bcbfc83", size = 212215, upload-time = "2025-11-15T08:36:52.553Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/08/3d/f5b8dd2512f33bfab4faba71f66f6873603d625212206dd36f12403ae4ca/zope_interface-8.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a16715808408db7252b8c1597ed9008bdad7bf378ed48eb9b0595fad4170e49d", size = 208660, upload-time = "2025-11-15T08:36:53.579Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e5/41/c331adea9b11e05ff9ac4eb7d3032b24c36a3654ae9f2bf4ef2997048211/zope_interface-8.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce6b58752acc3352c4aa0b55bbeae2a941d61537e6afdad2467a624219025aae", size = 208851, upload-time = "2025-11-15T08:36:54.854Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/25/00/7a8019c3bb8b119c5f50f0a4869183a4b699ca004a7f87ce98382e6b364c/zope_interface-8.1.1-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:807778883d07177713136479de7fd566f9056a13aef63b686f0ab4807c6be259", size = 259292, upload-time = "2025-11-15T08:36:56.409Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/fc/b70e963bf89345edffdd5d16b61e789fdc09365972b603e13785360fea6f/zope_interface-8.1.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:50e5eb3b504a7d63dc25211b9298071d5b10a3eb754d6bf2f8ef06cb49f807ab", size = 264741, upload-time = "2025-11-15T08:36:57.675Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/fe/7d0b5c0692b283901b34847f2b2f50d805bfff4b31de4021ac9dfb516d2a/zope_interface-8.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eee6f93b2512ec9466cf30c37548fd3ed7bc4436ab29cd5943d7a0b561f14f0f", size = 264281, upload-time = "2025-11-15T08:36:58.968Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/2c/a7cebede1cf2757be158bcb151fe533fa951038cfc5007c7597f9f86804b/zope_interface-8.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:80edee6116d569883c58ff8efcecac3b737733d646802036dc337aa839a5f06b", size = 212327, upload-time = "2025-11-15T08:37:00.4Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/85/81/3c3b5386ce4fba4612fd82ffb8a90d76bcfea33ca2b6399f21e94d38484f/zope_interface-8.1.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:84f9be6d959640de9da5d14ac1f6a89148b16da766e88db37ed17e936160b0b1", size = 209046, upload-time = "2025-11-15T08:37:01.473Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4a/e3/32b7cb950c4c4326b3760a8e28e5d6f70ad15f852bfd8f9364b58634f74b/zope_interface-8.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:531fba91dcb97538f70cf4642a19d6574269460274e3f6004bba6fe684449c51", size = 209104, upload-time = "2025-11-15T08:37:02.887Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/3d/c4c68e1752a5f5effa2c1f5eaa4fea4399433c9b058fb7000a34bfb1c447/zope_interface-8.1.1-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:fc65f5633d5a9583ee8d88d1f5de6b46cd42c62e47757cfe86be36fb7c8c4c9b", size = 259277, upload-time = "2025-11-15T08:37:04.389Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/5b/cf4437b174af7591ee29bbad728f620cab5f47bd6e9c02f87d59f31a0dda/zope_interface-8.1.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:efef80ddec4d7d99618ef71bc93b88859248075ca2e1ae1c78636654d3d55533", size = 264742, upload-time = "2025-11-15T08:37:05.613Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/0e/0cf77356862852d3d3e62db9aadae5419a1a7d89bf963b219745283ab5ca/zope_interface-8.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:49aad83525eca3b4747ef51117d302e891f0042b06f32aa1c7023c62642f962b", size = 264252, upload-time = "2025-11-15T08:37:07.035Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/10/2af54aa88b2fa172d12364116cc40d325fedbb1877c3bb031b0da6052855/zope_interface-8.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:71cf329a21f98cb2bd9077340a589e316ac8a415cac900575a32544b3dffcb98", size = 212330, upload-time = "2025-11-15T08:37:08.14Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b9/f5/44efbd98ba06cb937fce7a69fcd7a78c4ac7aa4e1ad2125536801376d2d0/zope_interface-8.1.1-cp314-cp314-macosx_10_9_x86_64.whl", hash = "sha256:da311e9d253991ca327601f47c4644d72359bac6950fbb22f971b24cd7850f8c", size = 209099, upload-time = "2025-11-15T08:37:09.395Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/36/a19866c09c8485c36a4c6908e1dd3f8820b41c1ee333c291157cf4cf09e7/zope_interface-8.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3fb25fca0442c7fb93c4ee40b42e3e033fef2f648730c4b7ae6d43222a3e8946", size = 209240, upload-time = "2025-11-15T08:37:10.687Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/28/0dbf40db772d779a4ac8d006a57ad60936d42ad4769a3d5410dcfb98f6f9/zope_interface-8.1.1-cp314-cp314-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:bac588d0742b4e35efb7c7df1dacc0397b51ed37a17d4169a38019a1cebacf0a", size = 260919, upload-time = "2025-11-15T08:37:11.838Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/72/ae/650cd4c01dd1b32c26c800b2c4d852f044552c34a56fbb74d41f569cee31/zope_interface-8.1.1-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3d1f053d2d5e2b393e619bce1e55954885c2e63969159aa521839e719442db49", size = 264102, upload-time = "2025-11-15T08:37:13.241Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/f0/f534a2c34c006aa090c593cd70eaf94e259fd0786f934698d81f0534d907/zope_interface-8.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:64a1ad7f4cb17d948c6bdc525a1d60c0e567b2526feb4fa38b38f249961306b8", size = 264276, upload-time = "2025-11-15T08:37:14.369Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5b/a8/d7e9cf03067b767e23908dbab5f6be7735d70cb4818311a248a8c4bb23cc/zope_interface-8.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:169214da1b82b7695d1a36f92d70b11166d66b6b09d03df35d150cc62ac52276", size = 212492, upload-time = "2025-11-15T08:37:15.538Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/fa/6d9eb3a33998a3019d7eb4fa1802d01d6602fad90e0aea443e6e0fe8e49a/zope_interface-8.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:788c293f3165964ec6527b2d861072c68eef53425213f36d3893ebee89a89623", size = 207541, upload-time = "2026-01-09T08:04:55.378Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/8c/ad23c96fdee84cb1f768f6695dac187cc26e9038e01c69713ba0f7dc46ab/zope_interface-8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9a4e785097e741a1c953b3970ce28f2823bd63c00adc5d276f2981dd66c96c15", size = 208075, upload-time = "2026-01-09T08:04:57.118Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/dd/35/1bfd5fec31a307f0cf4065ee74ade63858ded3e2a71e248f1508118fcc95/zope_interface-8.2-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:16c69da19a06566664ddd4785f37cad5693a51d48df1515d264c20d005d322e2", size = 249528, upload-time = "2026-01-09T08:04:59.074Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c6/3a/5d50b5fdb0f8226a2edff6adb7efdd3762ec95dff827dbab1761cb9a9e85/zope_interface-8.2-cp310-cp310-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c31acfa3d7cde48bec45701b0e1f4698daffc378f559bfb296837d8c834732f6", size = 254646, upload-time = "2026-01-09T08:05:00.964Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2f/2a/ee7d675e151578eaf77828b8faac2b7ed9a69fead350bf5cf0e4afe7c73d/zope_interface-8.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0723507127f8269b8f3f22663168f717e9c9742107d1b6c9f419df561b71aa6d", size = 255083, upload-time = "2026-01-09T08:05:02.857Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/07/99e2342f976c3700e142eddc01524e375a9e9078869a6885d9c72f3a3659/zope_interface-8.2-cp310-cp310-win_amd64.whl", hash = "sha256:3bf73a910bb27344def2d301a03329c559a79b308e1e584686b74171d736be4e", size = 211924, upload-time = "2026-01-09T08:05:04.702Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/97/9c2aa8caae79915ed64eb114e18816f178984c917aa9adf2a18345e4f2e5/zope_interface-8.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c65ade7ea85516e428651048489f5e689e695c79188761de8c622594d1e13322", size = 208081, upload-time = "2026-01-09T08:05:06.623Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/34/86/4e2fcb01a8f6780ac84923748e450af0805531f47c0956b83065c99ab543/zope_interface-8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1ef4b43659e1348f35f38e7d1a6bbc1682efde239761f335ffc7e31e798b65b", size = 208522, upload-time = "2026-01-09T08:05:07.986Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/eb/08e277da32ddcd4014922854096cf6dcb7081fad415892c2da1bedefbf02/zope_interface-8.2-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:dfc4f44e8de2ff4eba20af4f0a3ca42d3c43ab24a08e49ccd8558b7a4185b466", size = 255198, upload-time = "2026-01-09T08:05:09.532Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/a1/b32484f3281a5dc83bc713ad61eca52c543735cdf204543172087a074a74/zope_interface-8.2-cp311-cp311-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8f094bfb49179ec5dc9981cb769af1275702bd64720ef94874d9e34da1390d4c", size = 259970, upload-time = "2026-01-09T08:05:11.477Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/81/bca0e8ae1e487d4093a8a7cfed2118aa2d4758c8cfd66e59d2af09d71f1c/zope_interface-8.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d2bb8e7364e18f083bf6744ccf30433b2a5f236c39c95df8514e3c13007098ce", size = 261153, upload-time = "2026-01-09T08:05:13.402Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/1e/e3ff2a708011e56b10b271b038d4cb650a8ad5b7d24352fe2edf6d6b187a/zope_interface-8.2-cp311-cp311-win_amd64.whl", hash = "sha256:6f4b4dfcfdfaa9177a600bb31cebf711fdb8c8e9ed84f14c61c420c6aa398489", size = 212330, upload-time = "2026-01-09T08:05:15.267Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e0/a0/1e1fabbd2e9c53ef92b69df6d14f4adc94ec25583b1380336905dc37e9a0/zope_interface-8.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:624b6787fc7c3e45fa401984f6add2c736b70a7506518c3b537ffaacc4b29d4c", size = 208785, upload-time = "2026-01-09T08:05:17.348Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/2a/88d098a06975c722a192ef1fb7d623d1b57c6a6997cf01a7aabb45ab1970/zope_interface-8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bc9ded9e97a0ed17731d479596ed1071e53b18e6fdb2fc33af1e43f5fd2d3aaa", size = 208976, upload-time = "2026-01-09T08:05:18.792Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/e8/757398549fdfd2f8c89f32c82ae4d2f0537ae2a5d2f21f4a2f711f5a059f/zope_interface-8.2-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:532367553e4420c80c0fc0cabcc2c74080d495573706f66723edee6eae53361d", size = 259411, upload-time = "2026-01-09T08:05:20.567Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/91/af/502601f0395ce84dff622f63cab47488657a04d0065547df42bee3a680ff/zope_interface-8.2-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2bf9cf275468bafa3c72688aad8cfcbe3d28ee792baf0b228a1b2d93bd1d541a", size = 264859, upload-time = "2026-01-09T08:05:22.234Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/0c/d2f765b9b4814a368a7c1b0ac23b68823c6789a732112668072fe596945d/zope_interface-8.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0009d2d3c02ea783045d7804da4fd016245e5c5de31a86cebba66dd6914d59a2", size = 264398, upload-time = "2026-01-09T08:05:23.853Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4a/81/2f171fbc4222066957e6b9220c4fb9146792540102c37e6d94e5d14aad97/zope_interface-8.2-cp312-cp312-win_amd64.whl", hash = "sha256:845d14e580220ae4544bd4d7eb800f0b6034fe5585fc2536806e0a26c2ee6640", size = 212444, upload-time = "2026-01-09T08:05:25.148Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/47/45188fb101fa060b20e6090e500682398ab415e516a0c228fbb22bc7def2/zope_interface-8.2-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:6068322004a0158c80dfd4708dfb103a899635408c67c3b10e9acec4dbacefec", size = 209170, upload-time = "2026-01-09T08:05:26.616Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/09/03/f6b9336c03c2b48403c4eb73a1ec961d94dc2fb5354c583dfb5fa05fd41f/zope_interface-8.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2499de92e8275d0dd68f84425b3e19e9268cd1fa8507997900fa4175f157733c", size = 209229, upload-time = "2026-01-09T08:05:28.521Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/07/b1/65fe1dca708569f302ade02e6cdca309eab6752bc9f80105514f5b708651/zope_interface-8.2-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:f777e68c76208503609c83ca021a6864902b646530a1a39abb9ed310d1100664", size = 259393, upload-time = "2026-01-09T08:05:29.897Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/a5/97b49cfceb6ed53d3dcfb3f3ebf24d83b5553194f0337fbbb3a9fec6cf78/zope_interface-8.2-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9b05a919fdb0ed6ea942e5a7800e09a8b6cdae6f98fee1bef1c9d1a3fc43aaa0", size = 264863, upload-time = "2026-01-09T08:05:31.501Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/02/0b7a77292810efe3a0586a505b077ebafd5114e10c6e6e659f0c8e387e1f/zope_interface-8.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ccc62b5712dd7bd64cfba3ee63089fb11e840f5914b990033beeae3b2180b6cb", size = 264369, upload-time = "2026-01-09T08:05:32.941Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/1d/0d1ff3846302ed1b5bbf659316d8084b30106770a5f346b7ff4e9f540f80/zope_interface-8.2-cp313-cp313-win_amd64.whl", hash = "sha256:34f877d1d3bb7565c494ed93828fa6417641ca26faf6e8f044e0d0d500807028", size = 212447, upload-time = "2026-01-09T08:05:35.064Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/da/3c89de3917751446728b8898b4d53318bc2f8f6bf8196e150a063c59905e/zope_interface-8.2-cp314-cp314-macosx_10_9_x86_64.whl", hash = "sha256:46c7e4e8cbc698398a67e56ca985d19cb92365b4aafbeb6a712e8c101090f4cb", size = 209223, upload-time = "2026-01-09T08:05:36.449Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/7f/62d00ec53f0a6e5df0c984781e6f3999ed265129c4c3413df8128d1e0207/zope_interface-8.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a87fc7517f825a97ff4a4ca4c8a950593c59e0f8e7bfe1b6f898a38d5ba9f9cf", size = 209366, upload-time = "2026-01-09T08:05:38.197Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/a2/f241986315174be8e00aabecfc2153cf8029c1327cab8ed53a9d979d7e08/zope_interface-8.2-cp314-cp314-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:ccf52f7d44d669203c2096c1a0c2c15d52e36b2e7a9413df50f48392c7d4d080", size = 261037, upload-time = "2026-01-09T08:05:39.568Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/cc/b321c51d6936ede296a1b8860cf173bee2928357fe1fff7f97234899173f/zope_interface-8.2-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:aae807efc7bd26302eb2fea05cd6de7d59269ed6ae23a6de1ee47add6de99b8c", size = 264219, upload-time = "2026-01-09T08:05:41.624Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/fb/5f5e7b40a2f4efd873fe173624795ca47eaa22e29051270c981361b45209/zope_interface-8.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:05a0e42d6d830f547e114de2e7cd15750dc6c0c78f8138e6c5035e51ddfff37c", size = 264390, upload-time = "2026-01-09T08:05:42.936Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/82/3f2bc594370bc3abd58e5f9085d263bf682a222f059ed46275cde0570810/zope_interface-8.2-cp314-cp314-win_amd64.whl", hash = "sha256:561ce42390bee90bae51cf1c012902a8033b2aaefbd0deed81e877562a116d48", size = 212585, upload-time = "2026-01-09T08:05:44.419Z" },
|
||||
]
|
||||
|
||||
@@ -21,7 +21,7 @@ import os
|
||||
from celery import Celery
|
||||
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings')
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings.main')
|
||||
app = Celery('wger')
|
||||
|
||||
# read config from Django settings, the CELERY namespace would make celery
|
||||
|
||||
@@ -287,6 +287,21 @@
|
||||
"delete_weightunit",
|
||||
"nutrition",
|
||||
"weightunit"
|
||||
],
|
||||
[
|
||||
"add_trophy",
|
||||
"trophies",
|
||||
"trophy"
|
||||
],
|
||||
[
|
||||
"change_trophy",
|
||||
"trophies",
|
||||
"trophy"
|
||||
],
|
||||
[
|
||||
"delete_trophy",
|
||||
"trophies",
|
||||
"trophy"
|
||||
]
|
||||
]
|
||||
},
|
||||
|
||||
@@ -340,38 +340,3 @@ class RegistrationFormNoCaptcha(UserCreationForm, UserEmailForm):
|
||||
css_class='text-center',
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class FeedbackRegisteredForm(forms.Form):
|
||||
"""
|
||||
Feedback form used for logged-in users
|
||||
"""
|
||||
|
||||
contact = forms.CharField(
|
||||
max_length=50,
|
||||
min_length=10,
|
||||
label=gettext_lazy('Contact'),
|
||||
help_text=gettext_lazy('Some way of answering you (e-mail, etc.)'),
|
||||
required=False,
|
||||
)
|
||||
|
||||
comment = forms.CharField(
|
||||
max_length=500,
|
||||
min_length=10,
|
||||
widget=widgets.Textarea,
|
||||
label=gettext_lazy('Comment'),
|
||||
help_text=gettext_lazy('What do you want to say?'),
|
||||
required=True,
|
||||
)
|
||||
|
||||
|
||||
class FeedbackAnonymousForm(FeedbackRegisteredForm):
|
||||
"""
|
||||
Feedback form used for anonymous users (has additionally a reCAPTCHA field)
|
||||
"""
|
||||
|
||||
captcha = ReCaptchaField(
|
||||
widget=ReCaptchaV3,
|
||||
label='reCaptcha',
|
||||
help_text=gettext_lazy('The form is secured with reCAPTCHA'),
|
||||
)
|
||||
|
||||
@@ -25,6 +25,7 @@ from wger.exercises.models import (
|
||||
ExerciseCategory,
|
||||
Muscle,
|
||||
)
|
||||
from wger.trophies.models import Trophy
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
@@ -58,6 +59,11 @@ class Command(BaseCommand):
|
||||
+ [i for i in WeightUnit.objects.all()]
|
||||
)
|
||||
|
||||
# Trophy data is only translated in the django repo
|
||||
trophy_data = [i.name for i in Trophy.objects.all()] + [
|
||||
i.description for i in Trophy.objects.all()
|
||||
]
|
||||
|
||||
# Make entries unique and sort alphabetically
|
||||
data = sorted(set([i.__str__() for i in data]))
|
||||
|
||||
@@ -67,6 +73,8 @@ class Command(BaseCommand):
|
||||
out = '{% load i18n %}\n'
|
||||
for i in data:
|
||||
out += f'{{% translate "{i}" %}}\n'
|
||||
for i in trophy_data:
|
||||
out += f'{{% translate "{i}" %}}\n'
|
||||
f.write(out)
|
||||
self.stdout.write(self.style.SUCCESS('Wrote content to wger/i18n.tpl'))
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0019_delete_daysofweek'),
|
||||
]
|
||||
@@ -13,6 +12,10 @@ class Migration(migrations.Migration):
|
||||
migrations.AddField(
|
||||
model_name='userprofile',
|
||||
name='trophies_enabled',
|
||||
field=models.BooleanField(default=True, help_text='Enable or disable the trophy system for this user', verbose_name='Enable trophies'),
|
||||
field=models.BooleanField(
|
||||
default=True,
|
||||
help_text='Enable or disable the trophy system for this user',
|
||||
verbose_name='Enable trophies',
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -374,12 +374,12 @@ by the US Department of Agriculture. It is extremely complete, with around
|
||||
behalf over the REST API
|
||||
"""
|
||||
|
||||
# trophies_enabled = models.BooleanField(
|
||||
# default=True,
|
||||
# verbose_name=_('Enable trophies'),
|
||||
# help_text=_('Enable or disable the trophy system for this user'),
|
||||
# )
|
||||
# """Flag to enable or disable trophies for this user"""
|
||||
trophies_enabled = models.BooleanField(
|
||||
default=True,
|
||||
verbose_name=_('Enable trophies'),
|
||||
help_text=_('Enable or disable the trophy system for this user'),
|
||||
)
|
||||
"""Flag to enable or disable trophies for this user"""
|
||||
|
||||
@property
|
||||
def is_trustworthy(self) -> bool:
|
||||
|
||||
55
wger/core/storage.py
Normal file
55
wger/core/storage.py
Normal file
@@ -0,0 +1,55 @@
|
||||
# This file is part of wger Workout Manager.
|
||||
#
|
||||
# wger Workout Manager is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# wger Workout Manager is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
|
||||
# Django
|
||||
from django.contrib.staticfiles.storage import ManifestStaticFilesStorage
|
||||
|
||||
|
||||
class LenientManifestStaticFilesStorage(ManifestStaticFilesStorage):
|
||||
"""
|
||||
Like ManifestStaticFilesStorage but does not raise when an entry or target file
|
||||
referenced from CSS/JS is missing and simply returns the original name in that case.
|
||||
|
||||
This is needed for some node packages that reference files not present (e.g. source maps).
|
||||
"""
|
||||
|
||||
def stored_name(self, name):
|
||||
try:
|
||||
return super().stored_name(name)
|
||||
except Exception:
|
||||
# If the manifest lookup or hashing fails (missing .map etc.), fall back
|
||||
# to the original reference so post-processing doesn't raise.
|
||||
print(
|
||||
f"Can't find name for static file reference: {name}. "
|
||||
f'This is expected in some node packages.'
|
||||
)
|
||||
|
||||
return name
|
||||
|
||||
def url_converter(self, name, hashed_files, template=None):
|
||||
# Wrap the base converter to ignore any errors during conversion and
|
||||
# return the original matched text unchanged.
|
||||
base_converter = super().url_converter(name, hashed_files, template)
|
||||
|
||||
def converter(matchobj):
|
||||
try:
|
||||
return base_converter(matchobj)
|
||||
except Exception:
|
||||
print(
|
||||
f"Can't find name for static file reference: {matchobj.group(0)}. "
|
||||
f'This is expected in some node packages.'
|
||||
)
|
||||
return matchobj.groupdict().get('matched', matchobj.group(0))
|
||||
|
||||
return converter
|
||||
@@ -395,6 +395,16 @@
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if perms.trophies.change_trophy %}
|
||||
<li>
|
||||
<a class="dropdown-item"
|
||||
href="{% url 'trophies:admin-overview' %}">
|
||||
{% translate "Trophies" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
{% load i18n static wger_extras compress django_bootstrap_breadcrumbs %}
|
||||
{% load i18n static wger_extras django_bootstrap_breadcrumbs %}
|
||||
{% block breadcrumbs %}
|
||||
{% clear_breadcrumbs %}
|
||||
{% endblock %}
|
||||
@@ -27,6 +27,8 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link rel="icon" href="{% static 'images/favicon.png' %}" type="image/png">
|
||||
|
||||
<!-- OpenGraph -->
|
||||
{% block opengraph %}
|
||||
<meta property="og:url" content="{{ request_absolute_path }}">
|
||||
@@ -63,19 +65,10 @@
|
||||
|
||||
{% block header %}{% endblock %}
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
|
||||
if (typeof wgerCustomPageInit !== "undefined") {
|
||||
wgerCustomPageInit();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<title>{% block title %}{% endblock %}</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{# #}
|
||||
{# Navigation #}
|
||||
{# #}
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
-->
|
||||
|
||||
|
||||
{% load i18n static compress %}
|
||||
{% load i18n static %}
|
||||
<html lang="{{ language.short_name }}">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<meta charset="utf-8">
|
||||
<meta name="author" content="wger team">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link rel="icon" href="{% static 'images/favicon.png' %}" type="image/png">
|
||||
|
||||
<!-- OpenGraph -->
|
||||
{% block opengraph %}
|
||||
@@ -43,19 +43,12 @@
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'bootstrap-compiled.css' %}">
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'fontawesomefree/css/all.css' %}">
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'css/landing_page.css' %}">
|
||||
|
||||
{% compress css %}
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'bootstrap-compiled.css' %}">
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'fontawesomefree/css/all.css' %}">
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'css/landing_page.css' %}">
|
||||
{% endcompress %}
|
||||
|
||||
<link rel="icon" href="{% static 'images/favicon.png' %}" type="image/png">
|
||||
|
||||
{% compress js %}
|
||||
<script src="{% static 'node/bootstrap/dist/js/bootstrap.bundle.min.js' %}"></script>
|
||||
<script src="{% static 'node/@popperjs/core/dist/umd/popper.js' %}"></script>
|
||||
{% endcompress %}
|
||||
<script src="{% static 'node/bootstrap/dist/js/bootstrap.bundle.min.js' %}"></script>
|
||||
<script src="{% static 'node/@popperjs/core/dist/umd/popper.js' %}"></script>
|
||||
|
||||
<title>wger Workout Manager - {% translate "Features" %}</title>
|
||||
</head>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
{% load i18n static wger_extras compress django_bootstrap_breadcrumbs %}
|
||||
{% load i18n static wger_extras django_bootstrap_breadcrumbs %}
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
# This file is part of wger Workout Manager.
|
||||
#
|
||||
# wger Workout Manager is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# wger Workout Manager is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
|
||||
# Standard Library
|
||||
from unittest import skip
|
||||
|
||||
# Django
|
||||
from django.core import mail
|
||||
from django.urls import reverse
|
||||
|
||||
# wger
|
||||
from wger.core.tests.base_testcase import WgerTestCase
|
||||
|
||||
|
||||
class FeedbackTestCase(WgerTestCase):
|
||||
"""
|
||||
Tests the feedback form
|
||||
"""
|
||||
|
||||
def send_feedback(self, logged_in=True):
|
||||
"""
|
||||
Helper function
|
||||
"""
|
||||
response = self.client.get(reverse('core:feedback'))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.post(
|
||||
reverse('core:feedback'),
|
||||
{'comment': 'A very long and interesting comment'},
|
||||
)
|
||||
if logged_in:
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
response = self.client.get(response['Location'])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Short comment
|
||||
response = self.client.post(reverse('core:feedback'), {'comment': '12345'})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(response.context['form'].errors), 1)
|
||||
else:
|
||||
# No recaptcha field
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(mail.outbox), 0)
|
||||
|
||||
# Correctly filled in reCaptcha
|
||||
response = self.client.post(
|
||||
reverse('core:feedback'),
|
||||
{
|
||||
'comment': 'A very long and interesting comment',
|
||||
'g-recaptcha-response': 'PASSED',
|
||||
},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
response = self.client.get(response['Location'])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_send_feedback_admin(self):
|
||||
"""
|
||||
Tests the feedback form as an admin user
|
||||
"""
|
||||
|
||||
self.user_login('admin')
|
||||
self.send_feedback()
|
||||
|
||||
def test_send_feedback_user(self):
|
||||
"""
|
||||
Tests the feedback form as a regular user
|
||||
"""
|
||||
|
||||
self.user_login('test')
|
||||
self.send_feedback()
|
||||
|
||||
@skip('Failing due to recaptcha issues')
|
||||
def test_send_feedback_logged_out(self):
|
||||
"""
|
||||
Tests the feedback form as a logged out user
|
||||
"""
|
||||
|
||||
self.send_feedback(logged_in=False)
|
||||
@@ -197,19 +197,12 @@ patterns_weight_units = [
|
||||
urlpatterns = [
|
||||
# The landing page
|
||||
path('', misc.index, name='index'),
|
||||
# The dashboard
|
||||
path('dashboard', ReactView.as_view(login_required=True), name='dashboard'),
|
||||
# Others
|
||||
path(
|
||||
'imprint',
|
||||
TemplateView.as_view(template_name='misc/about.html'),
|
||||
name='imprint',
|
||||
),
|
||||
path(
|
||||
'feedback',
|
||||
misc.FeedbackClass.as_view(),
|
||||
name='feedback',
|
||||
),
|
||||
path('language/', include((patterns_language, 'language'), namespace='language')),
|
||||
path('user/', include((patterns_user, 'user'), namespace='user')),
|
||||
path('license/', include((patterns_license, 'license'), namespace='license')),
|
||||
|
||||
@@ -21,32 +21,15 @@ import logging
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth import login as django_login
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.core import mail
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import render
|
||||
from django.template.loader import render_to_string
|
||||
from django.urls import (
|
||||
reverse,
|
||||
reverse_lazy,
|
||||
)
|
||||
from django.utils.text import slugify
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext as _
|
||||
from django.views.generic.edit import FormView
|
||||
|
||||
# Third Party
|
||||
from crispy_forms.helper import FormHelper
|
||||
from crispy_forms.layout import Submit
|
||||
|
||||
# wger
|
||||
from wger.core.demo import (
|
||||
create_demo_entries,
|
||||
create_temporary_user,
|
||||
)
|
||||
from wger.core.forms import (
|
||||
FeedbackAnonymousForm,
|
||||
FeedbackRegisteredForm,
|
||||
)
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -94,57 +77,3 @@ def demo_entries(request):
|
||||
),
|
||||
)
|
||||
return HttpResponseRedirect(reverse('core:dashboard'))
|
||||
|
||||
|
||||
class FeedbackClass(FormView):
|
||||
template_name = 'form.html'
|
||||
success_url = reverse_lazy('software:about-us')
|
||||
|
||||
def get_initial(self):
|
||||
"""
|
||||
Fill in the contact, if available
|
||||
"""
|
||||
if self.request.user.is_authenticated:
|
||||
return {'contact': self.request.user.email}
|
||||
return {}
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
"""
|
||||
Set necessary template data to correctly render the form
|
||||
"""
|
||||
context = super(FeedbackClass, self).get_context_data(**kwargs)
|
||||
context['title'] = _('Feedback')
|
||||
return context
|
||||
|
||||
def get_form_class(self):
|
||||
"""
|
||||
Load the correct feedback form depending on the user
|
||||
(either with reCaptcha field or not)
|
||||
"""
|
||||
if self.request.user.is_anonymous or self.request.user.userprofile.is_temporary:
|
||||
return FeedbackAnonymousForm
|
||||
else:
|
||||
return FeedbackRegisteredForm
|
||||
|
||||
def get_form(self, form_class=None):
|
||||
"""Return an instance of the form to be used in this view."""
|
||||
|
||||
form = super(FeedbackClass, self).get_form(form_class)
|
||||
form.helper = FormHelper()
|
||||
form.helper.form_id = slugify(self.request.path)
|
||||
form.helper.add_input(Submit('submit', _('Submit'), css_class='btn-success btn-block'))
|
||||
form.helper.form_class = 'wger-form'
|
||||
return form
|
||||
|
||||
def form_valid(self, form):
|
||||
"""
|
||||
Send the feedback to the administrators
|
||||
"""
|
||||
messages.success(self.request, _('Your feedback was successfully sent. Thank you!'))
|
||||
|
||||
context = {'user': self.request.user, 'form_data': form.cleaned_data}
|
||||
subject = 'New feedback'
|
||||
message = render_to_string('user/email_feedback.html', context)
|
||||
mail.mail_admins(subject, message)
|
||||
|
||||
return super(FeedbackClass, self).form_valid(form)
|
||||
|
||||
@@ -31,10 +31,7 @@ from django.db import (
|
||||
)
|
||||
from django.db.models import Q
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import (
|
||||
get_language,
|
||||
gettext_lazy as _,
|
||||
)
|
||||
from django.utils.translation import get_language
|
||||
|
||||
# Third Party
|
||||
from simple_history.models import HistoricalRecords
|
||||
@@ -83,20 +80,20 @@ class Exercise(AbstractLicenseModel, AbstractHistoryMixin, models.Model):
|
||||
|
||||
category = models.ForeignKey(
|
||||
ExerciseCategory,
|
||||
verbose_name=_('Category'),
|
||||
verbose_name='Category',
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
muscles = models.ManyToManyField(
|
||||
Muscle,
|
||||
blank=True,
|
||||
verbose_name=_('Primary muscles'),
|
||||
verbose_name='Primary muscles',
|
||||
)
|
||||
"""Main muscles trained by the exercise"""
|
||||
|
||||
muscles_secondary = models.ManyToManyField(
|
||||
Muscle,
|
||||
verbose_name=_('Secondary muscles'),
|
||||
verbose_name='Secondary muscles',
|
||||
related_name='secondary_muscles_base',
|
||||
blank=True,
|
||||
)
|
||||
@@ -104,14 +101,14 @@ class Exercise(AbstractLicenseModel, AbstractHistoryMixin, models.Model):
|
||||
|
||||
equipment = models.ManyToManyField(
|
||||
Equipment,
|
||||
verbose_name=_('Equipment'),
|
||||
verbose_name='Equipment',
|
||||
blank=True,
|
||||
)
|
||||
"""Equipment needed by this exercise"""
|
||||
|
||||
variations = models.ForeignKey(
|
||||
Variation,
|
||||
verbose_name=_('Variations'),
|
||||
verbose_name='Variations',
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
@@ -119,13 +116,13 @@ class Exercise(AbstractLicenseModel, AbstractHistoryMixin, models.Model):
|
||||
"""Variations of this exercise"""
|
||||
|
||||
created = models.DateTimeField(
|
||||
_('Date'),
|
||||
'Creation date',
|
||||
auto_now_add=True,
|
||||
)
|
||||
"""The submission datetime"""
|
||||
|
||||
last_update = models.DateTimeField(
|
||||
_('Date'),
|
||||
'last update',
|
||||
auto_now=True,
|
||||
)
|
||||
"""Datetime of last modification"""
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
# Django
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class ExerciseCategory(models.Model):
|
||||
@@ -26,12 +25,12 @@ class ExerciseCategory(models.Model):
|
||||
|
||||
name = models.CharField(
|
||||
max_length=100,
|
||||
verbose_name=_('Name'),
|
||||
verbose_name='Name',
|
||||
)
|
||||
|
||||
# Metaclass to set some other properties
|
||||
class Meta:
|
||||
verbose_name_plural = _('Exercise Categories')
|
||||
verbose_name_plural = 'Exercise Categories'
|
||||
ordering = [
|
||||
'name',
|
||||
]
|
||||
|
||||
@@ -19,7 +19,6 @@ import uuid
|
||||
|
||||
# Django
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# Third Party
|
||||
from simple_history.models import HistoricalRecords
|
||||
@@ -46,14 +45,14 @@ class ExerciseComment(models.Model):
|
||||
|
||||
translation = models.ForeignKey(
|
||||
Translation,
|
||||
verbose_name=_('Exercise'),
|
||||
verbose_name='Exercise',
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
comment = models.CharField(
|
||||
max_length=200,
|
||||
verbose_name=_('Comment'),
|
||||
help_text=_('A comment about how to correctly do this exercise.'),
|
||||
verbose_name='Comment',
|
||||
help_text='A comment about how to correctly do this exercise.',
|
||||
)
|
||||
|
||||
history = HistoricalRecords()
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
# Django
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class Equipment(models.Model):
|
||||
@@ -26,7 +25,7 @@ class Equipment(models.Model):
|
||||
|
||||
name = models.CharField(
|
||||
max_length=50,
|
||||
verbose_name=_('Name'),
|
||||
verbose_name='Name',
|
||||
)
|
||||
|
||||
class Meta:
|
||||
|
||||
@@ -20,7 +20,6 @@ import uuid
|
||||
# Django
|
||||
from django.contrib.postgres.indexes import GinIndex
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# Third Party
|
||||
from simple_history.models import HistoricalRecords
|
||||
@@ -47,13 +46,13 @@ class Alias(models.Model):
|
||||
|
||||
translation = models.ForeignKey(
|
||||
Translation,
|
||||
verbose_name=_('Exercise'),
|
||||
verbose_name='Exercise',
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
alias = models.CharField(
|
||||
max_length=200,
|
||||
verbose_name=_('Alias for an exercise'),
|
||||
verbose_name='Alias for an exercise',
|
||||
)
|
||||
|
||||
history = HistoricalRecords()
|
||||
|
||||
@@ -20,7 +20,6 @@ import uuid
|
||||
|
||||
# Django
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# Third Party
|
||||
from simple_history.models import HistoricalRecords
|
||||
@@ -55,11 +54,11 @@ class ExerciseImage(AbstractLicenseModel, AbstractHistoryMixin, models.Model, Ba
|
||||
PHOTO = '4'
|
||||
OTHER = '5'
|
||||
STYLE = (
|
||||
(LINE_ART, _('Line')),
|
||||
(THREE_D, _('3D')),
|
||||
(LOW_POLY, _('Low-poly')),
|
||||
(PHOTO, _('Photo')),
|
||||
(OTHER, _('Other')),
|
||||
(LINE_ART, 'Line'),
|
||||
(THREE_D, '3D'),
|
||||
(LOW_POLY, 'Low-poly'),
|
||||
(PHOTO, 'Photo'),
|
||||
(OTHER, 'Other'),
|
||||
)
|
||||
|
||||
uuid = models.UUIDField(
|
||||
@@ -72,13 +71,13 @@ class ExerciseImage(AbstractLicenseModel, AbstractHistoryMixin, models.Model, Ba
|
||||
|
||||
exercise = models.ForeignKey(
|
||||
Exercise,
|
||||
verbose_name=_('Exercise'),
|
||||
verbose_name='Exercise',
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
"""The exercise the image belongs to"""
|
||||
|
||||
image = models.ImageField(
|
||||
verbose_name=_('Image'),
|
||||
verbose_name='Image',
|
||||
help_text='Only JPEG, PNG and WebP formats are supported',
|
||||
upload_to=exercise_image_upload_dir,
|
||||
validators=[validate_image_static_no_animation],
|
||||
@@ -88,7 +87,7 @@ class ExerciseImage(AbstractLicenseModel, AbstractHistoryMixin, models.Model, Ba
|
||||
"""Uploaded image"""
|
||||
|
||||
height = models.PositiveIntegerField(
|
||||
verbose_name=_('Height'),
|
||||
verbose_name='Height',
|
||||
null=True,
|
||||
blank=True,
|
||||
editable=False,
|
||||
@@ -96,7 +95,7 @@ class ExerciseImage(AbstractLicenseModel, AbstractHistoryMixin, models.Model, Ba
|
||||
"""Image height"""
|
||||
|
||||
width = models.PositiveIntegerField(
|
||||
verbose_name=_('Width'),
|
||||
verbose_name='Width',
|
||||
null=True,
|
||||
blank=True,
|
||||
editable=False,
|
||||
@@ -104,7 +103,7 @@ class ExerciseImage(AbstractLicenseModel, AbstractHistoryMixin, models.Model, Ba
|
||||
"""Image width"""
|
||||
|
||||
is_main = models.BooleanField(
|
||||
verbose_name=_('Main picture'),
|
||||
verbose_name='Is main picture',
|
||||
default=False,
|
||||
)
|
||||
"""A flag indicating whether the image is the exercise's main image"""
|
||||
|
||||
@@ -23,7 +23,6 @@ from django.core.validators import MinLengthValidator
|
||||
from django.db import models
|
||||
from django.urls import reverse
|
||||
from django.utils.text import slugify
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# Third Party
|
||||
import bleach
|
||||
@@ -46,32 +45,32 @@ class Translation(AbstractLicenseModel, AbstractHistoryMixin, models.Model):
|
||||
|
||||
description = models.TextField(
|
||||
max_length=2000,
|
||||
verbose_name=_('Description'),
|
||||
verbose_name='Description',
|
||||
validators=[MinLengthValidator(40)],
|
||||
)
|
||||
"""Description on how to perform the exercise"""
|
||||
|
||||
name = models.CharField(
|
||||
verbose_name='Name',
|
||||
max_length=200,
|
||||
verbose_name=_('Name'),
|
||||
)
|
||||
"""The exercise's name"""
|
||||
|
||||
created = models.DateTimeField(
|
||||
_('Date'),
|
||||
verbose_name='Date',
|
||||
auto_now_add=True,
|
||||
)
|
||||
"""The submission date"""
|
||||
|
||||
last_update = models.DateTimeField(
|
||||
_('Date'),
|
||||
verbose_name='Date',
|
||||
auto_now=True,
|
||||
)
|
||||
"""Datetime of the last modification"""
|
||||
|
||||
language = models.ForeignKey(
|
||||
Language,
|
||||
verbose_name=_('Language'),
|
||||
verbose_name='Language',
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
"""The exercise's language"""
|
||||
|
||||
@@ -95,33 +95,33 @@ class ExerciseVideo(AbstractLicenseModel, AbstractHistoryMixin, models.Model):
|
||||
|
||||
exercise = models.ForeignKey(
|
||||
Exercise,
|
||||
verbose_name=_('Exercise'),
|
||||
verbose_name='Exercise',
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
"""The exercise the video belongs to"""
|
||||
|
||||
is_main = models.BooleanField(
|
||||
verbose_name=_('Main video'),
|
||||
verbose_name='Is main video',
|
||||
default=False,
|
||||
)
|
||||
"""A flag indicating whether the video is the exercise's main one"""
|
||||
|
||||
video = models.FileField(
|
||||
verbose_name=_('Video'),
|
||||
verbose_name='Video',
|
||||
upload_to=exercise_video_upload_dir,
|
||||
validators=[validate_video],
|
||||
)
|
||||
"""Uploaded video"""
|
||||
|
||||
size = models.IntegerField(
|
||||
verbose_name=_('Size'),
|
||||
verbose_name='Size',
|
||||
default=0,
|
||||
editable=False,
|
||||
)
|
||||
"""The video filesize, in bytes"""
|
||||
|
||||
duration = models.DecimalField(
|
||||
verbose_name=_('Duration'),
|
||||
verbose_name='Duration',
|
||||
default=0,
|
||||
editable=False,
|
||||
max_digits=12,
|
||||
@@ -130,21 +130,21 @@ class ExerciseVideo(AbstractLicenseModel, AbstractHistoryMixin, models.Model):
|
||||
"""The video duration, in seconds"""
|
||||
|
||||
width = models.IntegerField(
|
||||
verbose_name=_('Width'),
|
||||
verbose_name='Width',
|
||||
default=0,
|
||||
editable=False,
|
||||
)
|
||||
"""The video width, in pixels"""
|
||||
|
||||
height = models.IntegerField(
|
||||
verbose_name=_('Height'),
|
||||
verbose_name='Height',
|
||||
default=0,
|
||||
editable=False,
|
||||
)
|
||||
"""The video height, in pixels"""
|
||||
|
||||
codec = models.CharField(
|
||||
verbose_name=_('Codec'),
|
||||
verbose_name='Codec',
|
||||
max_length=30,
|
||||
default='',
|
||||
editable=False,
|
||||
@@ -152,7 +152,7 @@ class ExerciseVideo(AbstractLicenseModel, AbstractHistoryMixin, models.Model):
|
||||
"""The video codec"""
|
||||
|
||||
codec_long = models.CharField(
|
||||
verbose_name=_('Codec, long name'),
|
||||
verbose_name='Codec, long name',
|
||||
max_length=100,
|
||||
default='',
|
||||
editable=False,
|
||||
@@ -160,13 +160,13 @@ class ExerciseVideo(AbstractLicenseModel, AbstractHistoryMixin, models.Model):
|
||||
"""The video codec, in full"""
|
||||
|
||||
created = models.DateTimeField(
|
||||
_('Date'),
|
||||
verbose_name='Date',
|
||||
auto_now_add=True,
|
||||
)
|
||||
"""The creation time"""
|
||||
|
||||
last_update = models.DateTimeField(
|
||||
_('Date'),
|
||||
verbose_name='Date',
|
||||
auto_now=True,
|
||||
)
|
||||
"""Datetime of last modification"""
|
||||
|
||||
@@ -23,7 +23,6 @@ import uuid
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import models
|
||||
from django.dispatch import receiver
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# wger
|
||||
from wger.utils.images import validate_image_static_no_animation
|
||||
@@ -42,17 +41,20 @@ class Image(models.Model):
|
||||
'-date',
|
||||
]
|
||||
|
||||
date = models.DateField(_('Date'), default=datetime.datetime.now)
|
||||
date = models.DateField(
|
||||
verbose_name='Date',
|
||||
default=datetime.datetime.now,
|
||||
)
|
||||
|
||||
user = models.ForeignKey(
|
||||
User,
|
||||
verbose_name=_('User'),
|
||||
verbose_name='User',
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
image = models.ImageField(
|
||||
verbose_name=_('Image'),
|
||||
help_text=_('Only PNG and JPEG formats are supported'),
|
||||
verbose_name='Image',
|
||||
help_text='Only PNG and JPEG formats are supported',
|
||||
upload_to=gallery_upload_dir,
|
||||
height_field='height',
|
||||
width_field='width',
|
||||
@@ -66,7 +68,7 @@ class Image(models.Model):
|
||||
"""Width of the image"""
|
||||
|
||||
description = models.TextField(
|
||||
verbose_name=_('Description'),
|
||||
verbose_name='Description',
|
||||
max_length=1000,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
@@ -38,3 +38,45 @@
|
||||
{% translate "kg" %}
|
||||
{% translate "lb" %}
|
||||
{% translate "none (bodyweight exercise)" %}
|
||||
{% translate "Beginner" %}
|
||||
{% translate "Consistent" %}
|
||||
{% translate "Dedicated" %}
|
||||
{% translate "Obsessed" %}
|
||||
{% translate "Legend" %}
|
||||
{% translate "Veteran" %}
|
||||
{% translate "Titan" %}
|
||||
{% translate "Unstoppable" %}
|
||||
{% translate "Weekend Warrior" %}
|
||||
{% translate "Elephant lifter" %}
|
||||
{% translate "Bus lifter" %}
|
||||
{% translate "Plane lifter" %}
|
||||
{% translate "Blue whale lifter" %}
|
||||
{% translate "Space Station lifter" %}
|
||||
{% translate "Millionaire" %}
|
||||
{% translate "Atlas" %}
|
||||
{% translate "Early Bird" %}
|
||||
{% translate "Night Owl" %}
|
||||
{% translate "New Year, New Me" %}
|
||||
{% translate "Phoenix" %}
|
||||
{% translate "Personal Record" %}
|
||||
{% translate "Complete your first workout" %}
|
||||
{% translate "Complete 10 workouts" %}
|
||||
{% translate "Complete 50 workouts" %}
|
||||
{% translate "Complete 100 workouts" %}
|
||||
{% translate "Complete 200 workouts" %}
|
||||
{% translate "Complete 500 workouts" %}
|
||||
{% translate "Complete 1000 workouts" %}
|
||||
{% translate "Maintain a 30-day workout streak" %}
|
||||
{% translate "Work out on Saturday and Sunday for 4 consecutive weekends" %}
|
||||
{% translate "Lift a cumulative total of 5.000 kg" %}
|
||||
{% translate "Lift a cumulative total of 20.000 kg" %}
|
||||
{% translate "Lift a cumulative total of 50.000 kg" %}
|
||||
{% translate "Lift a cumulative total of 150.000 kg" %}
|
||||
{% translate "Lift a cumulative total of 450.000 kg" %}
|
||||
{% translate "Lift a cumulative total of 1.000.000 kg" %}
|
||||
{% translate "Lift a cumulative total of 10.000.000 kg" %}
|
||||
{% translate "Complete a workout before 6:00 AM" %}
|
||||
{% translate "Complete a workout after 9:00 PM" %}
|
||||
{% translate "Work out on January 1st" %}
|
||||
{% translate "Return to training after being inactive for 30 days" %}
|
||||
{% translate "Achieve a new Personal Record on any exercise" %}
|
||||
|
||||
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
@@ -19,7 +19,6 @@ from typing import List
|
||||
|
||||
# Django
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# wger
|
||||
from wger.manager.dataclasses import SlotData
|
||||
@@ -48,7 +47,7 @@ class Day(models.Model):
|
||||
|
||||
routine = models.ForeignKey(
|
||||
'Routine',
|
||||
verbose_name=_('Routine'),
|
||||
verbose_name='Routine',
|
||||
on_delete=models.CASCADE,
|
||||
related_name='days',
|
||||
)
|
||||
@@ -56,7 +55,7 @@ class Day(models.Model):
|
||||
order = models.PositiveIntegerField(
|
||||
default=1,
|
||||
null=False,
|
||||
verbose_name=_('Order'),
|
||||
verbose_name='Order',
|
||||
db_index=True,
|
||||
)
|
||||
|
||||
@@ -69,13 +68,13 @@ class Day(models.Model):
|
||||
|
||||
name = models.CharField(
|
||||
max_length=20,
|
||||
verbose_name=_('Name'),
|
||||
verbose_name='Name',
|
||||
blank=True, # needed for rest days
|
||||
)
|
||||
|
||||
description = models.CharField(
|
||||
max_length=1000,
|
||||
verbose_name=_('Description'),
|
||||
verbose_name='Description',
|
||||
blank=True,
|
||||
)
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import datetime
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# wger
|
||||
from wger.core.models import (
|
||||
@@ -50,13 +49,13 @@ class WorkoutLog(models.Model):
|
||||
objects = WorkoutLogManager()
|
||||
|
||||
date = models.DateTimeField(
|
||||
verbose_name=_('Date'),
|
||||
verbose_name='Date',
|
||||
default=datetime.datetime.now,
|
||||
)
|
||||
|
||||
user = models.ForeignKey(
|
||||
User,
|
||||
verbose_name=_('User'),
|
||||
verbose_name='User',
|
||||
editable=False,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
@@ -75,7 +74,7 @@ class WorkoutLog(models.Model):
|
||||
|
||||
session = models.ForeignKey(
|
||||
'WorkoutSession',
|
||||
verbose_name=_('Session'),
|
||||
verbose_name='Session',
|
||||
on_delete=models.CASCADE,
|
||||
null=True,
|
||||
related_name='logs',
|
||||
@@ -88,13 +87,13 @@ class WorkoutLog(models.Model):
|
||||
|
||||
exercise = models.ForeignKey(
|
||||
Exercise,
|
||||
verbose_name=_('Exercise'),
|
||||
verbose_name='Exercise',
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
routine = models.ForeignKey(
|
||||
'Routine',
|
||||
verbose_name=_('Workout'),
|
||||
verbose_name='Workout',
|
||||
on_delete=models.CASCADE,
|
||||
null=True,
|
||||
)
|
||||
@@ -111,7 +110,7 @@ class WorkoutLog(models.Model):
|
||||
|
||||
repetitions_unit = models.ForeignKey(
|
||||
RepetitionUnit,
|
||||
verbose_name=_('Unit'),
|
||||
verbose_name='Repetitions unit',
|
||||
default=REP_UNIT_REPETITIONS,
|
||||
on_delete=models.CASCADE,
|
||||
null=True,
|
||||
@@ -135,7 +134,7 @@ class WorkoutLog(models.Model):
|
||||
repetitions_target = models.DecimalField(
|
||||
max_digits=6,
|
||||
decimal_places=2,
|
||||
verbose_name=_('Repetitions'),
|
||||
verbose_name='Repetitions target',
|
||||
validators=[NullMinValueValidator(0)],
|
||||
null=True,
|
||||
blank=True,
|
||||
@@ -146,7 +145,7 @@ class WorkoutLog(models.Model):
|
||||
|
||||
weight_unit = models.ForeignKey(
|
||||
WeightUnit,
|
||||
verbose_name=_('Unit'),
|
||||
verbose_name='Weight unit',
|
||||
default=WEIGHT_UNIT_KG,
|
||||
on_delete=models.CASCADE,
|
||||
null=True,
|
||||
@@ -170,7 +169,7 @@ class WorkoutLog(models.Model):
|
||||
weight_target = models.DecimalField(
|
||||
max_digits=6,
|
||||
decimal_places=2,
|
||||
verbose_name=_('Weight'),
|
||||
verbose_name='Weight target',
|
||||
validators=[NullMinValueValidator(0)],
|
||||
null=True,
|
||||
blank=True,
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Django
|
||||
from django.core.validators import (
|
||||
MaxValueValidator,
|
||||
|
||||
@@ -74,48 +74,46 @@ class Routine(models.Model):
|
||||
|
||||
user = models.ForeignKey(
|
||||
User,
|
||||
verbose_name=_('User'),
|
||||
verbose_name='User',
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
name = models.CharField(
|
||||
verbose_name=_('Name'),
|
||||
verbose_name='Name',
|
||||
max_length=25,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
description = models.TextField(
|
||||
verbose_name=_('Description'),
|
||||
verbose_name='Description',
|
||||
max_length=1000,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
created = models.DateTimeField(
|
||||
_('Creation date'),
|
||||
verbose_name='Creation date',
|
||||
auto_now_add=True,
|
||||
)
|
||||
|
||||
start = models.DateField(
|
||||
_('Start date'),
|
||||
verbose_name='Start date',
|
||||
)
|
||||
|
||||
end = models.DateField(
|
||||
_('End date'),
|
||||
verbose_name='End date',
|
||||
)
|
||||
|
||||
is_template = models.BooleanField(
|
||||
verbose_name=_('Workout template'),
|
||||
help_text=_(
|
||||
'Marking a workout as a template will freeze it and allow you to make copies of it'
|
||||
),
|
||||
verbose_name='Workout template',
|
||||
help_text='Marking a workout as a template will freeze it and allow you to make copies of it',
|
||||
default=False,
|
||||
null=False,
|
||||
)
|
||||
"""Marking a workout as a template will freeze it and allow you to make copies of it"""
|
||||
|
||||
is_public = models.BooleanField(
|
||||
verbose_name=_('Public template'),
|
||||
help_text=_('A public template is available to other users'),
|
||||
verbose_name='Public template',
|
||||
help_text='A public template is available to other users',
|
||||
default=False,
|
||||
null=False,
|
||||
)
|
||||
|
||||
@@ -44,7 +44,7 @@ class WorkoutSession(models.Model):
|
||||
|
||||
user = models.ForeignKey(
|
||||
User,
|
||||
verbose_name=_('User'),
|
||||
verbose_name='User',
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
"""
|
||||
@@ -70,7 +70,7 @@ class WorkoutSession(models.Model):
|
||||
"""
|
||||
|
||||
date = models.DateField(
|
||||
verbose_name=_('Date'),
|
||||
verbose_name='Date',
|
||||
default=datetime.date.today,
|
||||
)
|
||||
"""
|
||||
@@ -78,30 +78,28 @@ class WorkoutSession(models.Model):
|
||||
"""
|
||||
|
||||
notes = models.TextField(
|
||||
verbose_name=_('Notes'),
|
||||
verbose_name='Notes',
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text=_('Any notes you might want to save about this workout session.'),
|
||||
help_text='Any notes you might want to save about this workout session.',
|
||||
)
|
||||
"""
|
||||
User notes about the workout
|
||||
"""
|
||||
|
||||
impression = models.CharField(
|
||||
verbose_name=_('General impression'),
|
||||
verbose_name='General impression',
|
||||
max_length=2,
|
||||
choices=IMPRESSION,
|
||||
default=IMPRESSION_NEUTRAL,
|
||||
help_text=_(
|
||||
'Your impression about this workout session. Did you exercise as well as you could?'
|
||||
),
|
||||
help_text='Your impression about this workout session. Did you exercise as well as you could?',
|
||||
)
|
||||
"""
|
||||
The user's general impression of workout
|
||||
"""
|
||||
|
||||
time_start = models.TimeField(
|
||||
verbose_name=_('Start time'),
|
||||
verbose_name='Start time',
|
||||
blank=True,
|
||||
null=True,
|
||||
)
|
||||
@@ -110,7 +108,7 @@ class WorkoutSession(models.Model):
|
||||
"""
|
||||
|
||||
time_end = models.TimeField(
|
||||
verbose_name=_('Finish time'),
|
||||
verbose_name='Finish time',
|
||||
blank=True,
|
||||
null=True,
|
||||
)
|
||||
|
||||
@@ -3,7 +3,6 @@ from typing import List
|
||||
|
||||
# Django
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# wger
|
||||
from wger.manager.dataclasses import (
|
||||
@@ -23,7 +22,7 @@ class Slot(models.Model):
|
||||
|
||||
day = models.ForeignKey(
|
||||
Day,
|
||||
verbose_name=_('Exercise day'),
|
||||
verbose_name='Exercise day',
|
||||
on_delete=models.CASCADE,
|
||||
related_name='slots',
|
||||
)
|
||||
@@ -31,13 +30,13 @@ class Slot(models.Model):
|
||||
order = models.PositiveIntegerField(
|
||||
default=1,
|
||||
null=False,
|
||||
verbose_name=_('Order'),
|
||||
verbose_name='Order',
|
||||
db_index=True,
|
||||
)
|
||||
|
||||
comment = models.CharField(
|
||||
max_length=200,
|
||||
verbose_name=_('Comment'),
|
||||
verbose_name='Comment',
|
||||
blank=True,
|
||||
)
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ from typing import (
|
||||
from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# wger
|
||||
from wger.core.models import (
|
||||
@@ -119,7 +118,7 @@ class SlotEntry(models.Model):
|
||||
|
||||
weight_unit = models.ForeignKey(
|
||||
WeightUnit,
|
||||
verbose_name=_('Unit'),
|
||||
verbose_name='Unit',
|
||||
default=WEIGHT_UNIT_KG,
|
||||
on_delete=models.CASCADE,
|
||||
null=True,
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
# Django
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class Category(models.Model):
|
||||
@@ -28,17 +27,17 @@ class Category(models.Model):
|
||||
|
||||
user = models.ForeignKey(
|
||||
User,
|
||||
verbose_name=_('User'),
|
||||
verbose_name='User',
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
name = models.CharField(
|
||||
verbose_name=_('Name'),
|
||||
verbose_name='Name',
|
||||
max_length=100,
|
||||
)
|
||||
|
||||
unit = models.CharField(
|
||||
verbose_name=_('Unit'),
|
||||
verbose_name='Unit',
|
||||
max_length=30,
|
||||
)
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ from django.core.validators import (
|
||||
MinValueValidator,
|
||||
)
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# wger
|
||||
from wger.measurements.models import Category
|
||||
@@ -38,17 +37,17 @@ class Measurement(models.Model):
|
||||
|
||||
category = models.ForeignKey(
|
||||
Category,
|
||||
verbose_name=_('User'),
|
||||
verbose_name='User',
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
date = models.DateField(
|
||||
_('Date'),
|
||||
verbose_name='Date',
|
||||
default=datetime.datetime.now,
|
||||
)
|
||||
|
||||
value = models.DecimalField(
|
||||
verbose_name=_('Value'),
|
||||
verbose_name='Value',
|
||||
max_digits=6,
|
||||
decimal_places=2,
|
||||
validators=[
|
||||
@@ -58,7 +57,7 @@ class Measurement(models.Model):
|
||||
)
|
||||
|
||||
notes = models.CharField(
|
||||
verbose_name=_('Description'),
|
||||
verbose_name='Description',
|
||||
max_length=100,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
@@ -20,7 +20,6 @@ import uuid
|
||||
|
||||
# Django
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# wger
|
||||
from wger.utils.helpers import BaseImage
|
||||
@@ -56,8 +55,8 @@ class Image(AbstractLicenseModel, models.Model, BaseImage):
|
||||
"""Image for this ingredient"""
|
||||
|
||||
image = models.ImageField(
|
||||
verbose_name=_('Image'),
|
||||
help_text=_('Only PNG and JPEG formats are supported'),
|
||||
verbose_name='Image',
|
||||
help_text='Only PNG and JPEG formats are supported',
|
||||
upload_to=ingredient_image_upload_dir,
|
||||
height_field='height',
|
||||
width_field='width',
|
||||
|
||||
@@ -34,7 +34,6 @@ from django.db import models
|
||||
from django.http import HttpRequest
|
||||
from django.urls import reverse
|
||||
from django.utils.text import slugify
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# Third Party
|
||||
from openfoodfacts import API
|
||||
@@ -78,19 +77,19 @@ class Ingredient(AbstractLicenseModel, models.Model):
|
||||
|
||||
language = models.ForeignKey(
|
||||
Language,
|
||||
verbose_name=_('Language'),
|
||||
verbose_name='Language',
|
||||
editable=False,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
created = models.DateTimeField(
|
||||
_('Date'),
|
||||
verbose_name='Date',
|
||||
auto_now_add=True,
|
||||
)
|
||||
"""Date when the ingredient was created"""
|
||||
|
||||
last_update = models.DateTimeField(
|
||||
_('Date'),
|
||||
'Date',
|
||||
auto_now=True,
|
||||
blank=True,
|
||||
editable=False,
|
||||
@@ -123,28 +122,28 @@ class Ingredient(AbstractLicenseModel, models.Model):
|
||||
# Product infos
|
||||
name = models.CharField(
|
||||
max_length=200,
|
||||
verbose_name=_('Name'),
|
||||
verbose_name='Name',
|
||||
validators=[MinLengthValidator(3)],
|
||||
)
|
||||
|
||||
energy = models.IntegerField(
|
||||
verbose_name=_('Energy'),
|
||||
help_text=_('In kcal per 100g'),
|
||||
verbose_name='Energy',
|
||||
help_text='In kcal per 100g',
|
||||
)
|
||||
|
||||
protein = models.DecimalField(
|
||||
decimal_places=3,
|
||||
max_digits=6,
|
||||
verbose_name=_('Protein'),
|
||||
help_text=_('In g per 100g of product'),
|
||||
verbose_name='Protein',
|
||||
help_text='In g per 100g of product',
|
||||
validators=[MinValueValidator(Decimal(0)), MaxValueValidator(Decimal(100))],
|
||||
)
|
||||
|
||||
carbohydrates = models.DecimalField(
|
||||
decimal_places=3,
|
||||
max_digits=6,
|
||||
verbose_name=_('Carbohydrates'),
|
||||
help_text=_('In g per 100g of product'),
|
||||
verbose_name='Carbohydrates',
|
||||
help_text='In g per 100g of product',
|
||||
validators=[MinValueValidator(Decimal(0)), MaxValueValidator(Decimal(100))],
|
||||
)
|
||||
|
||||
@@ -153,16 +152,16 @@ class Ingredient(AbstractLicenseModel, models.Model):
|
||||
max_digits=6,
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name=_('Sugar content in carbohydrates'),
|
||||
help_text=_('In g per 100g of product'),
|
||||
verbose_name='Sugar content in carbohydrates',
|
||||
help_text='In g per 100g of product',
|
||||
validators=[MinValueValidator(Decimal(0)), MaxValueValidator(Decimal(100))],
|
||||
)
|
||||
|
||||
fat = models.DecimalField(
|
||||
decimal_places=3,
|
||||
max_digits=6,
|
||||
verbose_name=_('Fat'),
|
||||
help_text=_('In g per 100g of product'),
|
||||
verbose_name='Fat',
|
||||
help_text='In g per 100g of product',
|
||||
validators=[MinValueValidator(Decimal(0)), MaxValueValidator(Decimal(100))],
|
||||
)
|
||||
|
||||
@@ -171,8 +170,8 @@ class Ingredient(AbstractLicenseModel, models.Model):
|
||||
max_digits=6,
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name=_('Saturated fat content in fats'),
|
||||
help_text=_('In g per 100g of product'),
|
||||
verbose_name='Saturated fat content in fats',
|
||||
help_text='In g per 100g of product',
|
||||
validators=[MinValueValidator(Decimal(0)), MaxValueValidator(Decimal(100))],
|
||||
)
|
||||
|
||||
@@ -181,8 +180,8 @@ class Ingredient(AbstractLicenseModel, models.Model):
|
||||
max_digits=6,
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name=_('Fiber'),
|
||||
help_text=_('In g per 100g of product'),
|
||||
verbose_name='Fiber',
|
||||
help_text='In g per 100g of product',
|
||||
validators=[MinValueValidator(Decimal(0)), MaxValueValidator(Decimal(100))],
|
||||
)
|
||||
|
||||
@@ -191,8 +190,8 @@ class Ingredient(AbstractLicenseModel, models.Model):
|
||||
max_digits=6,
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name=_('Sodium'),
|
||||
help_text=_('In g per 100g of product'),
|
||||
verbose_name='Sodium',
|
||||
help_text='In g per 100g of product',
|
||||
validators=[MinValueValidator(Decimal(0)), MaxValueValidator(Decimal(100))],
|
||||
)
|
||||
|
||||
@@ -220,15 +219,15 @@ class Ingredient(AbstractLicenseModel, models.Model):
|
||||
"""Name of the source, such as Open Food Facts"""
|
||||
|
||||
source_url = models.URLField(
|
||||
verbose_name=_('Link'),
|
||||
help_text=_('Link to product'),
|
||||
verbose_name='Link',
|
||||
help_text='Link to product',
|
||||
blank=True,
|
||||
null=True,
|
||||
)
|
||||
"""URL of the product at the source"""
|
||||
|
||||
last_imported = models.DateTimeField(
|
||||
_('Date'),
|
||||
'Date',
|
||||
auto_now_add=True,
|
||||
null=True,
|
||||
blank=True,
|
||||
@@ -242,7 +241,7 @@ class Ingredient(AbstractLicenseModel, models.Model):
|
||||
|
||||
category = models.ForeignKey(
|
||||
IngredientCategory,
|
||||
verbose_name=_('Category'),
|
||||
verbose_name='Category',
|
||||
on_delete=models.CASCADE,
|
||||
null=True,
|
||||
blank=True,
|
||||
@@ -250,7 +249,7 @@ class Ingredient(AbstractLicenseModel, models.Model):
|
||||
|
||||
brand = models.CharField(
|
||||
max_length=200,
|
||||
verbose_name=_('Brand name of product'),
|
||||
verbose_name='Brand name of product',
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
@@ -316,11 +315,9 @@ class Ingredient(AbstractLicenseModel, models.Model):
|
||||
|
||||
if not ((energy_upper > energy_calculated) and (energy_calculated > energy_lower)):
|
||||
raise ValidationError(
|
||||
_(
|
||||
f'The total energy ({self.energy}kcal) is not the approximate sum of the '
|
||||
f'energy provided by protein, carbohydrates and fat ({energy_calculated}kcal'
|
||||
f' +/-{self.ENERGY_APPROXIMATION}%)'
|
||||
)
|
||||
f'The total energy ({self.energy}kcal) is not the approximate sum of the '
|
||||
f'energy provided by protein, carbohydrates and fat ({energy_calculated}kcal'
|
||||
f' +/-{self.ENERGY_APPROXIMATION}%)'
|
||||
)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
# Django
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class IngredientCategory(models.Model):
|
||||
@@ -24,11 +23,11 @@ class IngredientCategory(models.Model):
|
||||
Model for an Ingredient category
|
||||
"""
|
||||
|
||||
name = models.CharField(max_length=100, verbose_name=_('Name'))
|
||||
name = models.CharField(max_length=100, verbose_name='Name')
|
||||
|
||||
# Metaclass to set some other properties
|
||||
class Meta:
|
||||
verbose_name_plural = _('Ingredient Categories')
|
||||
verbose_name_plural = 'Ingredient Categories'
|
||||
ordering = [
|
||||
'name',
|
||||
]
|
||||
|
||||
@@ -19,7 +19,6 @@ import logging
|
||||
|
||||
# Django
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# Local
|
||||
from .ingredient import Ingredient
|
||||
@@ -36,23 +35,23 @@ class IngredientWeightUnit(models.Model):
|
||||
|
||||
ingredient = models.ForeignKey(
|
||||
Ingredient,
|
||||
verbose_name=_('Ingredient'),
|
||||
verbose_name='Ingredient',
|
||||
editable=False,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
unit = models.ForeignKey(
|
||||
WeightUnit,
|
||||
verbose_name=_('Weight unit'),
|
||||
verbose_name='Weight unit',
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
gram = models.IntegerField(verbose_name=_('Amount in grams'))
|
||||
gram = models.IntegerField(verbose_name='Amount in grams')
|
||||
amount = models.DecimalField(
|
||||
decimal_places=2,
|
||||
max_digits=5,
|
||||
default=1,
|
||||
verbose_name=_('Amount'),
|
||||
help_text=_('Unit amount, e.g. "1 Cup" or "1/2 spoon"'),
|
||||
verbose_name='Amount',
|
||||
help_text='Unit amount, e.g. "1 Cup" or "1/2 spoon"',
|
||||
)
|
||||
|
||||
def get_owner_object(self):
|
||||
|
||||
@@ -24,7 +24,6 @@ from django.core.validators import (
|
||||
)
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# wger
|
||||
from wger.nutrition.helpers import BaseMealItem
|
||||
@@ -49,7 +48,7 @@ class LogItem(BaseMealItem, models.Model):
|
||||
|
||||
plan = models.ForeignKey(
|
||||
NutritionPlan,
|
||||
verbose_name=_('Nutrition plan'),
|
||||
verbose_name='Nutrition plan',
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
"""
|
||||
@@ -58,7 +57,7 @@ class LogItem(BaseMealItem, models.Model):
|
||||
|
||||
meal = models.ForeignKey(
|
||||
Meal,
|
||||
verbose_name=_('Meal'),
|
||||
verbose_name='Meal',
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='log_items',
|
||||
blank=True,
|
||||
@@ -68,13 +67,13 @@ class LogItem(BaseMealItem, models.Model):
|
||||
The meal this log belongs to (optional)
|
||||
"""
|
||||
|
||||
datetime = models.DateTimeField(verbose_name=_('Date and Time (Approx.)'), default=timezone.now)
|
||||
datetime = models.DateTimeField(verbose_name='Date and Time (Approx.)', default=timezone.now)
|
||||
"""
|
||||
Time and date when the log was added
|
||||
"""
|
||||
|
||||
comment = models.TextField(
|
||||
verbose_name=_('Comment'),
|
||||
verbose_name='Comment',
|
||||
blank=True,
|
||||
null=True,
|
||||
)
|
||||
@@ -84,7 +83,7 @@ class LogItem(BaseMealItem, models.Model):
|
||||
|
||||
ingredient = models.ForeignKey(
|
||||
Ingredient,
|
||||
verbose_name=_('Ingredient'),
|
||||
verbose_name='Ingredient',
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
"""
|
||||
@@ -93,7 +92,7 @@ class LogItem(BaseMealItem, models.Model):
|
||||
|
||||
weight_unit = models.ForeignKey(
|
||||
IngredientWeightUnit,
|
||||
verbose_name=_('Weight unit'),
|
||||
verbose_name='Weight unit',
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.CASCADE,
|
||||
@@ -105,7 +104,7 @@ class LogItem(BaseMealItem, models.Model):
|
||||
amount = models.DecimalField(
|
||||
decimal_places=2,
|
||||
max_digits=6,
|
||||
verbose_name=_('Amount'),
|
||||
verbose_name='Amount',
|
||||
validators=[MinValueValidator(Decimal(1)), MaxValueValidator(Decimal(1000))],
|
||||
)
|
||||
"""
|
||||
|
||||
@@ -19,7 +19,6 @@ import logging
|
||||
|
||||
# Django
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# wger
|
||||
from wger.utils.fields import Html5TimeField
|
||||
@@ -45,27 +44,25 @@ class Meal(models.Model):
|
||||
|
||||
plan = models.ForeignKey(
|
||||
NutritionPlan,
|
||||
verbose_name=_('Nutrition plan'),
|
||||
verbose_name='Nutrition plan',
|
||||
editable=False,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
order = models.IntegerField(
|
||||
verbose_name=_('Order'),
|
||||
verbose_name='Order',
|
||||
blank=True,
|
||||
editable=False,
|
||||
)
|
||||
time = Html5TimeField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name=_('Time (approx)'),
|
||||
verbose_name='Time (approx)',
|
||||
)
|
||||
name = models.CharField(
|
||||
max_length=25,
|
||||
blank=True,
|
||||
verbose_name=_('Name'),
|
||||
help_text=_(
|
||||
'Give meals a textual description / name such as "Breakfast" or "after workout"'
|
||||
),
|
||||
verbose_name='Name',
|
||||
help_text='Give meals a textual description / name such as "Breakfast" or "after workout"',
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
|
||||
@@ -24,7 +24,6 @@ from django.core.validators import (
|
||||
MinValueValidator,
|
||||
)
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# wger
|
||||
from wger.nutrition.helpers import BaseMealItem
|
||||
@@ -45,32 +44,32 @@ class MealItem(BaseMealItem, models.Model):
|
||||
|
||||
meal = models.ForeignKey(
|
||||
Meal,
|
||||
verbose_name=_('Nutrition plan'),
|
||||
verbose_name='Nutrition plan',
|
||||
editable=False,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
ingredient = models.ForeignKey(
|
||||
Ingredient,
|
||||
verbose_name=_('Ingredient'),
|
||||
verbose_name='Ingredient',
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
weight_unit = models.ForeignKey(
|
||||
IngredientWeightUnit,
|
||||
verbose_name=_('Weight unit'),
|
||||
verbose_name='Weight unit',
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
order = models.IntegerField(
|
||||
verbose_name=_('Order'),
|
||||
verbose_name='Order',
|
||||
blank=True,
|
||||
editable=False,
|
||||
)
|
||||
amount = models.DecimalField(
|
||||
decimal_places=2,
|
||||
max_digits=6,
|
||||
verbose_name=_('Amount'),
|
||||
verbose_name='Amount',
|
||||
validators=[MinValueValidator(Decimal(1)), MaxValueValidator(Decimal(1000))],
|
||||
)
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ from django.contrib.auth.models import User
|
||||
from django.core.cache import cache
|
||||
from django.db import models
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# wger
|
||||
from wger.nutrition.consts import ENERGY_FACTOR
|
||||
@@ -48,24 +47,24 @@ class NutritionPlan(models.Model):
|
||||
|
||||
user = models.ForeignKey(
|
||||
User,
|
||||
verbose_name=_('User'),
|
||||
verbose_name='User',
|
||||
editable=False,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
creation_date = models.DateField(
|
||||
_('Creation date'),
|
||||
'Creation date',
|
||||
auto_now_add=True,
|
||||
)
|
||||
|
||||
start = models.DateField(
|
||||
_('Start date'),
|
||||
verbose_name='Start date',
|
||||
blank=True,
|
||||
default=datetime.date.today,
|
||||
)
|
||||
|
||||
end = models.DateField(
|
||||
_('End date'),
|
||||
verbose_name='End date',
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
@@ -73,10 +72,8 @@ class NutritionPlan(models.Model):
|
||||
description = models.CharField(
|
||||
max_length=80,
|
||||
blank=True,
|
||||
verbose_name=_('Description'),
|
||||
help_text=_(
|
||||
'A description of the goal of the plan, e.g. "Gain mass" or "Prepare for summer"'
|
||||
),
|
||||
verbose_name='Description',
|
||||
help_text='A description of the goal of the plan, e.g. "Gain mass" or "Prepare for summer"',
|
||||
)
|
||||
|
||||
only_logging = models.BooleanField(
|
||||
@@ -96,9 +93,9 @@ class NutritionPlan(models.Model):
|
||||
goal_fat = models.IntegerField(null=True, default=None)
|
||||
|
||||
has_goal_calories = models.BooleanField(
|
||||
verbose_name=_('Use daily calories'),
|
||||
verbose_name='Use daily calories',
|
||||
default=False,
|
||||
help_text=_(
|
||||
help_text=(
|
||||
'Tick the box if you want to mark this '
|
||||
'plan as having a goal amount of calories. '
|
||||
'You can use the calculator or enter the '
|
||||
@@ -114,7 +111,7 @@ class NutritionPlan(models.Model):
|
||||
if self.description:
|
||||
return self.description
|
||||
else:
|
||||
return str(_('Nutrition plan'))
|
||||
return 'Nutrition plan'
|
||||
|
||||
def get_absolute_url(self):
|
||||
"""
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
# Django
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# wger
|
||||
from wger.core.models import Language
|
||||
@@ -29,13 +28,13 @@ class WeightUnit(models.Model):
|
||||
|
||||
language = models.ForeignKey(
|
||||
Language,
|
||||
verbose_name=_('Language'),
|
||||
verbose_name='Language',
|
||||
editable=False,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
name = models.CharField(
|
||||
max_length=200,
|
||||
verbose_name=_('Name'),
|
||||
verbose_name='Name',
|
||||
)
|
||||
|
||||
# Metaclass to set some other properties
|
||||
|
||||
@@ -121,7 +121,7 @@ class IngredientDeleteView(
|
||||
|
||||
# Send some additional data to the template
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(IngredientDeleteView, self).get_context_data(**kwargs)
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
context['title'] = _('Delete {0}?').format(self.object)
|
||||
return context
|
||||
@@ -141,7 +141,7 @@ class IngredientEditView(WgerFormMixin, LoginRequiredMixin, PermissionRequiredMi
|
||||
"""
|
||||
Send some additional data to the template
|
||||
"""
|
||||
context = super(IngredientEditView, self).get_context_data(**kwargs)
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['title'] = _('Edit {0}').format(self.object)
|
||||
return context
|
||||
|
||||
|
||||
185
wger/tasks.py
185
wger/tasks.py
@@ -1,5 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# This file is part of wger Workout Manager.
|
||||
#
|
||||
# wger Workout Manager is free software: you can redistribute it and/or modify
|
||||
@@ -17,7 +15,6 @@
|
||||
# Standard Library
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
@@ -25,9 +22,9 @@ import tempfile
|
||||
import django
|
||||
from django.core.management import (
|
||||
call_command,
|
||||
color_style,
|
||||
execute_from_command_line,
|
||||
)
|
||||
from django.utils.crypto import get_random_string
|
||||
|
||||
# Third Party
|
||||
import requests
|
||||
@@ -42,6 +39,8 @@ from tqdm import tqdm
|
||||
logger = logging.getLogger(__name__)
|
||||
FIXTURE_URL = 'https://github.com/wger-project/data/raw/master/fixtures/'
|
||||
|
||||
style = color_style()
|
||||
|
||||
|
||||
@task(
|
||||
help={
|
||||
@@ -56,8 +55,6 @@ def start(context, address='localhost', port=8000, settings_path=None, extra_arg
|
||||
"""
|
||||
Start the application using django's built in webserver
|
||||
"""
|
||||
|
||||
# Find the path to the settings and setup the django environment
|
||||
setup_django_environment(settings_path)
|
||||
|
||||
argv = ['', 'runserver', '--noreload']
|
||||
@@ -70,22 +67,14 @@ def start(context, address='localhost', port=8000, settings_path=None, extra_arg
|
||||
|
||||
@task(
|
||||
help={
|
||||
'settings-path': 'Path to settings file (absolute path). Leave empty for default',
|
||||
'database-path': 'Path to sqlite database (absolute path). Leave empty for default',
|
||||
'settings-path': 'Path to settings file. Leave empty for default (settings.main)',
|
||||
'process-static': 'Whether to process static files (install npm packages and process css). Default: True',
|
||||
}
|
||||
)
|
||||
def bootstrap(context, settings_path=None, database_path=None, process_static=True):
|
||||
def bootstrap(context, settings_path=None, process_static=True):
|
||||
"""
|
||||
Performs all steps necessary to bootstrap the application
|
||||
"""
|
||||
|
||||
# Create settings if necessary
|
||||
if settings_path is None:
|
||||
settings_path = get_path('settings.py')
|
||||
if not os.path.exists(settings_path):
|
||||
create_settings(context, settings_path=settings_path, database_path=database_path)
|
||||
|
||||
# Find the path to the settings and setup the django environment
|
||||
setup_django_environment(settings_path)
|
||||
|
||||
# Create Database if necessary
|
||||
@@ -101,93 +90,11 @@ def bootstrap(context, settings_path=None, database_path=None, process_static=Tr
|
||||
context.run('npm run build:css:sass')
|
||||
|
||||
|
||||
@task(
|
||||
help={
|
||||
'settings-path': 'Path to settings file (absolute path). Leave empty for default',
|
||||
'database-path': 'Path to sqlite database (absolute path). Leave empty for default',
|
||||
'database-type': 'Database type to use. Supported: sqlite3, postgresql. Default: sqlite3',
|
||||
'key-length': 'Length of the generated secret key. Default: 50',
|
||||
}
|
||||
)
|
||||
def create_settings(
|
||||
context,
|
||||
settings_path=None,
|
||||
database_path=None,
|
||||
database_type='sqlite3',
|
||||
key_length=50,
|
||||
):
|
||||
"""
|
||||
Creates a local settings file
|
||||
"""
|
||||
if settings_path is None:
|
||||
settings_path = get_path('settings.py')
|
||||
|
||||
settings_module = os.path.dirname(settings_path)
|
||||
print(f'*** Creating settings file at {settings_module}')
|
||||
|
||||
if database_path is None:
|
||||
database_path = get_path('database.sqlite').as_posix()
|
||||
dbpath_value = database_path
|
||||
|
||||
media_folder_path = get_path('media').as_posix()
|
||||
|
||||
# Use localhost with default django port if no URL given
|
||||
url = 'http://localhost:8000'
|
||||
|
||||
# Fill in the config file template
|
||||
settings_template = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'settings.tpl')
|
||||
with open(settings_template, 'r') as settings_file:
|
||||
settings_content = settings_file.read()
|
||||
|
||||
if database_type == 'postgresql':
|
||||
dbengine = 'postgresql'
|
||||
dbname = 'wger'
|
||||
dbuser = 'wger'
|
||||
dbpassword = 'wger'
|
||||
dbhost = 'localhost'
|
||||
dbport = 5432
|
||||
elif database_type == 'sqlite3':
|
||||
dbengine = 'sqlite3'
|
||||
dbname = dbpath_value
|
||||
dbuser = ''
|
||||
dbpassword = ''
|
||||
dbhost = ''
|
||||
dbport = ''
|
||||
|
||||
# Create a random SECRET_KEY to put it in the settings.
|
||||
# from django.core.management.commands.startproject
|
||||
secret_key = get_random_string(key_length, 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)')
|
||||
|
||||
settings_content = settings_content.format(
|
||||
dbname=dbname,
|
||||
dbpath=dbpath_value,
|
||||
dbengine=dbengine,
|
||||
dbuser=dbuser,
|
||||
dbpassword=dbpassword,
|
||||
dbhost=dbhost,
|
||||
dbport=dbport,
|
||||
default_key=secret_key,
|
||||
siteurl=url,
|
||||
media_folder_path=media_folder_path,
|
||||
)
|
||||
|
||||
if not os.path.exists(settings_module):
|
||||
os.makedirs(settings_module)
|
||||
|
||||
if not os.path.exists(os.path.dirname(database_path)):
|
||||
os.makedirs(os.path.dirname(database_path))
|
||||
|
||||
with open(settings_path, 'w') as settings_file:
|
||||
settings_file.write(settings_content)
|
||||
|
||||
|
||||
@task(help={'settings-path': 'Path to settings file (absolute path). Leave empty for default'})
|
||||
def create_or_reset_admin(context, settings_path=None):
|
||||
def create_or_reset_admin(context, settings_path: str = None):
|
||||
"""
|
||||
Creates an admin user or resets the password for an existing one
|
||||
"""
|
||||
|
||||
# Find the path to the settings and setup the django environment
|
||||
setup_django_environment(settings_path)
|
||||
|
||||
# can't be imported in global scope as it already requires
|
||||
@@ -207,25 +114,21 @@ def create_or_reset_admin(context, settings_path=None):
|
||||
call_command('loaddata', path + 'users.json')
|
||||
|
||||
|
||||
@task(help={'settings-path': 'Path to settings file (absolute path). Leave empty for default'})
|
||||
@task(help={'settings-path': 'Path to settings file. Leave empty for default (settings.main)'})
|
||||
def migrate_db(context, settings_path=None):
|
||||
"""
|
||||
Run all database migrations
|
||||
"""
|
||||
|
||||
# Find the path to the settings and setup the django environment
|
||||
setup_django_environment(settings_path)
|
||||
|
||||
call_command('migrate')
|
||||
|
||||
|
||||
@task(help={'settings-path': 'Path to settings file (absolute path). Leave empty for default'})
|
||||
def load_fixtures(context, settings_path=None):
|
||||
@task(help={'settings-path': 'Path to settings file. Leave empty for default (settings.main)'})
|
||||
def load_fixtures(context, settings_path: str = None):
|
||||
"""
|
||||
Loads all fixtures
|
||||
"""
|
||||
|
||||
# Find the path to the settings and setup the django environment
|
||||
setup_django_environment(settings_path)
|
||||
|
||||
# Gym
|
||||
@@ -257,13 +160,11 @@ def load_fixtures(context, settings_path=None):
|
||||
call_command('loaddata', 'gym-adminconfig.json')
|
||||
|
||||
|
||||
@task(help={'settings-path': 'Path to settings file (absolute path). Leave empty for default'})
|
||||
def load_online_fixtures(context, settings_path=None):
|
||||
@task(help={'settings-path': 'Path to settings file. Leave empty for default (settings.main)'})
|
||||
def load_online_fixtures(context, settings_path: str = None):
|
||||
"""
|
||||
Downloads fixtures from server and installs them (at the moment only ingredients)
|
||||
"""
|
||||
|
||||
# Find the path to the settings and set up the django environment
|
||||
setup_django_environment(settings_path)
|
||||
|
||||
# Prepare the download
|
||||
@@ -291,57 +192,28 @@ def load_online_fixtures(context, settings_path=None):
|
||||
os.unlink(f.name)
|
||||
|
||||
|
||||
@task
|
||||
def config_location(context):
|
||||
"""
|
||||
Returns the default location for the settings file and the data folder
|
||||
"""
|
||||
print('Default locations:')
|
||||
print(f'* settings: {get_path("settings.py")}')
|
||||
print(f'* media folder: {get_path("media")}')
|
||||
print(f'* database path: {get_path("database.sqlite")}')
|
||||
|
||||
|
||||
#
|
||||
#
|
||||
# Helper functions
|
||||
#
|
||||
# Note: these functions were originally in wger/utils/main.py but were moved
|
||||
# here because of different import problems (the packaged pip-installed
|
||||
# packaged has a different sys path than the local one)
|
||||
#
|
||||
|
||||
|
||||
def get_path(file='settings.py') -> pathlib.Path:
|
||||
"""
|
||||
Return the path of the given file relatively to the wger source folder
|
||||
|
||||
Note: one parent is the step from e.g. some-checkout/wger/settings.py
|
||||
to some-checkout/wger, the second one to get to the source folder
|
||||
itself.
|
||||
"""
|
||||
return (pathlib.Path(__file__).parent.parent / file).resolve()
|
||||
|
||||
|
||||
def setup_django_environment(settings_path):
|
||||
def setup_django_environment(settings_path: str = None):
|
||||
"""
|
||||
Setup the django environment
|
||||
"""
|
||||
if settings_path is not None:
|
||||
print(f'*** Using settings from argument: {settings_path}')
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = settings_path
|
||||
elif os.environ.get('DJANGO_SETTINGS_MODULE') is not None:
|
||||
print(f'*** Using settings from env: {os.environ.get("DJANGO_SETTINGS_MODULE")}')
|
||||
else:
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings.main'
|
||||
print('*** No settings given, using settings.main')
|
||||
|
||||
# Use default settings if the user didn't specify something else
|
||||
if settings_path is None:
|
||||
settings_path = get_path('settings.py').as_posix()
|
||||
print(f'*** No settings given, using {settings_path}')
|
||||
|
||||
# Find out file path and fine name of settings and setup django
|
||||
settings_file = os.path.basename(settings_path)
|
||||
settings_module_name = ''.join(settings_file.split('.')[:-1])
|
||||
if '.' in settings_module_name:
|
||||
print("'.' is not an allowed character in the settings-file")
|
||||
# Check if we are in the wger source folder
|
||||
if not os.path.isfile('manage.py'):
|
||||
print(style.ERROR('Error: please run this script from the wger checkout folder'))
|
||||
sys.exit(1)
|
||||
settings_module_dir = os.path.dirname(settings_path)
|
||||
sys.path.append(settings_module_dir)
|
||||
os.environ[django.conf.ENVIRONMENT_VARIABLE] = '%s' % settings_module_name
|
||||
|
||||
django.setup()
|
||||
|
||||
|
||||
@@ -356,12 +228,11 @@ def database_exists():
|
||||
from django.db import DatabaseError
|
||||
|
||||
try:
|
||||
# TODO: Use another model, the User could be deactivated
|
||||
User.objects.count()
|
||||
except DatabaseError:
|
||||
return False
|
||||
except ImproperlyConfigured:
|
||||
print('Your settings file seems broken')
|
||||
except ImproperlyConfigured as e:
|
||||
print(style.ERROR('Your settings file seems broken: '), e)
|
||||
sys.exit(0)
|
||||
else:
|
||||
return True
|
||||
@@ -369,9 +240,7 @@ def database_exists():
|
||||
|
||||
def make_program():
|
||||
ns = Collection(
|
||||
start,
|
||||
bootstrap,
|
||||
create_settings,
|
||||
create_or_reset_admin,
|
||||
migrate_db,
|
||||
load_fixtures,
|
||||
|
||||
@@ -10,6 +10,8 @@ their workout activities.
|
||||
- **Progressive Trophies**: Show user progress towards earning a trophy
|
||||
- **Hidden Trophies**: Secret achievements that are revealed only when
|
||||
earned
|
||||
- **Repeatable Trophies**: Trophies can be earned multiple times, for
|
||||
example PR trophies. Context data can be added to each earned trophy.
|
||||
- **Automatic Evaluation**: Trophies are evaluated automatically when
|
||||
workout data changes
|
||||
- **Statistics Tracking**: Denormalized statistics for efficient trophy
|
||||
@@ -54,6 +56,7 @@ Defines an achievement that users can earn.
|
||||
- `is_hidden`: Hidden until earned
|
||||
- `is_progressive`: Shows progress percentage
|
||||
- `is_active`: Can be earned (admins can disable)
|
||||
- `is_repeatable`: Can be earned multiple times
|
||||
- `order`: Display order
|
||||
|
||||
### UserTrophy
|
||||
@@ -66,6 +69,7 @@ Links users to their earned trophies.
|
||||
- `earned_at`: Timestamp when earned
|
||||
- `progress`: Progress percentage (0-100)
|
||||
- `is_notified`: For future notification system
|
||||
- `context_data`: Additionnal information on the trophy
|
||||
|
||||
### UserStatistics
|
||||
|
||||
@@ -118,6 +122,10 @@ Trophy checkers are Python classes that determine if a user has earned a trophy.
|
||||
- Params: `{'inactive_days': 30}`
|
||||
- Example: "Return to training after 30 days inactive"
|
||||
|
||||
8. **personal_record**: Check for new PRs
|
||||
- Params: `{'log': WorkoutLog}`
|
||||
- Example: "Beats PR on exercise 'Bench Press Dumbells' by logging 100kg for 10 reps."
|
||||
|
||||
## Management Commands
|
||||
|
||||
### Load Trophies
|
||||
@@ -125,14 +133,8 @@ Trophy checkers are Python classes that determine if a user has earned a trophy.
|
||||
Load the initial set of trophies into the database:
|
||||
|
||||
```bash
|
||||
# Load new trophies (skip existing)
|
||||
python manage.py load_trophies
|
||||
|
||||
# Update existing trophies
|
||||
python manage.py load_trophies --update
|
||||
|
||||
# Verbose output
|
||||
python manage.py load_trophies -v 2
|
||||
# Load trophies (overwrites existing ones if IDs match)
|
||||
python manage.py loaddata initial_trophies
|
||||
```
|
||||
|
||||
### Evaluate Trophies
|
||||
@@ -531,7 +533,7 @@ python manage.py test wger.trophies.tests.test_integration
|
||||
|
||||
## Initial Trophies
|
||||
|
||||
The system includes 9 initial trophies:
|
||||
The system includes 10 initial trophies.
|
||||
|
||||
1. **Beginner**: Complete your first workout
|
||||
2. **Unstoppable**: Maintain a 30-day workout streak
|
||||
@@ -544,8 +546,9 @@ The system includes 9 initial trophies:
|
||||
8. **New Year, New Me**: Work out on January 1st
|
||||
9. **Phoenix** (Hidden): Return to training after being inactive for
|
||||
30 days
|
||||
10. **PR Trophy** Achieve a new Personal Record on any exercise
|
||||
|
||||
Load them with: `python manage.py load_trophies`
|
||||
Load them with: `python manage.py loaddata initial_trophies`
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
||||
0
wger/trophies/__init__.py
Normal file
0
wger/trophies/__init__.py
Normal file
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user