Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
matmair committed May 27, 2024
2 parents 8579fd4 + 5577a08 commit 000be47
Show file tree
Hide file tree
Showing 31 changed files with 327 additions and 215 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ jobs:
python-version: ${{ env.python_version }}
- name: Version Check
run: |
pip install --require-hashes -r .github/requirements.txt
pip install --require-hashes -r contrib/dev_reqs/requirements.txt
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
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/qc_checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ jobs:
uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # [email protected]
- name: Check Version
run: |
pip install --require-hashes -r .github/requirements.txt
pip install --require-hashes -r contrib/dev_reqs/requirements.txt
python3 .github/scripts/version_check.py
mkdocs:
Expand All @@ -122,7 +122,7 @@ jobs:
python-version: ${{ env.python_version }}
- name: Check Config
run: |
pip install --require-hashes -r .github/requirements.txt
pip install --require-hashes -r contrib/dev_reqs/requirements.txt
pip install --require-hashes -r docs/requirements.txt
python docs/ci/check_mkdocs_config.py
- name: Check Links
Expand Down Expand Up @@ -168,7 +168,7 @@ jobs:
- name: Download public schema
if: needs.paths-filter.outputs.api == 'false'
run: |
pip install --require-hashes -r .github/requirements.txt >/dev/null 2>&1
pip install --require-hashes -r contrib/dev_reqs/requirements.txt >/dev/null 2>&1
version="$(python3 .github/scripts/version_check.py only_version 2>&1)"
echo "Version: $version"
url="https://raw.githubusercontent.com/inventree/schema/main/export/${version}/api.yaml"
Expand All @@ -187,7 +187,7 @@ jobs:
id: version
if: github.ref == 'refs/heads/master' && needs.paths-filter.outputs.api == 'true'
run: |
pip install --require-hashes -r .github/requirements.txt >/dev/null 2>&1
pip install --require-hashes -r contrib/dev_reqs/requirements.txt >/dev/null 2>&1
version="$(python3 .github/scripts/version_check.py only_version 2>&1)"
echo "Version: $version"
echo "version=$version" >> "$GITHUB_OUTPUT"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # [email protected]
- name: Version Check
run: |
pip install --require-hashes -r .github/requirements.txt
pip install --require-hashes -r contrib/dev_reqs/requirements.txt
python3 .github/scripts/version_check.py
- name: Push to Stable Branch
uses: ad-m/github-push-action@d91a481090679876dfc4178fef17f286781251df # [email protected]
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ repos:
files: src/backend/requirements\.(in|txt)$
- id: pip-compile
name: pip-compile requirements.txt
args: [.github/requirements.in, -o, .github/requirements.txt,--python-version=3.9, --no-strip-extras, --generate-hashes]
files: .github/requirements\.(in|txt)$
args: [contrib/dev_reqs/requirements.in, -o, contrib/dev_reqs/requirements.txt,--python-version=3.9, --no-strip-extras, --generate-hashes]
files: contrib/dev_reqs/requirements\.(in|txt)$
- id: pip-compile
name: pip-compile requirements.txt
args: [docs/requirements.in, -o, docs/requirements.txt,--python-version=3.9, --no-strip-extras, --generate-hashes]
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# This file was autogenerated by uv via the following command:
# uv pip compile .github/requirements.in -o .github/requirements.txt --python-version=3.9 --no-strip-extras --generate-hashes
# uv pip compile contrib/dev_reqs/requirements.in -o contrib/dev_reqs/requirements.txt --python-version=3.9 --no-strip-extras --generate-hashes
certifi==2024.2.2 \
--hash=sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f \
--hash=sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1
Expand Down
36 changes: 35 additions & 1 deletion contrib/packager.io/functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ function detect_ip() {
echo "IP address is ${INVENTREE_IP}"
}

function detect_python() {
# Detect if there is already a python version installed in /opt/inventree/env/lib
if test -f "${APP_HOME}/env/bin/python"; then
echo "# Python environment already present"
# Extract earliest python version initialised from /opt/inventree/env/lib
SETUP_PYTHON=$(ls -1 ${APP_HOME}/env/bin/python* | sort | head -n 1)
echo "# Found earliest version: ${SETUP_PYTHON}"
else
echo "# No python environment found - using ${SETUP_PYTHON}"
fi
}

