mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-15 11:35:41 +00:00
Merge branch 'master' into matmair/issue6281
This commit is contained in:
2
src/backend/InvenTree/.gitignore
vendored
Normal file
2
src/backend/InvenTree/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Files generated during unit testing
|
||||
_testfolder/
|
@ -11,29 +11,32 @@ v304 - 2025-01-25 : https://github.com/inventree/InvenTree/pull/6293
|
||||
- Removes a considerable amount of old auth endpoints
|
||||
- Introduces allauth based REST API
|
||||
|
||||
v303 - 2025-01-20 - https://github.com/inventree/InvenTree/pull/8915
|
||||
v304 - 2025-01-22 : https://github.com/inventree/InvenTree/pull/8940
|
||||
- Adds "category" filter to build list API
|
||||
|
||||
v303 - 2025-01-20 : https://github.com/inventree/InvenTree/pull/8915
|
||||
- Adds "start_date" field to Build model and API endpoints
|
||||
- Adds additional API filtering and sorting options for Build list
|
||||
|
||||
v302 - 2025-01-18 - https://github.com/inventree/InvenTree/pull/8905
|
||||
v302 - 2025-01-18 : https://github.com/inventree/InvenTree/pull/8905
|
||||
- Fix schema definition on the /label/print endpoint
|
||||
|
||||
v301 - 2025-01-14 - https://github.com/inventree/InvenTree/pull/8894
|
||||
v301 - 2025-01-14 : https://github.com/inventree/InvenTree/pull/8894
|
||||
- Remove ui preferences from the API
|
||||
|
||||
v300 - 2025-01-13 - https://github.com/inventree/InvenTree/pull/8886
|
||||
v300 - 2025-01-13 : https://github.com/inventree/InvenTree/pull/8886
|
||||
- Allow null value for 'expiry_date' field introduced in #8867
|
||||
|
||||
v299 - 2025-01-10 - https://github.com/inventree/InvenTree/pull/8867
|
||||
v299 - 2025-01-10 : https://github.com/inventree/InvenTree/pull/8867
|
||||
- Adds 'expiry_date' field to the PurchaseOrderReceive API endpoint
|
||||
- Adds 'default_expiry` field to the PartBriefSerializer, affecting API endpoints which use it
|
||||
|
||||
v298 - 2025-01-07 - https://github.com/inventree/InvenTree/pull/8848
|
||||
v298 - 2025-01-07 : https://github.com/inventree/InvenTree/pull/8848
|
||||
- Adds 'created_by' field to PurchaseOrder API endpoints
|
||||
- Adds 'created_by' field to SalesOrder API endpoints
|
||||
- Adds 'created_by' field to ReturnOrder API endpoints
|
||||
|
||||
v297 - 2024-12-29 - https://github.com/inventree/InvenTree/pull/8438
|
||||
v297 - 2024-12-29 : https://github.com/inventree/InvenTree/pull/8438
|
||||
- Adjustments to the CustomUserState API endpoints and serializers
|
||||
|
||||
v296 - 2024-12-25 : https://github.com/inventree/InvenTree/pull/8732
|
||||
|
@ -13,7 +13,7 @@ from rest_framework.exceptions import ValidationError
|
||||
import build.admin
|
||||
import build.serializers
|
||||
import common.models
|
||||
import part.models
|
||||
import part.models as part_models
|
||||
from build.models import Build, BuildItem, BuildLine
|
||||
from build.status_codes import BuildStatus, BuildStatusGroups
|
||||
from generic.states.api import StatusView
|
||||
@ -77,7 +77,10 @@ class BuildFilter(rest_filters.FilterSet):
|
||||
return queryset
|
||||
|
||||
part = rest_filters.ModelChoiceFilter(
|
||||
queryset=part.models.Part.objects.all(), field_name='part', method='filter_part'
|
||||
queryset=part_models.Part.objects.all(),
|
||||
field_name='part',
|
||||
method='filter_part',
|
||||
label=_('Part'),
|
||||
)
|
||||
|
||||
def filter_part(self, queryset, name, part):
|
||||
@ -94,6 +97,17 @@ class BuildFilter(rest_filters.FilterSet):
|
||||
else:
|
||||
return queryset.filter(part=part)
|
||||
|
||||
category = rest_filters.ModelChoiceFilter(
|
||||
queryset=part_models.PartCategory.objects.all(),
|
||||
method='filter_category',
|
||||
label=_('Category'),
|
||||
)
|
||||
|
||||
def filter_category(self, queryset, name, category):
|
||||
"""Filter by part category (including sub-categories)."""
|
||||
categories = category.get_descendants(include_self=True)
|
||||
return queryset.filter(part__category__in=categories)
|
||||
|
||||
ancestor = rest_filters.ModelChoiceFilter(
|
||||
queryset=Build.objects.all(),
|
||||
label=_('Ancestor Build'),
|
||||
@ -417,7 +431,7 @@ class BuildLineFilter(rest_filters.FilterSet):
|
||||
)
|
||||
|
||||
part = rest_filters.ModelChoiceFilter(
|
||||
queryset=part.models.Part.objects.all(),
|
||||
queryset=part_models.Part.objects.all(),
|
||||
label=_('Part'),
|
||||
field_name='bom_item__sub_part',
|
||||
)
|
||||
@ -729,7 +743,7 @@ class BuildItemFilter(rest_filters.FilterSet):
|
||||
return queryset
|
||||
|
||||
part = rest_filters.ModelChoiceFilter(
|
||||
queryset=part.models.Part.objects.all(),
|
||||
queryset=part_models.Part.objects.all(),
|
||||
label=_('Part'),
|
||||
method='filter_part',
|
||||
field_name='stock_item__part',
|
||||
|
@ -10,7 +10,6 @@ import traceback
|
||||
from importlib.metadata import entry_points
|
||||
from importlib.util import module_from_spec
|
||||
|
||||
from django import template
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import AppRegistryNotReady
|
||||
from django.db.utils import IntegrityError
|
||||
@ -244,35 +243,3 @@ def get_plugins(pkg, baseclass, path=None):
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
|
||||
# region templates
|
||||
def render_template(plugin, template_file, context=None):
|
||||
"""Locate and render a template file, available in the global template context."""
|
||||
try:
|
||||
tmp = template.loader.get_template(template_file)
|
||||
except template.TemplateDoesNotExist:
|
||||
logger.exception(
|
||||
"Plugin %s could not locate template '%s'", plugin.slug, template_file
|
||||
)
|
||||
|
||||
return f"""
|
||||
<div class='alert alert-block alert-danger'>
|
||||
Template file <em>{template_file}</em> does not exist.
|
||||
</div>
|
||||
"""
|
||||
|
||||
# Render with the provided context
|
||||
html = tmp.render(context)
|
||||
|
||||
return html
|
||||
|
||||
|
||||
def render_text(text, context=None):
|
||||
"""Locate a raw string with provided context."""
|
||||
ctx = template.Context(context)
|
||||
|
||||
return template.Template(text).render(ctx)
|
||||
|
||||
|
||||
# endregion
|
||||
|
@ -142,7 +142,7 @@ class PluginConfig(InvenTree.models.MetadataMixin, models.Model):
|
||||
|
||||
def save(self, force_insert=False, force_update=False, *args, **kwargs):
|
||||
"""Extend save method to reload plugins if the 'active' status changes."""
|
||||
reload = kwargs.pop('no_reload', False) # check if no_reload flag is set
|
||||
no_reload = kwargs.pop('no_reload', False) # check if no_reload flag is set
|
||||
|
||||
super().save(force_insert, force_update, *args, **kwargs)
|
||||
|
||||
@ -150,10 +150,10 @@ class PluginConfig(InvenTree.models.MetadataMixin, models.Model):
|
||||
# Force active if builtin
|
||||
self.active = True
|
||||
|
||||
if not reload and self.active != self.__org_active:
|
||||
if not no_reload and self.active != self.__org_active:
|
||||
if settings.PLUGIN_TESTING:
|
||||
warnings.warn('A reload was triggered', stacklevel=2)
|
||||
registry.reload_plugins()
|
||||
warnings.warn('A plugin registry reload was triggered', stacklevel=2)
|
||||
registry.reload_plugins(full_reload=True, force_reload=True, collect=True)
|
||||
|
||||
@admin.display(boolean=True, description=_('Installed'))
|
||||
def is_installed(self) -> bool:
|
||||
|
@ -453,6 +453,8 @@ class PluginsRegistry:
|
||||
|
||||
Args:
|
||||
plugin: Plugin module
|
||||
configs: Plugin configuration dictionary
|
||||
force_reload (bool, optional): Force reload of plugin. Defaults to False.
|
||||
"""
|
||||
from InvenTree import version
|
||||
|
||||
@ -485,6 +487,7 @@ class PluginsRegistry:
|
||||
|
||||
# Check if this is a 'builtin' plugin
|
||||
builtin = plugin.check_is_builtin()
|
||||
sample = plugin.check_is_sample()
|
||||
|
||||
package_name = None
|
||||
|
||||
@ -510,11 +513,37 @@ class PluginsRegistry:
|
||||
# Initialize package - we can be sure that an admin has activated the plugin
|
||||
logger.debug('Loading plugin `%s`', plg_name)
|
||||
|
||||
# If this is a third-party plugin, reload the source module
|
||||
# This is required to ensure that separate processes are using the same code
|
||||
if not builtin and not sample:
|
||||
plugin_name = plugin.__name__
|
||||
module_name = plugin.__module__
|
||||
|
||||
if plugin_module := sys.modules.get(module_name):
|
||||
logger.debug('Reloading plugin `%s`', plg_name)
|
||||
# Reload the module
|
||||
try:
|
||||
importlib.reload(plugin_module)
|
||||
plugin = getattr(plugin_module, plugin_name)
|
||||
except ModuleNotFoundError:
|
||||
# No module found - try to import it directly
|
||||
try:
|
||||
raw_module = _load_source(
|
||||
module_name, plugin_module.__file__
|
||||
)
|
||||
plugin = getattr(raw_module, plugin_name)
|
||||
except Exception:
|
||||
pass
|
||||
except Exception:
|
||||
logger.exception('Failed to reload plugin `%s`', plg_name)
|
||||
|
||||
try:
|
||||
t_start = time.time()
|
||||
plg_i: InvenTreePlugin = plugin()
|
||||
dt = time.time() - t_start
|
||||
logger.debug('Loaded plugin `%s` in %.3fs', plg_name, dt)
|
||||
except ModuleNotFoundError as e:
|
||||
raise e
|
||||
except Exception as error:
|
||||
handle_error(
|
||||
error, log_name='init'
|
||||
@ -745,7 +774,7 @@ class PluginsRegistry:
|
||||
|
||||
if old_hash != self.registry_hash:
|
||||
try:
|
||||
logger.debug(
|
||||
logger.info(
|
||||
'Updating plugin registry hash: %s', str(self.registry_hash)
|
||||
)
|
||||
set_global_setting(
|
||||
@ -839,11 +868,16 @@ def _load_source(modname, filename):
|
||||
|
||||
See https://docs.python.org/3/whatsnew/3.12.html#imp
|
||||
"""
|
||||
loader = importlib.machinery.SourceFileLoader(modname, filename)
|
||||
spec = importlib.util.spec_from_file_location(modname, filename, loader=loader)
|
||||
if modname in sys.modules:
|
||||
del sys.modules[modname]
|
||||
|
||||
# loader = importlib.machinery.SourceFileLoader(modname, filename)
|
||||
spec = importlib.util.spec_from_file_location(modname, filename) # , loader=loader)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
# The module is always executed and not cached in sys.modules.
|
||||
# Uncomment the following line to cache the module.
|
||||
# sys.modules[module.__name__] = module
|
||||
loader.exec_module(module)
|
||||
|
||||
sys.modules[module.__name__] = module
|
||||
|
||||
if spec.loader:
|
||||
spec.loader.exec_module(module)
|
||||
|
||||
return module
|
||||
|
@ -205,7 +205,7 @@ class PluginDetailAPITest(PluginMixin, InvenTreeAPITestCase):
|
||||
|
||||
plg_inactive.active = True
|
||||
plg_inactive.save()
|
||||
self.assertEqual(cm.warning.args[0], 'A reload was triggered')
|
||||
self.assertEqual(cm.warning.args[0], 'A plugin registry reload was triggered')
|
||||
|
||||
def test_check_plugin(self):
|
||||
"""Test check_plugin function."""
|
||||
|
@ -1,26 +0,0 @@
|
||||
"""Unit tests for helpers.py."""
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from .helpers import render_template
|
||||
|
||||
|
||||
class HelperTests(TestCase):
|
||||
"""Tests for helpers."""
|
||||
|
||||
def test_render_template(self):
|
||||
"""Check if render_template helper works."""
|
||||
|
||||
class ErrorSource:
|
||||
slug = 'sampleplg'
|
||||
|
||||
# working sample
|
||||
response = render_template(ErrorSource(), 'sample/sample.html', {'abc': 123})
|
||||
self.assertEqual(response, '<h1>123</h1>\n')
|
||||
|
||||
# Wrong sample
|
||||
response = render_template(
|
||||
ErrorSource(), 'sample/wrongsample.html', {'abc': 123}
|
||||
)
|
||||
self.assertIn('lert alert-block alert-danger', response)
|
||||
self.assertIn('Template file <em>sample/wrongsample.html</em>', response)
|
@ -4,9 +4,11 @@ import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import textwrap
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from unittest import mock
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.test import TestCase, override_settings
|
||||
|
||||
@ -18,6 +20,9 @@ from plugin.samples.integration.another_sample import (
|
||||
)
|
||||
from plugin.samples.integration.sample import SampleIntegrationPlugin
|
||||
|
||||
# Directory for testing plugins during CI
|
||||
PLUGIN_TEST_DIR = '_testfolder/test_plugins'
|
||||
|
||||
|
||||
class PluginTagTests(TestCase):
|
||||
"""Tests for the plugin extras."""
|
||||
@ -287,3 +292,111 @@ class RegistryTests(TestCase):
|
||||
self.assertEqual(
|
||||
registry.errors.get('init')[0]['broken_sample'], "'This is a dummy error'"
|
||||
)
|
||||
|
||||
@override_settings(PLUGIN_TESTING=True, PLUGIN_TESTING_SETUP=True)
|
||||
@patch.dict(os.environ, {'INVENTREE_PLUGIN_TEST_DIR': PLUGIN_TEST_DIR})
|
||||
def test_registry_reload(self):
|
||||
"""Test that the registry correctly reloads plugin modules.
|
||||
|
||||
- Create a simple plugin which we can change the version
|
||||
- Ensure that the "hash" of the plugin registry changes
|
||||
"""
|
||||
dummy_file = os.path.join(PLUGIN_TEST_DIR, 'dummy_ci_plugin.py')
|
||||
|
||||
# Ensure the plugin dir exists
|
||||
os.makedirs(PLUGIN_TEST_DIR, exist_ok=True)
|
||||
|
||||
# Create an __init__.py file
|
||||
init_file = os.path.join(PLUGIN_TEST_DIR, '__init__.py')
|
||||
if not os.path.exists(init_file):
|
||||
with open(os.path.join(init_file), 'w', encoding='utf-8') as f:
|
||||
f.write('')
|
||||
|
||||
def plugin_content(version):
|
||||
"""Return the content of the plugin file."""
|
||||
content = f"""
|
||||
from plugin import InvenTreePlugin
|
||||
|
||||
PLG_VERSION = "{version}"
|
||||
|
||||
print(">>> LOADING DUMMY PLUGIN v" + PLG_VERSION + " <<<")
|
||||
|
||||
class DummyCIPlugin(InvenTreePlugin):
|
||||
|
||||
NAME = "DummyCIPlugin"
|
||||
SLUG = "dummyci"
|
||||
TITLE = "Dummy plugin for CI testing"
|
||||
|
||||
VERSION = PLG_VERSION
|
||||
|
||||
"""
|
||||
|
||||
return textwrap.dedent(content)
|
||||
|
||||
def create_plugin_file(
|
||||
version: str, enabled: bool = True, reload: bool = True
|
||||
) -> str:
|
||||
"""Create a plugin file with the given version.
|
||||
|
||||
Arguments:
|
||||
version: The version string to use for the plugin file
|
||||
enabled: Whether the plugin should be enabled or not
|
||||
|
||||
Returns:
|
||||
str: The plugin registry hash
|
||||
"""
|
||||
import time
|
||||
|
||||
content = plugin_content(version)
|
||||
|
||||
with open(dummy_file, 'w', encoding='utf-8') as f:
|
||||
f.write(content)
|
||||
|
||||
# Wait for the file to be written
|
||||
time.sleep(2)
|
||||
|
||||
if reload:
|
||||
# Ensure the plugin is activated
|
||||
registry.set_plugin_state('dummyci', enabled)
|
||||
registry.reload_plugins(
|
||||
full_reload=True, collect=True, force_reload=True
|
||||
)
|
||||
|
||||
registry.update_plugin_hash()
|
||||
|
||||
return registry.registry_hash
|
||||
|
||||
# Initial hash, with plugin disabled
|
||||
hash_disabled = create_plugin_file('0.0.1', enabled=False, reload=False)
|
||||
|
||||
# Perform initial registry reload
|
||||
registry.reload_plugins(full_reload=True, collect=True, force_reload=True)
|
||||
|
||||
# Start plugin in known state
|
||||
registry.set_plugin_state('dummyci', False)
|
||||
|
||||
hash_disabled = create_plugin_file('0.0.1', enabled=False)
|
||||
|
||||
# Enable the plugin
|
||||
hash_enabled = create_plugin_file('0.1.0', enabled=True)
|
||||
|
||||
# Hash must be different!
|
||||
self.assertNotEqual(hash_disabled, hash_enabled)
|
||||
|
||||
plugin_hash = hash_enabled
|
||||
|
||||
for v in ['0.1.1', '7.1.2', '1.2.1', '4.0.1']:
|
||||
h = create_plugin_file(v, enabled=True)
|
||||
self.assertNotEqual(plugin_hash, h)
|
||||
plugin_hash = h
|
||||
|
||||
# Revert back to original 'version'
|
||||
h = create_plugin_file('0.1.0', enabled=True)
|
||||
self.assertEqual(hash_enabled, h)
|
||||
|
||||
# Disable the plugin
|
||||
h = create_plugin_file('0.0.1', enabled=False)
|
||||
self.assertEqual(hash_disabled, h)
|
||||
|
||||
# Finally, ensure that the plugin file is removed after testing
|
||||
os.remove(dummy_file)
|
||||
|
@ -91,7 +91,7 @@
|
||||
"nyc": "^17.1.0",
|
||||
"rollup-plugin-license": "^3.5.3",
|
||||
"typescript": "^5.7.3",
|
||||
"vite": "^6.0.7",
|
||||
"vite": "^6.0.9",
|
||||
"vite-plugin-babel-macros": "^1.0.6",
|
||||
"vite-plugin-istanbul": "^6.0.2"
|
||||
}
|
||||
|
@ -179,10 +179,17 @@ function FilterAddGroup({
|
||||
|
||||
// Determine the "type" of filter (default = boolean)
|
||||
const filterType: TableFilterType = useMemo(() => {
|
||||
return (
|
||||
availableFilters?.find((flt) => flt.name === selectedFilter)?.type ??
|
||||
'boolean'
|
||||
);
|
||||
const filter = availableFilters?.find((flt) => flt.name === selectedFilter);
|
||||
|
||||
if (filter?.type) {
|
||||
return filter.type;
|
||||
} else if (filter?.choices) {
|
||||
// If choices are provided, it is a choice filter
|
||||
return 'choice';
|
||||
} else {
|
||||
// Default fallback
|
||||
return 'boolean';
|
||||
}
|
||||
}, [selectedFilter]);
|
||||
|
||||
const setSelectedValue = useCallback(
|
||||
|
@ -8,7 +8,9 @@ import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||
import { ModelType } from '../../enums/ModelType';
|
||||
import { UserRoles } from '../../enums/Roles';
|
||||
import { useBuildOrderFields } from '../../forms/BuildForms';
|
||||
import { shortenString } from '../../functions/tables';
|
||||
import {
|
||||
useFilters,
|
||||
useOwnerFilters,
|
||||
useProjectCodeFilters,
|
||||
useUserFilters
|
||||
@ -131,6 +133,17 @@ export function BuildOrderTable({
|
||||
const ownerFilters = useOwnerFilters();
|
||||
const userFilters = useUserFilters();
|
||||
|
||||
const categoryFilters = useFilters({
|
||||
url: apiUrl(ApiEndpoints.category_list),
|
||||
transform: (item) => ({
|
||||
value: item.pk,
|
||||
label: shortenString({
|
||||
str: item.pathstring,
|
||||
len: 50
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
const tableFilters: TableFilter[] = useMemo(() => {
|
||||
const filters: TableFilter[] = [
|
||||
OutstandingFilter(),
|
||||
@ -177,7 +190,13 @@ export function BuildOrderTable({
|
||||
description: t`Filter by user who issued this order`,
|
||||
choices: userFilters.choices
|
||||
},
|
||||
ResponsibleFilter({ choices: ownerFilters.choices })
|
||||
ResponsibleFilter({ choices: ownerFilters.choices }),
|
||||
{
|
||||
name: 'category',
|
||||
label: t`Category`,
|
||||
description: t`Filter by part category`,
|
||||
choices: categoryFilters.choices
|
||||
}
|
||||
];
|
||||
|
||||
// If we are filtering on a specific part, we can include the "include variants" filter
|
||||
@ -193,6 +212,7 @@ export function BuildOrderTable({
|
||||
return filters;
|
||||
}, [
|
||||
partId,
|
||||
categoryFilters.choices,
|
||||
projectCodeFilters.choices,
|
||||
ownerFilters.choices,
|
||||
userFilters.choices
|
||||
|
@ -1724,41 +1724,21 @@
|
||||
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.19.2.tgz#0c896535473291cb41f152c180bedd5680a3b273"
|
||||
integrity sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA==
|
||||
|
||||
"@rollup/rollup-android-arm-eabi@4.22.5":
|
||||
version "4.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.5.tgz#e0f5350845090ca09690fe4a472717f3b8aae225"
|
||||
integrity sha512-SU5cvamg0Eyu/F+kLeMXS7GoahL+OoizlclVFX3l5Ql6yNlywJJ0OuqTzUx0v+aHhPHEB/56CT06GQrRrGNYww==
|
||||
|
||||
"@rollup/rollup-android-arm-eabi@4.30.1":
|
||||
version "4.30.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.30.1.tgz#14c737dc19603a096568044eadaa60395eefb809"
|
||||
integrity sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q==
|
||||
|
||||
"@rollup/rollup-android-arm64@4.22.5":
|
||||
version "4.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.5.tgz#08270faef6747e2716d3e978a8bbf479f75fb19a"
|
||||
integrity sha512-S4pit5BP6E5R5C8S6tgU/drvgjtYW76FBuG6+ibG3tMvlD1h9LHVF9KmlmaUBQ8Obou7hEyS+0w+IR/VtxwNMQ==
|
||||
|
||||
"@rollup/rollup-android-arm64@4.30.1":
|
||||
version "4.30.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.30.1.tgz#9d81ea54fc5650eb4ebbc0a7d84cee331bfa30ad"
|
||||
integrity sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w==
|
||||
|
||||
"@rollup/rollup-darwin-arm64@4.22.5":
|
||||
version "4.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.5.tgz#691671133b350661328d42c8dbdedd56dfb97dfd"
|
||||
integrity sha512-250ZGg4ipTL0TGvLlfACkIxS9+KLtIbn7BCZjsZj88zSg2Lvu3Xdw6dhAhfe/FjjXPVNCtcSp+WZjVsD3a/Zlw==
|
||||
|
||||
"@rollup/rollup-darwin-arm64@4.30.1":
|
||||
version "4.30.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.30.1.tgz#29448cb1370cf678b50743d2e392be18470abc23"
|
||||
integrity sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q==
|
||||
|
||||
"@rollup/rollup-darwin-x64@4.22.5":
|
||||
version "4.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.5.tgz#b2ec52a1615f24b1cd40bc8906ae31af81e8a342"
|
||||
integrity sha512-D8brJEFg5D+QxFcW6jYANu+Rr9SlKtTenmsX5hOSzNYVrK5oLAEMTUgKWYJP+wdKyCdeSwnapLsn+OVRFycuQg==
|
||||
|
||||
"@rollup/rollup-darwin-x64@4.30.1":
|
||||
version "4.30.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.30.1.tgz#0ca99741c3ed096700557a43bb03359450c7857d"
|
||||
@ -1774,41 +1754,21 @@
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.30.1.tgz#dfba762a023063dc901610722995286df4a48360"
|
||||
integrity sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw==
|
||||
|
||||
"@rollup/rollup-linux-arm-gnueabihf@4.22.5":
|
||||
version "4.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.5.tgz#217f01f304808920680bd269002df38e25d9205f"
|
||||
integrity sha512-PNqXYmdNFyWNg0ma5LdY8wP+eQfdvyaBAojAXgO7/gs0Q/6TQJVXAXe8gwW9URjbS0YAammur0fynYGiWsKlXw==
|
||||
|
||||
"@rollup/rollup-linux-arm-gnueabihf@4.30.1":
|
||||
version "4.30.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.30.1.tgz#b9da54171726266c5ef4237f462a85b3c3cf6ac9"
|
||||
integrity sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==
|
||||
|
||||
"@rollup/rollup-linux-arm-musleabihf@4.22.5":
|
||||
version "4.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.5.tgz#93ac1c5a1e389f4482a2edaeec41fcffee54a930"
|
||||
integrity sha512-kSSCZOKz3HqlrEuwKd9TYv7vxPYD77vHSUvM2y0YaTGnFc8AdI5TTQRrM1yIp3tXCKrSL9A7JLoILjtad5t8pQ==
|
||||
|
||||
"@rollup/rollup-linux-arm-musleabihf@4.30.1":
|
||||
version "4.30.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.30.1.tgz#b9db69b3f85f5529eb992936d8f411ee6d04297b"
|
||||
integrity sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==
|
||||
|
||||
"@rollup/rollup-linux-arm64-gnu@4.22.5":
|
||||
version "4.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.5.tgz#a7f146787d6041fecc4ecdf1aa72234661ca94a4"
|
||||
integrity sha512-oTXQeJHRbOnwRnRffb6bmqmUugz0glXaPyspp4gbQOPVApdpRrY/j7KP3lr7M8kTfQTyrBUzFjj5EuHAhqH4/w==
|
||||
|
||||
"@rollup/rollup-linux-arm64-gnu@4.30.1":
|
||||
version "4.30.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.30.1.tgz#2550cf9bb4d47d917fd1ab4af756d7bbc3ee1528"
|
||||
integrity sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==
|
||||
|
||||
"@rollup/rollup-linux-arm64-musl@4.22.5":
|
||||
version "4.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.5.tgz#6a37236189648e678bd564d6e8ca798f42cf42c5"
|
||||
integrity sha512-qnOTIIs6tIGFKCHdhYitgC2XQ2X25InIbZFor5wh+mALH84qnFHvc+vmWUpyX97B0hNvwNUL4B+MB8vJvH65Fw==
|
||||
|
||||
"@rollup/rollup-linux-arm64-musl@4.30.1":
|
||||
version "4.30.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.30.1.tgz#9d06b26d286c7dded6336961a2f83e48330e0c80"
|
||||
@ -1819,81 +1779,41 @@
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.30.1.tgz#e957bb8fee0c8021329a34ca8dfa825826ee0e2e"
|
||||
integrity sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==
|
||||
|
||||
"@rollup/rollup-linux-powerpc64le-gnu@4.22.5":
|
||||
version "4.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.5.tgz#5661420dc463bec31ecb2d17d113de858cfcfe2d"
|
||||
integrity sha512-TMYu+DUdNlgBXING13rHSfUc3Ky5nLPbWs4bFnT+R6Vu3OvXkTkixvvBKk8uO4MT5Ab6lC3U7x8S8El2q5o56w==
|
||||
|
||||
"@rollup/rollup-linux-powerpc64le-gnu@4.30.1":
|
||||
version "4.30.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.30.1.tgz#e8585075ddfb389222c5aada39ea62d6d2511ccc"
|
||||
integrity sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==
|
||||
|
||||
"@rollup/rollup-linux-riscv64-gnu@4.22.5":
|
||||
version "4.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.5.tgz#cb00342b7432bdef723aa606281de2f522d6dcf7"
|
||||
integrity sha512-PTQq1Kz22ZRvuhr3uURH+U/Q/a0pbxJoICGSprNLAoBEkyD3Sh9qP5I0Asn0y0wejXQBbsVMRZRxlbGFD9OK4A==
|
||||
|
||||
"@rollup/rollup-linux-riscv64-gnu@4.30.1":
|
||||
version "4.30.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.30.1.tgz#7d0d40cee7946ccaa5a4e19a35c6925444696a9e"
|
||||
integrity sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==
|
||||
|
||||
"@rollup/rollup-linux-s390x-gnu@4.22.5":
|
||||
version "4.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.5.tgz#0708889674dccecccd28e2befccf791e0767fcb7"
|
||||
integrity sha512-bR5nCojtpuMss6TDEmf/jnBnzlo+6n1UhgwqUvRoe4VIotC7FG1IKkyJbwsT7JDsF2jxR+NTnuOwiGv0hLyDoQ==
|
||||
|
||||
"@rollup/rollup-linux-s390x-gnu@4.30.1":
|
||||
version "4.30.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.30.1.tgz#c2dcd8a4b08b2f2778eceb7a5a5dfde6240ebdea"
|
||||
integrity sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==
|
||||
|
||||
"@rollup/rollup-linux-x64-gnu@4.22.5":
|
||||
version "4.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.5.tgz#a135b040b21582e91cfed2267ccfc7d589e1dbc6"
|
||||
integrity sha512-N0jPPhHjGShcB9/XXZQWuWBKZQnC1F36Ce3sDqWpujsGjDz/CQtOL9LgTrJ+rJC8MJeesMWrMWVLKKNR/tMOCA==
|
||||
|
||||
"@rollup/rollup-linux-x64-gnu@4.30.1":
|
||||
version "4.30.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.30.1.tgz#183637d91456877cb83d0a0315eb4788573aa588"
|
||||
integrity sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==
|
||||
|
||||
"@rollup/rollup-linux-x64-musl@4.22.5":
|
||||
version "4.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.5.tgz#88395a81a3ab7ee3dc8dc31a73ff62ed3185f34d"
|
||||
integrity sha512-uBa2e28ohzNNwjr6Uxm4XyaA1M/8aTgfF2T7UIlElLaeXkgpmIJ2EitVNQxjO9xLLLy60YqAgKn/AqSpCUkE9g==
|
||||
|
||||
"@rollup/rollup-linux-x64-musl@4.30.1":
|
||||
version "4.30.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.30.1.tgz#036a4c860662519f1f9453807547fd2a11d5bb01"
|
||||
integrity sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==
|
||||
|
||||
"@rollup/rollup-win32-arm64-msvc@4.22.5":
|
||||
version "4.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.5.tgz#12ee49233b1125f2c1da38392f63b1dbb0c31bba"
|
||||
integrity sha512-RXT8S1HP8AFN/Kr3tg4fuYrNxZ/pZf1HemC5Tsddc6HzgGnJm0+Lh5rAHJkDuW3StI0ynNXukidROMXYl6ew8w==
|
||||
|
||||
"@rollup/rollup-win32-arm64-msvc@4.30.1":
|
||||
version "4.30.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.30.1.tgz#51cad812456e616bfe4db5238fb9c7497e042a52"
|
||||
integrity sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==
|
||||
|
||||
"@rollup/rollup-win32-ia32-msvc@4.22.5":
|
||||
version "4.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.5.tgz#0f987b134c6b3123c22842b33ba0c2b6fb78cc3b"
|
||||
integrity sha512-ElTYOh50InL8kzyUD6XsnPit7jYCKrphmddKAe1/Ytt74apOxDq5YEcbsiKs0fR3vff3jEneMM+3I7jbqaMyBg==
|
||||
|
||||
"@rollup/rollup-win32-ia32-msvc@4.30.1":
|
||||
version "4.30.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.30.1.tgz#661c8b3e4cd60f51deaa39d153aac4566e748e5e"
|
||||
integrity sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw==
|
||||
|
||||
"@rollup/rollup-win32-x64-msvc@4.22.5":
|
||||
version "4.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.5.tgz#f2feb149235a5dc1deb5439758f8871255e5a161"
|
||||
integrity sha512-+lvL/4mQxSV8MukpkKyyvfwhH266COcWlXE/1qxwN08ajovta3459zrjLghYMgDerlzNwLAcFpvU+WWE5y6nAQ==
|
||||
|
||||
"@rollup/rollup-win32-x64-msvc@4.30.1":
|
||||
version "4.30.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.30.1.tgz#73bf1885ff052b82fbb0f82f8671f73c36e9137c"
|
||||
@ -4204,16 +4124,7 @@ postcss@8.4.38:
|
||||
picocolors "^1.0.0"
|
||||
source-map-js "^1.2.0"
|
||||
|
||||
postcss@^8.4.43:
|
||||
version "8.4.45"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.45.tgz#538d13d89a16ef71edbf75d895284ae06b79e603"
|
||||
integrity sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==
|
||||
dependencies:
|
||||
nanoid "^3.3.7"
|
||||
picocolors "^1.0.1"
|
||||
source-map-js "^1.2.0"
|
||||
|
||||
postcss@^8.4.49:
|
||||
postcss@^8.4.43, postcss@^8.4.49:
|
||||
version "8.5.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.1.tgz#e2272a1f8a807fafa413218245630b5db10a3214"
|
||||
integrity sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==
|
||||
@ -4579,32 +4490,7 @@ rollup-plugin-license@^3.5.3:
|
||||
spdx-expression-validate "~2.0.0"
|
||||
spdx-satisfies "~5.0.1"
|
||||
|
||||
rollup@^4.20.0:
|
||||
version "4.22.5"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.22.5.tgz#d5108cc470249417e50492456253884d19f5d40f"
|
||||
integrity sha512-WoinX7GeQOFMGznEcWA1WrTQCd/tpEbMkc3nuMs9BT0CPjMdSjPMTVClwWd4pgSQwJdP65SK9mTCNvItlr5o7w==
|
||||
dependencies:
|
||||
"@types/estree" "1.0.6"
|
||||
optionalDependencies:
|
||||
"@rollup/rollup-android-arm-eabi" "4.22.5"
|
||||
"@rollup/rollup-android-arm64" "4.22.5"
|
||||
"@rollup/rollup-darwin-arm64" "4.22.5"
|
||||
"@rollup/rollup-darwin-x64" "4.22.5"
|
||||
"@rollup/rollup-linux-arm-gnueabihf" "4.22.5"
|
||||
"@rollup/rollup-linux-arm-musleabihf" "4.22.5"
|
||||
"@rollup/rollup-linux-arm64-gnu" "4.22.5"
|
||||
"@rollup/rollup-linux-arm64-musl" "4.22.5"
|
||||
"@rollup/rollup-linux-powerpc64le-gnu" "4.22.5"
|
||||
"@rollup/rollup-linux-riscv64-gnu" "4.22.5"
|
||||
"@rollup/rollup-linux-s390x-gnu" "4.22.5"
|
||||
"@rollup/rollup-linux-x64-gnu" "4.22.5"
|
||||
"@rollup/rollup-linux-x64-musl" "4.22.5"
|
||||
"@rollup/rollup-win32-arm64-msvc" "4.22.5"
|
||||
"@rollup/rollup-win32-ia32-msvc" "4.22.5"
|
||||
"@rollup/rollup-win32-x64-msvc" "4.22.5"
|
||||
fsevents "~2.3.2"
|
||||
|
||||
rollup@^4.23.0:
|
||||
rollup@^4.20.0, rollup@^4.23.0:
|
||||
version "4.30.1"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.30.1.tgz#d5c3d066055259366cdc3eb6f1d051c5d6afaf74"
|
||||
integrity sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==
|
||||
@ -5147,10 +5033,10 @@ vite@^5.0.0, vite@^5.0.11:
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.3"
|
||||
|
||||
vite@^6.0.7:
|
||||
version "6.0.7"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-6.0.7.tgz#f0f8c120733b04af52b4a1e3e7cb54eb851a799b"
|
||||
integrity sha512-RDt8r/7qx9940f8FcOIAH9PTViRrghKaK2K1jY3RaAURrEUbm9Du1mJ72G+jlhtG3WwodnfzY8ORQZbBavZEAQ==
|
||||
vite@^6.0.9:
|
||||
version "6.0.9"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-6.0.9.tgz#0a830b767ef7aa762360b56bdef955c1395dc1ee"
|
||||
integrity sha512-MSgUxHcaXLtnBPktkbUSoQUANApKYuxZ6DrbVENlIorbhL2dZydTLaZ01tjUoE3szeFzlFk9ANOKk0xurh4MKA==
|
||||
dependencies:
|
||||
esbuild "^0.24.2"
|
||||
postcss "^8.4.49"
|
||||
|
21
tasks.py
21
tasks.py
@ -910,13 +910,28 @@ def gunicorn(c, address='0.0.0.0:8000', workers=None):
|
||||
run(c, cmd, pty=True)
|
||||
|
||||
|
||||
@task(pre=[wait], help={'address': 'Server address:port (default=127.0.0.1:8000)'})
|
||||
def server(c, address='127.0.0.1:8000'):
|
||||
@task(
|
||||
pre=[wait],
|
||||
help={
|
||||
'address': 'Server address:port (default=127.0.0.1:8000)',
|
||||
'no_reload': 'Do not automatically reload the server in response to code changes',
|
||||
'no_threading': 'Disable multi-threading for the development server',
|
||||
},
|
||||
)
|
||||
def server(c, address='127.0.0.1:8000', no_reload=False, no_threading=False):
|
||||
"""Launch a (development) server using Django's in-built webserver.
|
||||
|
||||
Note: This is *not* sufficient for a production installation.
|
||||
"""
|
||||
manage(c, f'runserver {address}', pty=True)
|
||||
cmd = f'runserver {address}'
|
||||
|
||||
if no_reload:
|
||||
cmd += ' --noreload'
|
||||
|
||||
if no_threading:
|
||||
cmd += ' --nothreading'
|
||||
|
||||
manage(c, cmd, pty=True)
|
||||
|
||||
|
||||
@task(pre=[wait])
|
||||
|
Reference in New Issue
Block a user