Code structure refactor (#5582)

* moved docker files to /contrib/container

* changed code owners to make more precise

* updated CI to use new subdirs

* added manual trigger for testing

* moved ci files

* moved assets into subdir

* moved deploy template file to contrib

* moved django files to src/backend

* updated paths in scripts etc

* updated reqs path

* fixed version file path

* fixed flake8 path

* fixed path to node ressources

* fixed task paths

* added dep path for node

* removed unused yarn lockfile

* removed unused ci script

* updated internal backend paths for tasks

* updated translation stats path

* fixed source path for coverage

* fixed main commit repo path

* fit in changes from testing

* gather packager improvements (#149)

* Matmair/issue5578 (#143)

* moved docker files to /contrib/container

* changed code owners to make more precise

* updated CI to use new subdirs

* added manual trigger for testing

* moved ci files

* moved assets into subdir

* moved deploy template file to contrib

* moved django files to src/backend

* updated paths in scripts etc

* updated reqs path

* fixed version file path

* fixed flake8 path

* fixed path to node ressources

* fixed task paths

* added dep path for node

* removed unused yarn lockfile

* removed unused ci script

* updated internal backend paths for tasks

* updated translation stats path

* fixed source path for coverage

* fixed main commit repo path

* fix docker path

* use project dir

* move project dir command

* fixed docker paths

* another fix?

* seperate tasks out

* remove tasks

* some debugging

* ci: add .deepsource.toml

* Update .deepsource.toml

* also ignore migrations

* more debugging

* fix path issues

* remove debug script

* fix style

* change locale path

* Fixed paths for requirements

* Added dummy requirements to fool packager

* fixed exec path

* remove deepsource

---------

Co-authored-by: deepsource-io[bot] <42547082+deepsource-io[bot]@users.noreply.github.com>

* Added docs for file structure

* Fixed style errors

* updated deepsource paths

* fix deepsource paths

* fixed reqs

* merge fixes

* move newly added dirs too

* fix reqs files

* another dep fix

* merge upstream/master

* revert removal of tags

* merge upstream

* enabled detection of old config files

* adapt coverage src

* also detect and support old location for plugins.txt

* style fix

* fix ~/init.sh location

* fix requirements path

* fix config to current master

* move new folders

* fix import order

* fix paths for qc_check

* fix docs build

* fix fix path

* set docker project dir

* just use a cd

* set image path?

* set file correct

* fix copy path

* fix tasks dir

* fix init path

* fix copy path

* set prject dir

* fix paths

* remove old prod files

* fix dev env path

* set docker file

* Fix devcontainer docker compose file

* fix login attempt values

* fix init.sh path

* Fix pathing for Docker

* Docker build fix

- Set INVENTREE_BACKEND_DIR separately

* Update init.sh

* Fix path

* Update requirements.txt

* merge

* fix rq merge

* fix docker compose usage

---------

Co-authored-by: deepsource-io[bot] <42547082+deepsource-io[bot]@users.noreply.github.com>
Co-authored-by: Oliver <oliver.henry.walters@gmail.com>
This commit is contained in:
Matthias Mair 2024-04-03 02:16:59 +01:00 committed by GitHub
parent dd889e8eeb
commit 0bace3f3af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3317 changed files with 532 additions and 1194 deletions

View File

@ -16,6 +16,7 @@ services:
inventree:
build:
context: ..
dockerfile: ../InvenTree/contrib/container/Dockerfile
target: dev
args:
base_image: "mcr.microsoft.com/vscode/devcontainers/base:alpine-3.18"

11
.github/CODEOWNERS vendored
View File

@ -1,2 +1,13 @@
# General owner is the maintainers team
* @SchrodingersGat
# plugins are co-owned
/src/backend/InvenTree/plugin/ @SchrodingersGat @matmair
/src/backend/InvenTree/plugins/ @SchrodingersGat @matmair
# Installer functions
.pkgr.yml @matmair
Procfile @matmair
runtime.txt @matmair
/contrib/installer @matmair
/contrib/packager.io @matmair

View File

@ -11,7 +11,7 @@ runs:
invoke migrate
invoke import-fixtures
invoke export-records -f data.json
python3 ./InvenTree/manage.py flush --noinput
python3 ./src/backend/InvenTree/manage.py flush --noinput
invoke migrate
invoke import-records -f data.json
invoke import-records -f data.json

View File

@ -65,10 +65,11 @@ runs:
with:
node-version: ${{ env.node_version }}
cache: 'npm'
cache-dependency-path: src/backend/package-lock.json
- name: Install npm packages
if: ${{ inputs.npm == 'true' }}
shell: bash
run: npm install
run: cd src/backend && npm install
# OS installs
- name: Install OS Dependencies
@ -77,12 +78,13 @@ runs:
run: |
sudo apt-get update
sudo apt-get install ${{ inputs.apt-dependency }}
sudo apt-get install ${{ inputs.apt-dependency }}
# Invoke commands
- name: Install dev requirements
if: ${{ inputs.dev-install == 'true' ||inputs.install == 'true' }}
shell: bash
run: uv pip install -r requirements-dev.txt
run: uv pip install -r src/backend/requirements-dev.txt
- name: Run invoke install
if: ${{ inputs.install == 'true' }}
shell: bash

View File

@ -114,7 +114,9 @@ if __name__ == '__main__':
print(f'GITHUB_BASE_REF: {GITHUB_BASE_REF}')
here = Path(__file__).parent.absolute()
version_file = here.joinpath('..', 'InvenTree', 'InvenTree', 'version.py')
version_file = here.joinpath(
'..', '..', 'src', 'backend', 'InvenTree', 'InvenTree', 'version.py'
)
version = None

View File

@ -40,4 +40,4 @@ jobs:
- name: Test Translations
run: invoke translate
- name: Check Migration Files
run: python3 ci/check_migration_files.py
run: python3 .github/scripts/check_migration_files.py

View File

@ -78,26 +78,26 @@ jobs:
run: |
pip install requests==2.31.0
pip install pyyaml==6.0.1
python3 ci/version_check.py
python3 .github/scripts/version_check.py
echo "git_commit_hash=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
echo "git_commit_date=$(git show -s --format=%ci)" >> $GITHUB_ENV
- name: Test Docker Image
id: test-docker
run: |
docker build . --target production --tag inventree-test
docker build . --target production --tag inventree-test -f contrib/container/Dockerfile
docker run --rm inventree-test invoke --version
docker run --rm inventree-test invoke --list
docker run --rm inventree-test gunicorn --version
docker run --rm inventree-test pg_dump --version
- name: Build Docker Image
# Build the development docker image (using docker-compose.yml)
run: docker-compose build --no-cache
run: docker compose --project-directory . -f contrib/container/dev-docker-compose.yml build --no-cache
- name: Update Docker Image
run: |
docker-compose run inventree-dev-server invoke update
docker-compose run inventree-dev-server invoke setup-dev
docker-compose up -d
docker-compose run inventree-dev-server invoke wait
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml run inventree-dev-server invoke update
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml run inventree-dev-server invoke setup-dev
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml up -d
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml run inventree-dev-server invoke wait
- name: Check Data Directory
# The following file structure should have been created by the docker image
run: |
@ -112,10 +112,10 @@ jobs:
test -f data/secret_key.txt
- name: Run Unit Tests
run: |
echo "GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> docker.dev.env
docker-compose run inventree-dev-server invoke test --disable-pty
docker-compose run inventree-dev-server invoke test --migrations --disable-pty
docker-compose down
echo "GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> contrib/container/docker.dev.env
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml run inventree-dev-server invoke test --disable-pty
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml run inventree-dev-server invoke test --migrations --disable-pty
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml down
- name: Clean up test folder
run: |
rm -rf InvenTree/_testfolder

View File

@ -42,9 +42,9 @@ jobs:
with:
filters: |
server:
- 'InvenTree/**'
- 'requirements.txt'
- 'requirements-dev.txt'
- 'src/backend/InvenTree/**'
- 'src/backend/requirements.txt'
- 'src/backend/requirements-dev.txt'
migrations:
- '**/migrations/**'
- '.github/workflows**'
@ -68,12 +68,12 @@ jobs:
install: true
- name: Check Templated JS Files
run: |
cd ci
cd .github/scripts
python3 check_js_templates.py
- name: Lint Javascript Files
run: |
python InvenTree/manage.py prerender
npx eslint InvenTree/InvenTree/static_i18n/i18n/*.js
python src/backend/InvenTree/manage.py prerender
npx eslint src/backend/InvenTree/InvenTree/static_i18n/i18n/*.js
pre-commit:
name: Style [pre-commit]
@ -93,7 +93,7 @@ jobs:
- name: Check Version
run: |
pip install requests==2.31.0
python3 ci/version_check.py
python3 .github/scripts/version_check.py
mkdocs:
name: Style [Documentation]
@ -147,12 +147,12 @@ jobs:
dev-install: true
update: true
- name: Export API Documentation
run: invoke schema --ignore-warnings --filename InvenTree/schema.yml
run: invoke schema --ignore-warnings --filename src/backend/InvenTree/schema.yml
- name: Upload schema
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # pin@v4.3.1
with:
name: schema.yml
path: InvenTree/schema.yml
path: src/backend/InvenTree/schema.yml
- name: Download public schema
if: needs.paths-filter.outputs.api == 'false'
run: |
@ -166,8 +166,8 @@ jobs:
- name: Check for differences in API Schema
if: needs.paths-filter.outputs.api == 'false'
run: |
diff --color -u InvenTree/schema.yml api.yaml
diff -u InvenTree/schema.yml api.yaml && echo "no difference in API schema " || exit 2
diff --color -u src/backend/InvenTree/schema.yml api.yaml
diff -u src/backend/InvenTree/schema.yml api.yaml && echo "no difference in API schema " || exit 2
- name: Check schema - including warnings
run: invoke schema
continue-on-error: true
@ -273,7 +273,7 @@ jobs:
- name: Test Translations
run: invoke translate
- name: Check Migration Files
run: python3 ci/check_migration_files.py
run: python3 .github/scripts/check_migration_files.py
- name: Coverage Tests
run: invoke test --coverage
- name: Upload Coverage Report
@ -512,9 +512,9 @@ jobs:
run: cd src/frontend && npm run compile && npm run build
- name: Zip frontend
run: |
cd InvenTree/web/static
cd src/backend/InvenTree/web/static
zip -r frontend-build.zip web/
- uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # pin@v4.3.1
with:
name: frontend-build
path: InvenTree/web/static/web
path: src/backend/InvenTree/web/static/web

View File

@ -20,7 +20,7 @@ jobs:
- name: Version Check
run: |
pip install requests==2.31.0
python3 ci/version_check.py
python3 .github/scripts/version_check.py
- name: Push to Stable Branch
uses: ad-m/github-push-action@d91a481090679876dfc4178fef17f286781251df # pin@v0.8.0
if: env.stable_release == 'true'
@ -43,12 +43,12 @@ jobs:
run: cd src/frontend && npm run compile && npm run build
- name: Zip frontend
run: |
cd InvenTree/web/static/web
cd src/backend/InvenTree/web/static/web
zip -r ../frontend-build.zip *
- uses: svenstaro/upload-release-action@04733e069f2d7f7f0b4aebc4fbdbce8613b03ccd # pin@2.9.0
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: InvenTree/web/static/frontend-build.zip
file: src/backend/InvenTree/web/static/frontend-build.zip
asset_name: frontend-build.zip
tag: ${{ github.ref }}
overwrite: true

5
.gitignore vendored
View File

@ -84,7 +84,7 @@ data/
env/
# Locale stats file
locale_stats.json
src/backend/InvenTree/InvenTree/locale_stats.json
# node.js
node_modules/
@ -93,7 +93,7 @@ node_modules/
maintenance_mode_state.txt
# plugin dev directory
InvenTree/plugins/
src/backend/InvenTree/plugins/
# Compiled translation files
*.mo
@ -103,6 +103,7 @@ messages.ts
api.yaml
# web frontend (static files)
src/backend/InvenTree/web/static
InvenTree/web/static
# Generated docs files

View File

@ -2,12 +2,11 @@
# See https://pre-commit.com/hooks.html for more hooks
exclude: |
(?x)^(
InvenTree/InvenTree/static/.*|
InvenTree/locale/.*|
src/backend/InvenTree/InvenTree/static/.*|
src/backend/InvenTree/locale/.*|
src/frontend/src/locales/.* |
.*/migrations/.* |
src/frontend/yarn.lock |
yarn.lock
src/frontend/yarn.lock
)$
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
@ -32,12 +31,12 @@ repos:
hooks:
- id: pip-compile
name: pip-compile requirements-dev.in
args: [requirements-dev.in, -o, requirements-dev.txt, --python-version=3.9, --no-strip-extras]
files: ^requirements-dev\.(in|txt)$
args: [src/backend/requirements-dev.in, -o, src/backend/requirements-dev.txt, --python-version=3.9, --no-strip-extras]
files: src/backend/requirements-dev\.(in|txt)$
- id: pip-compile
name: pip-compile requirements.txt
args: [requirements.in, -o, requirements.txt,--python-version=3.9, --no-strip-extras]
files: ^requirements\.(in|txt)$
args: [src/backend/requirements.in, -o, src/backend/requirements.txt,--python-version=3.9, --no-strip-extras]
files: src/backend/requirements\.(in|txt)$
- repo: https://github.com/Riverside-Healthcare/djLint
rev: v1.34.1
hooks:

4
.vscode/launch.json vendored
View File

@ -8,7 +8,7 @@
"name": "InvenTree Server",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/InvenTree/manage.py",
"program": "${workspaceFolder}/src/backend/InvenTree/manage.py",
"args": ["runserver"],
"django": true,
"justMyCode": true
@ -17,7 +17,7 @@
"name": "InvenTree Server - 3rd party",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/InvenTree/manage.py",
"program": "${workspaceFolder}/src/backend/InvenTree/manage.py",
"args": ["runserver"],
"django": true,
"justMyCode": false

View File

@ -3,4 +3,48 @@
Hi there, thank you for your interest in contributing!
Please read our contribution guidelines, before submitting your first pull request to the InvenTree codebase.
### Project File Structure
The InvenTree project is split into two main components: frontend and backend. This source is located in the `src` directory. All other files are used for project management, documentation, and testing.
```bash
InvenTree/
├─ .devops/ # Files for Azure DevOps
├─ .github/ # Files for GitHub
│ ├─ actions/ # Reused actions
│ ├─ ISSUE_TEMPLATE/ # Templates for issues and pull requests
│ ├─ workflows/ # CI/CD flows
│ ├─ scripts/ # CI scripts
├─ .vscode/ # Settings for Visual Code IDE
├─ assets/ # General project assets
├─ contrib/ # Files needed for deployments
│ ├─ container/ # Files related to building container images
│ ├─ installer/ # Files needed to build single-file installer
│ ├─ packager.io/ # Files needed for Debian/Ubuntu packages
├─ docs/ # Directory for documentation / General helper files
│ ├─ ci/ # CI for documentation
│ ├─ docs/ # Source for documentation
├─ src/ # Source for application
│ ├─ backend/ # Directory for backend parts
│ │ ├─ InvenTree/ # Source for backend
│ │ ├─ requirements.txt # Dependencies for backend
│ │ ├─ package.json # Dependencies for backend HTML linting
│ ├─ frontend/ # Directory for frontend parts
│ │ ├─ src/ # Source for frontend
│ │ │ ├─ main.tsx # Entry point for frontend
│ │ ├─ tests/ # Tests for frontend
│ │ ├─ netlify.toml # Settings for frontend previews (Netlify)
│ │ ├─ package.json # Dependencies for frontend
│ │ ├─ playwright.config.ts # Settings for frontend tests
│ │ ├─ tsconfig.json # Settings for frontend compilation
├─ .pkgr.yml # Build definition for Debian/Ubuntu packages
├─ .pre-commit-config.yaml # Code formatter/linter configuration
├─ CONTRIBUTING.md # Contirbution guidelines and overview
├─ Procfile # Process definition for Debian/Ubuntu packages
├─ README.md # General project information and overview
├─ runtime.txt # Python runtime settings for Debian/Ubuntu packages build
├─ SECURITY.md # Project security policy
├─ tasks.py # Action definitions for development, testing and deployment
```
Refer to our [contribution guidelines](https://docs.inventree.org/en/latest/develop/contributing/) for more information!

View File

@ -1,7 +1,7 @@
# Web process: gunicorn
web: env/bin/gunicorn --chdir $APP_HOME/InvenTree -c InvenTree/gunicorn.conf.py InvenTree.wsgi -b 0.0.0.0:$PORT
web: env/bin/gunicorn --chdir $APP_HOME/src/backend/InvenTree -c src/backend/InvenTree/gunicorn.conf.py InvenTree.wsgi -b 0.0.0.0:$PORT
# Worker process: qcluster
worker: env/bin/python InvenTree/manage.py qcluster
worker: env/bin/python src/backendInvenTree/manage.py qcluster
# Invoke commands
invoke: echo "" | echo "" && . env/bin/activate && invoke
# CLI: Provided for backwards compatibility

View File

@ -1,5 +1,5 @@
<div align="center">
<img src="images/logo/inventree.png" alt="InvenTree logo" width="200" height="auto" />
<img src="assets/images/logo/inventree.png" alt="InvenTree logo" width="200" height="auto" />
<h1>InvenTree</h1>
<p>Open Source Inventory Management System </p>

View File

Before

Width:  |  Height:  |  Size: 198 KiB

After

Width:  |  Height:  |  Size: 198 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 341 KiB

After

Width:  |  Height:  |  Size: 341 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,31 +0,0 @@
"""Test that the root API endpoint is available."""
import json
import requests
# We expect the server to be running on the local host
url = 'http://localhost:8000/api/'
print('Testing InvenTree API endpoint')
response = requests.get(url)
assert response.status_code == 200
print('- Response 200 OK')
data = json.loads(response.text)
required_keys = ['server', 'version', 'apiVersion', 'worker_running']
for key in required_keys:
assert key in data
print(f"- Found key '{key}'")
# Check that the worker is running
assert data['worker_running']
print('- Background worker is operational')
print('API Endpoint Tests Passed OK')

View File

@ -1,27 +0,0 @@
"""Check that there are no database migration files which have not been committed."""
import subprocess
import sys
print('Checking for uncommitted locale files...')
cmd = ['git', 'status']
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = proc.communicate()
locales = []
for line in str(out.decode()).split('\n'):
# Check for any compiled translation files that have not been committed
if 'modified:' in line and '/locale/' in line and 'django.po' in line:
locales.append(line)
if len(locales) > 0:
print('There are {n} unstaged locale files:'.format(n=len(locales)))
for lang in locales:
print(' - {l}'.format(l=lang))
sys.exit(len(locales))

View File

@ -27,7 +27,6 @@ ENV INVENTREE_DOCKER="true"
# InvenTree paths
ENV INVENTREE_HOME="/home/inventree"
ENV INVENTREE_MNG_DIR="${INVENTREE_HOME}/InvenTree"
ENV INVENTREE_DATA_DIR="${INVENTREE_HOME}/${data_dir}"
ENV INVENTREE_STATIC_ROOT="${INVENTREE_DATA_DIR}/static"
ENV INVENTREE_MEDIA_ROOT="${INVENTREE_DATA_DIR}/media"
@ -75,9 +74,9 @@ EXPOSE 8000
RUN mkdir -p ${INVENTREE_HOME}
WORKDIR ${INVENTREE_HOME}
COPY ./docker/requirements.txt base_requirements.txt
COPY ./requirements.txt ./
COPY ./docker/install_build_packages.sh .
COPY contrib/container/requirements.txt base_requirements.txt
COPY src/backend/requirements.txt ./
COPY contrib/container/install_build_packages.sh .
RUN chmod +x install_build_packages.sh
# For ARMv7 architecture, add the piwheels repo (for cryptography library)
@ -87,7 +86,7 @@ RUN if [ `apk --print-arch` = "armv7" ]; then \
printf "[global]\nextra-index-url=https://www.piwheels.org/simple\n" > /etc/pip.conf ; \
fi
COPY tasks.py docker/gunicorn.conf.py docker/init.sh ./
COPY tasks.py contrib/container/gunicorn.conf.py contrib/container/init.sh ./
RUN chmod +x init.sh
ENTRYPOINT ["/bin/ash", "./init.sh"]
@ -104,10 +103,9 @@ FROM prebuild AS frontend
RUN apk add --no-cache --update nodejs npm && npm install -g yarn@v1.22.22
RUN yarn config set network-timeout 600000 -g
COPY InvenTree ${INVENTREE_HOME}/InvenTree
COPY src ${INVENTREE_HOME}/src
COPY tasks.py ${INVENTREE_HOME}/tasks.py
RUN cd ${INVENTREE_HOME}/InvenTree && inv frontend-compile
RUN cd ${INVENTREE_HOME} && inv frontend-compile
# InvenTree production image:
# - Copies required files from local directory
@ -124,15 +122,19 @@ ENV INVENTREE_COMMIT_DATE="${commit_date}"
ENV PATH=/root/.local/bin:$PATH
COPY --from=prebuild /root/.local /root/.local
ENV INVENTREE_BACKEND_DIR="${INVENTREE_HOME}"
# Copy source code
COPY InvenTree ./InvenTree
COPY --from=frontend ${INVENTREE_HOME}/InvenTree/web/static/web ./InvenTree/web/static/web
COPY src/backend/InvenTree ./InvenTree
COPY --from=frontend ${INVENTREE_HOME}/src/backend/InvenTree/web/static/web ./src/backend/InvenTree/web/static/web
# Launch the production server
CMD gunicorn -c ./gunicorn.conf.py InvenTree.wsgi -b 0.0.0.0:8000 --chdir ./InvenTree
FROM inventree_base AS dev
ENV INVENTREE_BACKEND_DIR="${INVENTREE_HOME}/src/backend"
# Vite server (for local frontend development)
EXPOSE 5173
@ -158,7 +160,7 @@ ENV INVENTREE_PY_ENV="${INVENTREE_DATA_DIR}/env"
WORKDIR ${INVENTREE_HOME}
# Entrypoint ensures that we are running in the python virtual environment
ENTRYPOINT ["/bin/ash", "./docker/init.sh"]
ENTRYPOINT ["/bin/ash", "./contrib/container/init.sh"]
# Launch the development server
CMD ["invoke", "server", "-a", "${INVENTREE_WEB_ADDR}:${INVENTREE_WEB_PORT}"]

View File

@ -40,6 +40,7 @@ services:
- inventree-dev-db
build: &build_config
context: .
dockerfile: contrib/container/Dockerfile
target: dev
# Cache the built image to be used by the inventree-dev-worker process
image: inventree-dev-image
@ -50,7 +51,7 @@ services:
# Mount local source directory to /home/inventree
- ./:/home/inventree:z
env_file:
- docker.dev.env
- contrib/container/docker.dev.env
restart: unless-stopped
# Background worker process handles long-running or periodic tasks
@ -64,5 +65,5 @@ services:
# Mount local source directory to /home/inventree
- ./:/home/inventree:z
env_file:
- docker.dev.env
- contrib/container/docker.dev.env
restart: unless-stopped

View File

@ -28,8 +28,8 @@ fi
if test -f "$INVENTREE_CONFIG_FILE"; then
echo "Loading config file : $INVENTREE_CONFIG_FILE"
else
echo "Copying config file to $INVENTREE_CONFIG_FILE"
cp $INVENTREE_HOME/InvenTree/config_template.yaml $INVENTREE_CONFIG_FILE
echo "Copying config file from $INVENTREE_BACKEND_DIR/InvenTree/config_template.yml to $INVENTREE_CONFIG_FILE"
cp $INVENTREE_BACKEND_DIR/InvenTree/config_template.yaml $INVENTREE_CONFIG_FILE
fi
# Setup a python virtual environment

View File

@ -2,7 +2,7 @@
"append_commit_message": false
files:
- source: /InvenTree/locale/en/LC_MESSAGES/django.po
translation: /InvenTree/locale/%two_letters_code%/LC_MESSAGES/%original_file_name%
- source: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po
translation: /src/backend/InvenTree/locale/%two_letters_code%/LC_MESSAGES/%original_file_name%
- source: /src/frontend/src/locales/en/messages.po
translation: /src/frontend/src/locales/%two_letters_code%/%original_file_name%

View File

@ -9,8 +9,8 @@ The InvenTree server code supports an extensible plugin architecture, allowing c
Plugins can be added from multiple sources:
- Plugins can be installed in InvenTrees venv via PIP (python package manager)
- Custom plugins should be placed in the directory `./InvenTree/plugins`.
- InvenTree built-in plugins are located in the directory `./InvenTree/plugin/builtin`.
- Custom plugins should be placed in the directory `./src/backend/InvenTree/plugins`.
- InvenTree built-in plugins are located in the directory `./src/backend/InvenTree/plugin/builtin`.
For further information, read more about [installing plugins](./plugins/install.md).
@ -28,7 +28,7 @@ Please read all release notes and watch out for warnings - we generally provide
#### Plugins
General classes and mechanisms are provided under the `plugin` [namespaces](https://github.com/inventree/InvenTree/blob/master/InvenTree/plugin/__init__.py). These include:
General classes and mechanisms are provided under the `plugin` [namespaces](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/plugin/__init__.py). These include:
```python
# Management objects
@ -44,7 +44,7 @@ MixinNotImplementedError # Is raised if a mixin was not implemented (core mec
#### Mixins
Mixins are split up internally to keep the source tree clean and enable better testing separation. All public APIs that should be used are exposed under `plugin.mixins`. These include all built-in mixins and notification methods. An up-to-date reference can be found in the source code (current master can be [found here](https://github.com/inventree/InvenTree/blob/master/InvenTree/plugin/mixins/__init__.py)).
Mixins are split up internally to keep the source tree clean and enable better testing separation. All public APIs that should be used are exposed under `plugin.mixins`. These include all built-in mixins and notification methods. An up-to-date reference can be found in the source code (current master can be [found here](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/plugin/mixins/__init__.py)).
#### Models and other internal InvenTree APIs
@ -72,7 +72,7 @@ MIN_VERSION = None # Lowest InvenTree version number that is supported by the p
MAX_VERSION = None # Highest InvenTree version number that is supported by the plugin
```
Refer to the [sample plugins](https://github.com/inventree/InvenTree/tree/master/InvenTree/plugin/samples) for further examples.
Refer to the [sample plugins](https://github.com/inventree/InvenTree/tree/master/src/backend/InvenTree/plugin/samples) for further examples.
### Plugin Config

View File

@ -15,4 +15,4 @@ POST {
}
```
For an example of a very simple action plugin, refer to `/InvenTree/plugin/samples/integratoni/simpleactionplugin.py`
For an example of a very simple action plugin, refer to `/src/backend/InvenTree/plugin/samples/integratoni/simpleactionplugin.py`

View File

@ -6,7 +6,7 @@ title: Barcode Mixin
InvenTree supports decoding of arbitrary barcode data via a **Barcode Plugin** interface. Barcode data POSTed to the `/api/barcode/` endpoint will be supplied to all loaded barcode plugins, and the first plugin to successfully interpret the barcode data will return a response to the client.
InvenTree can generate native QR codes to represent database objects (e.g. a single StockItem). This barcode can then be used to perform quick lookup of a stock item or location in the database. A client application (for example the InvenTree mobile app) scans a barcode, and sends the barcode data to the InvenTree server. The server then uses the **InvenTreeBarcodePlugin** (found at `/InvenTree/plugins/barcode/inventree.py`) to decode the supplied barcode data.
InvenTree can generate native QR codes to represent database objects (e.g. a single StockItem). This barcode can then be used to perform quick lookup of a stock item or location in the database. A client application (for example the InvenTree mobile app) scans a barcode, and sends the barcode data to the InvenTree server. The server then uses the **InvenTreeBarcodePlugin** (found at `/src/backend/InvenTree/plugins/barcode/inventree.py`) to decode the supplied barcode data.
Any third-party barcodes can be decoded by writing a matching plugin to decode the barcode data. These plugins could then perform a server-side action or render a JSON response back to the client for further action.

View File

@ -34,7 +34,7 @@ In certain container environments (such as docker), plugins are installed into a
#### Builtin Plugins
Builtin plugins ship in `src/InvenTree/plugin/builtin`. To achieve full unit-testing for all mixins there are some sample implementations in `src/InvenTree/plugin/samples`.
Builtin plugins ship in `src/backend/InvenTree/plugin/builtin`. To achieve full unit-testing for all mixins there are some sample implementations in `src/backend/InvenTree/plugin/samples`.
!!! success "Builtin Plugins"
Builtin plugins are always enabled, as they are required for core InvenTree functionality
@ -77,7 +77,7 @@ Admin users can install plugins directly from the web interface, via the "Plugin
Custom plugins can be placed in the `src/InvenTree/plugins/` directory, where they will be automatically discovered. This can be useful for developing and testing plugins, but can prove more difficult in production (e.g. when using Docker).
!!! info "Git Tracking"
The `src/InvenTree/plugins/` directory is excluded from Git version tracking - any plugin files here will be hidden from Git
The `src/backend/InvenTree/plugins/` directory is excluded from Git version tracking - any plugin files here will be hidden from Git
!!! warning "Not Recommended For Production"
Loading plugins via the local *plugins* directory is not recommended for production. If you cannot use PIP installation (above), specify a custom plugin directory (below) or use a [VCS](https://pip.pypa.io/en/stable/topics/vcs-support/) as a plugin install source.

View File

@ -28,4 +28,4 @@ If a locate plugin is installed and activated, the [InvenTree mobile app](../../
### Implementation
Refer to the [InvenTree source code](https://github.com/inventree/InvenTree/blob/master/InvenTree/plugin/samples/locate/locate_sample.py) for a simple implementation example.
Refer to the [InvenTree source code](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/plugin/samples/locate/locate_sample.py) for a simple implementation example.

View File

@ -16,7 +16,7 @@ Additionally the `add_label_context` method, allowing custom context data to be
### Example
A sample plugin which provides additional context data to the report templates can be found [in the InvenTree source code](https://github.com/inventree/InvenTree/blob/master/InvenTree/plugin/samples/integration/report_plugin_sample.py):
A sample plugin which provides additional context data to the report templates can be found [in the InvenTree source code](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/plugin/samples/integration/report_plugin_sample.py):
```python
"""Sample plugin for extending reporting functionality"""

View File

@ -59,4 +59,4 @@ class ScheduledTaskPlugin(ScheduleMixin, SettingsMixin, InvenTreePlugin):
```
!!! info "More Info"
For more information on any of the methods described below, refer to the InvenTree source code. [A working example is available as a starting point](https://github.com/inventree/InvenTree/blob/master/InvenTree/plugin/samples/integration/scheduled_task.py).
For more information on any of the methods described below, refer to the InvenTree source code. [A working example is available as a starting point](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/plugin/samples/integration/scheduled_task.py).

View File

@ -9,7 +9,7 @@ The `ValidationMixin` class enables plugins to perform custom validation of obje
Any of the methods described below can be implemented in a custom plugin to provide functionality as required.
!!! info "More Info"
For more information on any of the methods described below, refer to the InvenTree source code. [A working example is available as a starting point](https://github.com/inventree/InvenTree/blob/master/InvenTree/plugin/samples/integration/validation_sample.py).
For more information on any of the methods described below, refer to the InvenTree source code. [A working example is available as a starting point](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/plugin/samples/integration/validation_sample.py).
!!! info "Multi Plugin Support"
It is possible to have multiple plugins loaded simultaneously which support validation methods. For example when validating a field, if one plugin returns a null value (`None`) then the *next* plugin (if available) will be queried.

View File

@ -183,4 +183,4 @@ Finally added a `{% raw %}|floatformat:0{% endraw %}` to the quantity that remov
A default *BOM Report* template is provided out of the box, which is useful for generating simple test reports. Furthermore, it may be used as a starting point for developing custom BOM reports:
View the [source code](https://github.com/inventree/InvenTree/blob/master/InvenTree/report/templates/report/inventree_bill_of_materials_report.html) for the default test report template.
View the [source code](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/report/templates/report/inventree_bill_of_materials_report.html) for the default test report template.

View File

@ -321,4 +321,4 @@ This will result a report page like this:
A default *Build Report* template is provided out of the box, which is useful for generating simple test reports. Furthermore, it may be used as a starting point for developing custom BOM reports:
View the [source code](https://github.com/inventree/InvenTree/blob/master/InvenTree/report/templates/report/inventree_build_order_base.html) for the default build report template.
View the [source code](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/report/templates/report/inventree_build_order_base.html) for the default build report template.

View File

@ -12,7 +12,7 @@ Some common functions are provided for use in custom report and label templates.
```
!!! tip "Use the Source, Luke"
To see the full range of available helper functions, refer to the source file [report.py](https://github.com/inventree/InvenTree/blob/master/InvenTree/report/templatetags/report.py) where these functions are defined!
To see the full range of available helper functions, refer to the source file [report.py](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/report/templatetags/report.py) where these functions are defined!
## Assigning Variables

View File

@ -62,4 +62,4 @@ Price: {% render_currency line.total_line_price %}
A default *Purchase Order Report* template is provided out of the box, which is useful for generating simple test reports. Furthermore, it may be used as a starting point for developing custom BOM reports:
View the [source code](https://github.com/inventree/InvenTree/blob/master/InvenTree/report/templates/report/inventree_po_report_base.html) for the default purchase order report template.
View the [source code](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/report/templates/report/inventree_po_report_base.html) for the default purchase order report template.

View File

@ -159,7 +159,7 @@ InvenTree supports the following reporting functionality:
InvenTree is supplied with a number of default templates "out of the box". These are generally quite simple, but serve as a starting point for building custom reports to suit a specific need.
!!! tip "Read the Source"
The source code for the default reports is [available on GitHub](https://github.com/inventree/InvenTree/tree/master/InvenTree/report/templates/report). Use this as a guide for generating your own reports!
The source code for the default reports is [available on GitHub](https://github.com/inventree/InvenTree/tree/master/src/backend/InvenTree/report/templates/report). Use this as a guide for generating your own reports!
## Creating Reports

View File

@ -23,4 +23,4 @@ In addition to the default report context variables, the following context varia
A default report template is provided out of the box, which can be used as a starting point for developing custom return order report templates.
View the [source code](https://github.com/inventree/InvenTree/blob/master/InvenTree/report/templates/report/inventree_return_order_report_base.html) for the default return order report template.
View the [source code](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/report/templates/report/inventree_return_order_report_base.html) for the default return order report template.

View File

@ -28,4 +28,4 @@ In addition to the default report context variables, the following variables are
A default *Sales Order Report* template is provided out of the box, which is useful for generating simple test reports. Furthermore, it may be used as a starting point for developing custom BOM reports:
View the [source code](https://github.com/inventree/InvenTree/blob/master/InvenTree/report/templates/report/inventree_so_report_base.html) for the default sales order report template.
View the [source code](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/report/templates/report/inventree_so_report_base.html) for the default sales order report template.

View File

@ -84,4 +84,4 @@ A default *Test Report* template is provided out of the box, which is useful for
{% include "img.html" %}
{% endwith %}
View the [source code](https://github.com/inventree/InvenTree/blob/master/InvenTree/report/templates/report/inventree_test_report_base.html) for the default test report template.
View the [source code](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/report/templates/report/inventree_test_report_base.html) for the default test report template.

View File

@ -72,7 +72,7 @@ sudo apt-get install supervisor
Copy the supervisor configuration file:
```
sudo cp /home/inventree/src/deploy/supervisord.conf /etc/supervisord.conf
sudo cp /home/inventree/src/contrib/deploy/supervisord.conf /etc/supervisord.conf
```
### Start Supervisor Daemon

View File

@ -22,7 +22,7 @@ The InvenTree server tries to locate the `config.yaml` configuration file on sta
!!! tip "Config File Location"
When the InvenTree server boots, it will report the location where it expects to find the configuration file
The configuration file *template* can be found on [GitHub](https://github.com/inventree/InvenTree/blob/master/InvenTree/config_template.yaml)
The configuration file *template* can be found on [GitHub](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/config_template.yaml)
!!! info "Template File"
The default configuration file (as defined by the template linked above) will be copied to the specified configuration file location on first run, if a configuration file is not found in that location.

View File

@ -273,7 +273,7 @@ markdown_extensions:
# Global Variables
extra:
static_folder_source: ./InvenTree/InvenTree/static/
static_folder_source: ./src/backend/InvenTree/InvenTree/static/
static_folder_local_default: ./inventree_static/
# Site Analytics

View File

@ -11,8 +11,9 @@ exclude = [
"env",
".venv",
".env",
"src/backend/plugins/*",
]
src = ["InvenTree"]
src = ["src/backend/InvenTree"]
# line-length = 120
[tool.ruff.extend-per-file-ignores]
@ -69,13 +70,13 @@ skip-magic-trailing-comma = true
line-ending = "auto"
[tool.coverage.run]
source = ["InvenTree", ]
source = ["src/backend/InvenTree", "InvenTree"]
[tool.djlint]
ignore = "D018,H006,H008,H020,H021,H023,H025,H030,H031,T002"
[tool.isort]
src_paths=["InvenTree", "../InvenTree"]
src_paths=["src/backend/InvenTree", ]
skip_glob ="*/migrations/*.py"
known_django="django"
sections=["FUTURE","STDLIB","DJANGO","THIRDPARTY","FIRSTPARTY","LOCALFOLDER"]

View File

@ -6,7 +6,7 @@ mkdocs:
python:
install:
- requirements: docs/requirements.txt
- requirements: requirements.txt
- requirements: src/backend/requirements.txt
build:
os: "ubuntu-22.04"

View File

@ -1,353 +1,3 @@
# This file was autogenerated by uv via the following command:
# uv pip compile requirements.in -o requirements.txt --python-version=3.9 --no-strip-extras
asgiref==3.8.0
# via
# django
# django-cors-headers
async-timeout==4.0.3
# via redis
attrs==23.2.0
# via
# jsonschema
# referencing
babel==2.14.0
# via py-moneyed
bleach[css]==6.1.0
# via django-markdownify
brotli==1.1.0
# via fonttools
certifi==2024.2.2
# via
# requests
# sentry-sdk
cffi==1.16.0
# via
# cryptography
# weasyprint
charset-normalizer==3.3.2
# via requests
coreapi==2.3.3
coreschema==0.0.4
# via coreapi
cryptography==42.0.5
# via
# djangorestframework-simplejwt
# pyjwt
cssselect2==0.7.0
# via weasyprint
defusedxml==0.7.1
# via
# odfpy
# python3-openid
deprecated==1.2.14
# via
# opentelemetry-api
# opentelemetry-exporter-otlp-proto-grpc
# opentelemetry-exporter-otlp-proto-http
diff-match-patch==20230430
# via django-import-export
dj-rest-auth==5.0.2
django==4.2.11
# via
# dj-rest-auth
# django-allauth
# django-allauth-2fa
# django-cors-headers
# django-dbbackup
# django-error-report-2
# django-filter
# django-flags
# django-formtools
# django-ical
# django-import-export
# django-js-asset
# django-markdownify
# django-money
# django-otp
# django-picklefield
# django-q2
# django-recurrence
# django-redis
# django-sesame
# django-sql-utils
# django-sslserver
# django-stdimage
# django-taggit
# django-user-sessions
# django-weasyprint
# django-xforwardedfor-middleware
# djangorestframework
# djangorestframework-simplejwt
# drf-spectacular
django-allauth==0.61.1
# via django-allauth-2fa
django-allauth-2fa==0.11.1
django-cleanup==8.1.0
django-cors-headers==4.3.1
django-crispy-forms==1.14.0
django-dbbackup==4.1.0
django-error-report-2==0.4.2
django-filter==24.1
django-flags==5.0.13
django-formtools==2.5.1
django-ical==1.9.2
django-import-export==3.3.7
django-js-asset==2.2.0
# via django-mptt
django-maintenance-mode==0.21.1
django-markdownify==0.9.3
django-money==3.2.0
django-mptt==0.16.0
django-otp==1.3.0
# via django-allauth-2fa
django-picklefield==3.1
# via django-q2
django-q-sentry==0.1.6
django-q2==1.6.2
django-recurrence==1.11.1
# via django-ical
django-redis==5.4.0
django-sesame==3.2.2
django-sql-utils==0.7.0
django-sslserver==0.22
django-stdimage==6.0.2
django-taggit==5.0.1
django-user-sessions==2.0.0
django-weasyprint==2.3.0
django-xforwardedfor-middleware==2.0
djangorestframework==3.14.0
# via
# dj-rest-auth
# djangorestframework-simplejwt
# drf-spectacular
djangorestframework-simplejwt[crypto]==5.3.1
drf-spectacular==0.27.1
dulwich==0.21.7
et-xmlfile==1.1.0
# via openpyxl
feedparser==6.0.11
fonttools[woff]==4.50.0
# via weasyprint
googleapis-common-protos==1.63.0
# via
# opentelemetry-exporter-otlp-proto-grpc
# opentelemetry-exporter-otlp-proto-http
grpcio==1.62.1
# via opentelemetry-exporter-otlp-proto-grpc
gunicorn==21.2.0
html5lib==1.1
# via weasyprint
icalendar==5.0.12
# via django-ical
idna==3.6
# via requests
importlib-metadata==6.11.0
# via
# django-q2
# markdown
# opentelemetry-api
inflection==0.5.1
# via drf-spectacular
itypes==1.2.0
# via coreapi
jinja2==3.1.3
# via coreschema
jsonschema==4.21.1
# via drf-spectacular
jsonschema-specifications==2023.12.1
# via jsonschema
markdown==3.6
# via django-markdownify
markuppy==1.14
# via tablib
markupsafe==2.1.5
# via jinja2
oauthlib==3.2.2
# via requests-oauthlib
odfpy==1.4.1
# via tablib
openpyxl==3.1.2
# via tablib
opentelemetry-api==1.23.0
# via
# opentelemetry-exporter-otlp-proto-grpc
# opentelemetry-exporter-otlp-proto-http
# opentelemetry-instrumentation
# opentelemetry-instrumentation-django
# opentelemetry-instrumentation-redis
# opentelemetry-instrumentation-requests
# opentelemetry-instrumentation-wsgi
# opentelemetry-sdk
opentelemetry-exporter-otlp==1.23.0
opentelemetry-exporter-otlp-proto-common==1.23.0
# via
# opentelemetry-exporter-otlp-proto-grpc
# opentelemetry-exporter-otlp-proto-http
opentelemetry-exporter-otlp-proto-grpc==1.23.0
# via opentelemetry-exporter-otlp
opentelemetry-exporter-otlp-proto-http==1.23.0
# via opentelemetry-exporter-otlp
opentelemetry-instrumentation==0.44b0
# via
# opentelemetry-instrumentation-django
# opentelemetry-instrumentation-redis
# opentelemetry-instrumentation-requests
# opentelemetry-instrumentation-wsgi
opentelemetry-instrumentation-django==0.44b0
opentelemetry-instrumentation-redis==0.44b0
opentelemetry-instrumentation-requests==0.44b0
opentelemetry-instrumentation-wsgi==0.44b0
# via opentelemetry-instrumentation-django
opentelemetry-proto==1.23.0
# via
# opentelemetry-exporter-otlp-proto-common
# opentelemetry-exporter-otlp-proto-grpc
# opentelemetry-exporter-otlp-proto-http
opentelemetry-sdk==1.23.0
# via
# opentelemetry-exporter-otlp-proto-grpc
# opentelemetry-exporter-otlp-proto-http
opentelemetry-semantic-conventions==0.44b0
# via
# opentelemetry-instrumentation-django
# opentelemetry-instrumentation-redis
# opentelemetry-instrumentation-requests
# opentelemetry-instrumentation-wsgi
# opentelemetry-sdk
opentelemetry-util-http==0.44b0
# via
# opentelemetry-instrumentation-django
# opentelemetry-instrumentation-requests
# opentelemetry-instrumentation-wsgi
packaging==24.0
# via gunicorn
pdf2image==1.17.0
pillow==10.2.0
# via
# django-stdimage
# pdf2image
# python-barcode
# qrcode
# weasyprint
pint==0.21
protobuf==4.25.3
# via
# googleapis-common-protos
# opentelemetry-proto
py-moneyed==3.0
# via django-money
pycparser==2.21
# via cffi
pydyf==0.9.0
# via weasyprint
pyjwt[crypto]==2.8.0
# via
# django-allauth
# djangorestframework-simplejwt
pyphen==0.14.0
# via weasyprint
pypng==0.20220715.0
# via qrcode
python-barcode[images]==0.15.1
python-dateutil==2.9.0.post0
# via
# django-recurrence
# icalendar
python-dotenv==1.0.1
python-fsutil==0.14.1
# via django-maintenance-mode
python3-openid==3.2.0
# via django-allauth
pytz==2024.1
# via
# django-dbbackup
# djangorestframework
# icalendar
pyyaml==6.0.1
# via
# drf-spectacular
# tablib
qrcode[pil]==7.4.2
# via django-allauth-2fa
rapidfuzz==3.6.2
redis==5.0.3
# via django-redis
referencing==0.34.0
# via
# jsonschema
# jsonschema-specifications
regex==2023.12.25
requests==2.31.0
# via
# coreapi
# django-allauth
# opentelemetry-exporter-otlp-proto-http
# requests-oauthlib
requests-oauthlib==1.4.0
# via django-allauth
rpds-py==0.18.0
# via
# jsonschema
# referencing
sentry-sdk==1.43.0
# via django-q-sentry
setuptools==69.2.0
# via
# django-money
# opentelemetry-instrumentation
sgmllib3k==1.0.0
# via feedparser
six==1.16.0
# via
# bleach
# html5lib
# python-dateutil
sqlparse==0.4.4
# via
# django
# django-sql-utils
tablib[html, ods, xls, xlsx, yaml]==3.5.0
# via django-import-export
tinycss2==1.2.1
# via
# bleach
# cssselect2
# weasyprint
typing-extensions==4.10.0
# via
# asgiref
# drf-spectacular
# opentelemetry-sdk
# py-moneyed
# qrcode
uritemplate==4.1.1
# via
# coreapi
# drf-spectacular
urllib3==2.2.1
# via
# dulwich
# requests
# sentry-sdk
weasyprint==61.2
# via django-weasyprint
webencodings==0.5.1
# via
# bleach
# cssselect2
# html5lib
# tinycss2
whitenoise==6.6.0
wrapt==1.16.0
# via
# deprecated
# opentelemetry-instrumentation
# opentelemetry-instrumentation-redis
xlrd==2.0.1
# via tablib
xlwt==1.3.0
# via tablib
zipp==3.18.1
# via importlib-metadata
zopfli==0.2.3
# via fonttools
# Dummy requirements file to trigger the package pipeline
# The new requirements file is located in src/backend/requirements.txt
#

View File

@ -1142,7 +1142,7 @@ login_attempts = get_setting('INVENTREE_LOGIN_ATTEMPTS', 'login_attempts', 5)
try:
login_attempts = int(login_attempts)
login_attempts = f'{login_attempts}/m/ip,{login_attempts}/m/key'
login_attempts = f'{login_attempts}/m,{login_attempts}/m'
except ValueError:
pass

Some files were not shown because too many files have changed in this diff Show More