function get_env() {
envname=$1

Expand Down Expand Up @@ -90,7 +102,7 @@ function detect_envs() {
echo "# Using existing config file: ${INVENTREE_CONFIG_FILE}"

# Install parser
pip install --require-hashes -r ${APP_HOME}/.github/requirements.txt -q
pip install --require-hashes -r ${APP_HOME}/contrib/dev_reqs/requirements.txt -q

# Load config
local CONF=$(cat ${INVENTREE_CONFIG_FILE} | jc --yaml)
Expand Down Expand Up @@ -163,12 +175,20 @@ function create_initscripts() {
sudo -u ${APP_USER} --preserve-env=$SETUP_ENVS bash -c "cd ${APP_HOME} && ${SETUP_PYTHON} -m venv env"
sudo -u ${APP_USER} --preserve-env=$SETUP_ENVS bash -c "cd ${APP_HOME} && env/bin/pip install invoke wheel"

# Check INSTALLER_EXTRA exists and load it
if test -f "${APP_HOME}/INSTALLER_EXTRA"; then
echo "# Loading extra packages from INSTALLER_EXTRA"
source ${APP_HOME}/INSTALLER_EXTRA
fi

if [ -n "${SETUP_EXTRA_PIP}" ]; then
echo "# Installing extra pip packages"
if [ -n "${SETUP_DEBUG}" ]; then
echo "# Extra pip packages: ${SETUP_EXTRA_PIP}"
fi
sudo -u ${APP_USER} --preserve-env=$SETUP_ENVS bash -c "cd ${APP_HOME} && env/bin/pip install ${SETUP_EXTRA_PIP}"
# Write extra packages to INSTALLER_EXTRA
echo "SETUP_EXTRA_PIP='${SETUP_EXTRA_PIP}'" >>${APP_HOME}/INSTALLER_EXTRA
fi
fi

Expand Down Expand Up @@ -283,6 +303,20 @@ function set_env() {
chown ${APP_USER}:${APP_GROUP} ${DATA_DIR} ${INVENTREE_CONFIG_FILE}
}

function set_site() {
# Ensure IP is known
if [ -z "${INVENTREE_IP}" ]; then
echo "# No IP address found - skipping"
return
fi

# Check if INVENTREE_SITE_URL in inventree config
if [ -z "$(inventree config:get INVENTREE_SITE_URL)" ]; then
echo "# Setting up InvenTree site URL"
inventree config:set INVENTREE_SITE_URL=http://${INVENTREE_IP}
fi
}

function final_message() {
echo -e "####################################################################################"
echo -e "This InvenTree install uses nginx, the settings for the webserver can be found in"
Expand Down
2 changes: 2 additions & 0 deletions contrib/packager.io/postinstall.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ detect_envs
detect_docker
detect_initcmd
detect_ip
detect_python

# create processes
create_initscripts
Expand All @@ -45,6 +46,7 @@ update_or_install
if [ "${SETUP_CONF_LOADED}" = "true" ]; then
set_env
fi
set_site
start_inventree

# show info
Expand Down
1 change: 0 additions & 1 deletion docs/docs/report/context_variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ In addition to the model-specific context variables, the following global contex
| base_url | The base URL for the InvenTree instance |
| date | Current date, represented as a Python datetime.date object |
| datetime | Current datetime, represented as a Python datetime object |
| request | The Django request object associated with the printing process |
| template | The report template instance which is being rendered against |
| template_description | Description of the report template |
| template_name | Name of the report template |
Expand Down
6 changes: 5 additions & 1 deletion docs/docs/start/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ 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]({{ sourcefile("src/backend/InvenTree/config_template.yaml") }})
#### Configuration File Template

The configuration file *template* can be found on [GitHub]({{ sourcefile("src/backend/InvenTree/config_template.yaml") }}), and is shown below:

{{ includefile("src/backend/InvenTree/config_template.yaml", "Configuration File Template", format="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.
Expand Down
38 changes: 24 additions & 14 deletions docs/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,27 +167,37 @@ def listimages(subdir):
return assets

@env.macro
def templatefile(filename):
"""Include code for a provided template file."""
here = os.path.dirname(__file__)
template_dir = os.path.join(
here, '..', 'src', 'backend', 'InvenTree', 'report', 'templates'
)
template_file = os.path.join(template_dir, filename)
template_file = os.path.abspath(template_file)
def includefile(filename: str, title: str, format: str = ''):
"""Include a file in the documentation, in a 'collapse' block.
basename = os.path.basename(filename)
Arguments:
- filename: The name of the file to include (relative to the top-level directory)
- title:
"""
here = os.path.dirname(__file__)
path = os.path.join(here, '..', filename)
path = os.path.abspath(path)

if not os.path.exists(template_file):
raise FileNotFoundError(f'Report template file {filename} does not exist.')
if not os.path.exists(path):
raise FileNotFoundError(f'Required file {path} does not exist.')

with open(template_file, 'r') as f:
with open(path, 'r') as f:
content = f.read()

data = f'??? abstract "Template: {basename}"\n\n'
data += ' ```html\n'
data = f'??? abstract "{title}"\n\n'
data += f' ```{format}\n'
data += textwrap.indent(content, ' ')
data += '\n\n'
data += ' ```\n\n'

return data

@env.macro
def templatefile(filename):
"""Include code for a provided template file."""
base = os.path.basename(filename)
fn = os.path.join(
'src', 'backend', 'InvenTree', 'report', 'templates', filename
)

return includefile(fn, f'Template: {base}', format='html')
5 changes: 4 additions & 1 deletion src/backend/InvenTree/InvenTree/api_version.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
"""InvenTree API version information."""

# InvenTree API version
INVENTREE_API_VERSION = 201
INVENTREE_API_VERSION = 202

"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""

INVENTREE_API_TEXT = """
v202 - 2024-05-27 : https://github.com/inventree/InvenTree/pull/7343
- Adjust "required" attribute of Part.category field to be optional
v201 - 2024-05-21 : https://github.com/inventree/InvenTree/pull/7074
- Major refactor of the report template / report printing interface
- This is a *breaking change* to the report template API
Expand Down
70 changes: 51 additions & 19 deletions src/backend/InvenTree/InvenTree/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,26 +115,57 @@ def determine_metadata(self, request, view):

return metadata

def override_value(self, field_name, field_value, model_value):
"""Override a value on the serializer with a matching value for the model.
This is used to override the serializer values with model values,
if (and *only* if) the model value should take precedence.
The values are overridden under the following conditions:
- field_value is None
- model_value is callable, and field_value is not (this indicates that the model value is translated)
- model_value is not a string, and field_value is a string (this indicates that the model value is translated)
"""
if model_value and not field_value:
return model_value

if field_value and not model_value:
return field_value

if callable(model_value) and not callable(field_value):
return model_value

if type(model_value) is not str and type(field_value) is str:
return model_value

return field_value

def get_serializer_info(self, serializer):
"""Override get_serializer_info so that we can add 'default' values to any fields whose Meta.model specifies a default value."""
self.serializer = serializer

serializer_info = super().get_serializer_info(serializer)

# Look for any dynamic fields which were not available when the serializer was instantiated
for field_name in serializer.Meta.fields:
if field_name in serializer_info:
# Already know about this one
continue
if hasattr(serializer, 'Meta'):
for field_name in serializer.Meta.fields:
if field_name in serializer_info:
# Already know about this one
continue

if hasattr(serializer, field_name):
field = getattr(serializer, field_name)
serializer_info[field_name] = self.get_field_info(field)
if hasattr(serializer, field_name):
field = getattr(serializer, field_name)
serializer_info[field_name] = self.get_field_info(field)

model_class = None

# Attributes to copy extra attributes from the model to the field (if they don't exist)
extra_attributes = ['help_text', 'max_length']
# Note that the attributes may be named differently on the underlying model!
extra_attributes = {
'help_text': 'help_text',
'max_length': 'max_length',
'label': 'verbose_name',
}

try:
model_class = serializer.Meta.model
Expand Down Expand Up @@ -165,10 +196,12 @@ def get_serializer_info(self, serializer):
elif name in model_default_values:
serializer_info[name]['default'] = model_default_values[name]

for attr in extra_attributes:
if attr not in serializer_info[name]:
if hasattr(field, attr):
serializer_info[name][attr] = getattr(field, attr)
for field_key, model_key in extra_attributes.items():
field_value = serializer_info[name].get(field_key, None)
model_value = getattr(field, model_key, None)

if value := self.override_value(name, field_value, model_value):
serializer_info[name][field_key] = value

# Iterate through relations
for name, relation in model_fields.relations.items():
Expand All @@ -186,13 +219,12 @@ def get_serializer_info(self, serializer):
relation.model_field.get_limit_choices_to()
)

for attr in extra_attributes:
if attr not in serializer_info[name] and hasattr(
relation.model_field, attr
):
serializer_info[name][attr] = getattr(
relation.model_field, attr
)
for field_key, model_key in extra_attributes.items():
field_value = serializer_info[name].get(field_key, None)
model_value = getattr(relation.model_field, model_key, None)

if value := self.override_value(name, field_value, model_value):
serializer_info[name][field_key] = value

if name in model_default_values:
serializer_info[name]['default'] = model_default_values[name]
Expand Down
Loading

0 comments on commit 000be47

Please sign in to comment.