2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-17 12:35:46 +00:00
Files
InvenTree/InvenTree/label/apps.py
Matthias Mair 0c97a50e47 Docstring checks in QC checks (#3089)
* Add pre-commit to the stack

* exclude static

* Add locales to excludes

* fix style errors

* rename pipeline steps

* also wait on precommit

* make template matching simpler

* Use the same code for python setup everywhere

* use step and cache for python setup

* move regular settings up into general envs

* just use full update

* Use invoke instead of static references

* make setup actions more similar

* use python3

* refactor names to be similar

* fix runner version

* fix references

* remove incidential change

* use matrix for os

* Github can't do this right now

* ignore docstyle errors

* Add seperate docstring test

* update flake call

* do not fail on docstring

* refactor setup into workflow

* update reference

* switch to action

* resturcture

* add bash statements

* remove os from cache

* update input checks

* make code cleaner

* fix boolean

* no relative paths

* install wheel by python

* switch to install

* revert back to simple wheel

* refactor import export tests

* move setup keys back to not disturbe tests

* remove docstyle till that is fixed

* update references

* continue on error

* add docstring test

* use relativ action references

* Change step / job docstrings

* update to merge

* reformat comments 1

* fix docstrings 2

* fix docstrings 3

* fix docstrings 4

* fix docstrings 5

* fix docstrings 6

* fix docstrings 7

* fix docstrings 8

* fix docstirns 9

* fix docstrings 10

* docstring adjustments

* update the remaining docstrings

* small docstring changes

* fix function name

* update support files for docstrings

* Add missing args to docstrings

* Remove outdated function

* Add docstrings for the 'build' app

* Make API code cleaner

* add more docstrings for plugin app

* Remove dead code for plugin settings
No idea what that was even intended for

* ignore __init__ files for docstrings

* More docstrings

* Update docstrings for the 'part' directory

* Fixes for related_part functionality

* Fix removed stuff from merge 99676ee

* make more consistent

* Show statistics for docstrings

* add more docstrings

* move specific register statements to make them clearer to understant

* More docstrings for common

* and more docstrings

* and more

* simpler call

* docstrings for notifications

* docstrings for common/tests

* Add docs for common/models

* Revert "move specific register statements to make them clearer to understant"

This reverts commit ca96654622.

* use typing here

* Revert "Make API code cleaner"

This reverts commit 24fb68bd3e.

* docstring updates for the 'users' app

* Add generic Meta info to simple Meta classes

* remove unneeded unique_together statements

* More simple metas

* Remove unnecessary format specifier

* Remove extra json format specifiers

* Add docstrings for the 'plugin' app

* Docstrings for the 'label' app

* Add missing docstrings for the 'report' app

* Fix build test regression

* Fix top-level files

* docstrings for InvenTree/InvenTree

* reduce unneeded code

* add docstrings

* and more docstrings

* more docstrings

* more docstrings for stock

* more docstrings

* docstrings for order/views

* Docstrings for various files in the 'order' app

* Docstrings for order/test_api.py

* Docstrings for order/serializers.py

* Docstrings for order/admin.py

* More docstrings for the order app

* Add docstrings for the 'company' app

* Add unit tests for rebuilding the reference fields

* Prune out some more dead code

* remove more dead code

Co-authored-by: Oliver Walters <oliver.henry.walters@gmail.com>
2022-06-02 01:37:39 +10:00

302 lines
9.1 KiB
Python

"""label app specification"""
import hashlib
import logging
import os
import shutil
import warnings
from django.apps import AppConfig
from django.conf import settings
from django.core.exceptions import AppRegistryNotReady
from InvenTree.ready import canAppAccessDatabase
logger = logging.getLogger("inventree")
def hashFile(filename):
"""Calculate the MD5 hash of a file."""
md5 = hashlib.md5()
with open(filename, 'rb') as f:
data = f.read()
md5.update(data)
return md5.hexdigest()
class LabelConfig(AppConfig):
"""App configuration class for the 'label' app"""
name = 'label'
def ready(self):
"""This function is called whenever the label app is loaded."""
if canAppAccessDatabase():
self.create_labels() # pragma: no cover
def create_labels(self):
"""Create all default templates."""
# Test if models are ready
try:
from .models import StockLocationLabel
assert bool(StockLocationLabel is not None)
except AppRegistryNotReady: # pragma: no cover
# Database might not yet be ready
warnings.warn('Database was not ready for creating labels')
return
self.create_stock_item_labels()
self.create_stock_location_labels()
self.create_part_labels()
def create_stock_item_labels(self):
"""Create database entries for the default StockItemLabel templates, if they do not already exist."""
from .models import StockItemLabel
src_dir = os.path.join(
os.path.dirname(os.path.realpath(__file__)),
'templates',
'label',
'stockitem',
)
dst_dir = os.path.join(
settings.MEDIA_ROOT,
'label',
'inventree',
'stockitem',
)
if not os.path.exists(dst_dir):
logger.info(f"Creating required directory: '{dst_dir}'")
os.makedirs(dst_dir, exist_ok=True)
labels = [
{
'file': 'qr.html',
'name': 'QR Code',
'description': 'Simple QR code label',
'width': 24,
'height': 24,
},
]
for label in labels:
filename = os.path.join(
'label',
'inventree',
'stockitem',
label['file'],
)
# Check if the file exists in the media directory
src_file = os.path.join(src_dir, label['file'])
dst_file = os.path.join(settings.MEDIA_ROOT, filename)
to_copy = False
if os.path.exists(dst_file):
# File already exists - let's see if it is the "same",
# or if we need to overwrite it with a newer copy!
if hashFile(dst_file) != hashFile(src_file): # pragma: no cover
logger.info(f"Hash differs for '{filename}'")
to_copy = True
else:
logger.info(f"Label template '{filename}' is not present")
to_copy = True
if to_copy:
logger.info(f"Copying label template '{dst_file}'")
shutil.copyfile(src_file, dst_file)
# Check if a label matching the template already exists
if StockItemLabel.objects.filter(label=filename).exists():
continue # pragma: no cover
logger.info(f"Creating entry for StockItemLabel '{label['name']}'")
StockItemLabel.objects.create(
name=label['name'],
description=label['description'],
label=filename,
filters='',
enabled=True,
width=label['width'],
height=label['height'],
)
def create_stock_location_labels(self):
"""Create database entries for the default StockItemLocation templates, if they do not already exist."""
from .models import StockLocationLabel
src_dir = os.path.join(
os.path.dirname(os.path.realpath(__file__)),
'templates',
'label',
'stocklocation',
)
dst_dir = os.path.join(
settings.MEDIA_ROOT,
'label',
'inventree',
'stocklocation',
)
if not os.path.exists(dst_dir):
logger.info(f"Creating required directory: '{dst_dir}'")
os.makedirs(dst_dir, exist_ok=True)
labels = [
{
'file': 'qr.html',
'name': 'QR Code',
'description': 'Simple QR code label',
'width': 24,
'height': 24,
},
{
'file': 'qr_and_text.html',
'name': 'QR and text',
'description': 'Label with QR code and name of location',
'width': 50,
'height': 24,
}
]
for label in labels:
filename = os.path.join(
'label',
'inventree',
'stocklocation',
label['file'],
)
# Check if the file exists in the media directory
src_file = os.path.join(src_dir, label['file'])
dst_file = os.path.join(settings.MEDIA_ROOT, filename)
to_copy = False
if os.path.exists(dst_file):
# File already exists - let's see if it is the "same",
# or if we need to overwrite it with a newer copy!
if hashFile(dst_file) != hashFile(src_file): # pragma: no cover
logger.info(f"Hash differs for '{filename}'")
to_copy = True
else:
logger.info(f"Label template '{filename}' is not present")
to_copy = True
if to_copy:
logger.info(f"Copying label template '{dst_file}'")
shutil.copyfile(src_file, dst_file)
# Check if a label matching the template already exists
if StockLocationLabel.objects.filter(label=filename).exists():
continue # pragma: no cover
logger.info(f"Creating entry for StockLocationLabel '{label['name']}'")
StockLocationLabel.objects.create(
name=label['name'],
description=label['description'],
label=filename,
filters='',
enabled=True,
width=label['width'],
height=label['height'],
)
def create_part_labels(self):
"""Create database entries for the default PartLabel templates, if they do not already exist."""
from .models import PartLabel
src_dir = os.path.join(
os.path.dirname(os.path.realpath(__file__)),
'templates',
'label',
'part',
)
dst_dir = os.path.join(
settings.MEDIA_ROOT,
'label',
'inventree',
'part',
)
if not os.path.exists(dst_dir):
logger.info(f"Creating required directory: '{dst_dir}'")
os.makedirs(dst_dir, exist_ok=True)
labels = [
{
'file': 'part_label.html',
'name': 'Part Label',
'description': 'Simple part label',
'width': 70,
'height': 24,
},
{
'file': 'part_label_code128.html',
'name': 'Barcode Part Label',
'description': 'Simple part label with Code128 barcode',
'width': 70,
'height': 24,
},
]
for label in labels:
filename = os.path.join(
'label',
'inventree',
'part',
label['file']
)
src_file = os.path.join(src_dir, label['file'])
dst_file = os.path.join(settings.MEDIA_ROOT, filename)
to_copy = False
if os.path.exists(dst_file):
# File already exists - let's see if it is the "same"
if hashFile(dst_file) != hashFile(src_file): # pragma: no cover
logger.info(f"Hash differs for '{filename}'")
to_copy = True
else:
logger.info(f"Label template '{filename}' is not present")
to_copy = True
if to_copy:
logger.info(f"Copying label template '{dst_file}'")
shutil.copyfile(src_file, dst_file)
# Check if a label matching the template already exists
if PartLabel.objects.filter(label=filename).exists():
continue # pragma: no cover
logger.info(f"Creating entry for PartLabel '{label['name']}'")
PartLabel.objects.create(
name=label['name'],
description=label['description'],
label=filename,
filters='',
enabled=True,
width=label['width'],
height=label['height'],
)