diff --git a/netbox/dcim/models/cables.py b/netbox/dcim/models/cables.py index f8a61a794..64f0b8560 100644 --- a/netbox/dcim/models/cables.py +++ b/netbox/dcim/models/cables.py @@ -15,9 +15,9 @@ from dcim.constants import * from dcim.fields import PathField from dcim.utils import decompile_path_node, object_to_path_node from netbox.models import ChangeLoggedModel, PrimaryModel +from utilities.conversion import to_meters from utilities.fields import ColorField from utilities.querysets import RestrictedQuerySet -from utilities.utils import to_meters from wireless.models import WirelessLink from .device_components import FrontPort, RearPort, PathEndpoint diff --git a/netbox/dcim/models/mixins.py b/netbox/dcim/models/mixins.py index 9be8dc0a3..d4a05699c 100644 --- a/netbox/dcim/models/mixins.py +++ b/netbox/dcim/models/mixins.py @@ -2,7 +2,7 @@ from django.core.exceptions import ValidationError from django.db import models from django.utils.translation import gettext_lazy as _ from dcim.choices import * -from utilities.utils import to_grams +from utilities.conversion import to_grams __all__ = ( 'RenderConfigMixin', diff --git a/netbox/dcim/models/racks.py b/netbox/dcim/models/racks.py index 1e936aa58..79d5e892c 100644 --- a/netbox/dcim/models/racks.py +++ b/netbox/dcim/models/racks.py @@ -17,8 +17,9 @@ from dcim.svg import RackElevationSVG from netbox.choices import ColorChoices from netbox.models import OrganizationalModel, PrimaryModel from netbox.models.features import ContactsMixin, ImageAttachmentsMixin +from utilities.conversion import to_grams from utilities.fields import ColorField, NaturalOrderingField -from utilities.utils import array_to_string, drange, to_grams +from utilities.utils import array_to_string, drange from .device_components import PowerPort from .devices import Device, Module from .mixins import WeightMixin diff --git a/netbox/utilities/conversion.py b/netbox/utilities/conversion.py new file mode 100644 index 000000000..cd75c3c17 --- /dev/null +++ b/netbox/utilities/conversion.py @@ -0,0 +1,66 @@ +from decimal import Decimal + +from django.utils.translation import gettext as _ + +from dcim.choices import CableLengthUnitChoices, WeightUnitChoices + +__all__ = ( + 'to_grams', + 'to_meters', +) + + +def to_grams(weight, unit): + """ + Convert the given weight to kilograms. + """ + try: + if weight < 0: + raise ValueError(_("Weight must be a positive number")) + except TypeError: + raise TypeError(_("Invalid value '{weight}' for weight (must be a number)").format(weight=weight)) + + if unit == WeightUnitChoices.UNIT_KILOGRAM: + return weight * 1000 + if unit == WeightUnitChoices.UNIT_GRAM: + return weight + if unit == WeightUnitChoices.UNIT_POUND: + return weight * Decimal(453.592) + if unit == WeightUnitChoices.UNIT_OUNCE: + return weight * Decimal(28.3495) + raise ValueError( + _("Unknown unit {unit}. Must be one of the following: {valid_units}").format( + unit=unit, + valid_units=', '.join(WeightUnitChoices.values()) + ) + ) + + +def to_meters(length, unit): + """ + Convert the given length to meters. + """ + try: + if length < 0: + raise ValueError(_("Length must be a positive number")) + except TypeError: + raise TypeError(_("Invalid value '{length}' for length (must be a number)").format(length=length)) + + if unit == CableLengthUnitChoices.UNIT_KILOMETER: + return length * 1000 + if unit == CableLengthUnitChoices.UNIT_METER: + return length + if unit == CableLengthUnitChoices.UNIT_CENTIMETER: + return length / 100 + if unit == CableLengthUnitChoices.UNIT_MILE: + return length * Decimal(1609.344) + if unit == CableLengthUnitChoices.UNIT_FOOT: + return length * Decimal(0.3048) + if unit == CableLengthUnitChoices.UNIT_INCH: + return length * Decimal(0.0254) + raise ValueError( + _("Unknown unit {unit}. Must be one of the following: {valid_units}").format( + unit=unit, + valid_units=', '.join(CableLengthUnitChoices.values()) + ) + ) diff --git a/netbox/utilities/utils.py b/netbox/utilities/utils.py index 8f0d357b2..94e377dd7 100644 --- a/netbox/utilities/utils.py +++ b/netbox/utilities/utils.py @@ -1,7 +1,6 @@ import datetime import decimal import json -from decimal import Decimal from itertools import count, groupby from urllib.parse import urlencode @@ -14,11 +13,9 @@ from django.http import QueryDict from django.utils import timezone from django.utils.datastructures import MultiValueDict from django.utils.timezone import localtime -from django.utils.translation import gettext as _ from jinja2.sandbox import SandboxedEnvironment from mptt.models import MPTTModel -from dcim.choices import CableLengthUnitChoices, WeightUnitChoices from extras.utils import is_taggable from netbox.config import get_config from .constants import HTML_ALLOWED_ATTRIBUTES, HTML_ALLOWED_TAGS @@ -253,68 +250,6 @@ def drange(start, end, step=decimal.Decimal(1)): start += step -def to_meters(length, unit): - """ - Convert the given length to meters. - """ - try: - if length < 0: - raise ValueError(_("Length must be a positive number")) - except TypeError: - raise TypeError(_("Invalid value '{length}' for length (must be a number)").format(length=length)) - - valid_units = CableLengthUnitChoices.values() - if unit not in valid_units: - raise ValueError( - _("Unknown unit {unit}. Must be one of the following: {valid_units}").format( - unit=unit, valid_units=', '.join(valid_units) - ) - ) - - if unit == CableLengthUnitChoices.UNIT_KILOMETER: - return length * 1000 - if unit == CableLengthUnitChoices.UNIT_METER: - return length - if unit == CableLengthUnitChoices.UNIT_CENTIMETER: - return length / 100 - if unit == CableLengthUnitChoices.UNIT_MILE: - return length * Decimal(1609.344) - if unit == CableLengthUnitChoices.UNIT_FOOT: - return length * Decimal(0.3048) - if unit == CableLengthUnitChoices.UNIT_INCH: - return length * Decimal(0.0254) - raise ValueError(_("Unknown unit {unit}. Must be 'km', 'm', 'cm', 'mi', 'ft', or 'in'.").format(unit=unit)) - - -def to_grams(weight, unit): - """ - Convert the given weight to kilograms. - """ - try: - if weight < 0: - raise ValueError(_("Weight must be a positive number")) - except TypeError: - raise TypeError(_("Invalid value '{weight}' for weight (must be a number)").format(weight=weight)) - - valid_units = WeightUnitChoices.values() - if unit not in valid_units: - raise ValueError( - _("Unknown unit {unit}. Must be one of the following: {valid_units}").format( - unit=unit, valid_units=', '.join(valid_units) - ) - ) - - if unit == WeightUnitChoices.UNIT_KILOGRAM: - return weight * 1000 - if unit == WeightUnitChoices.UNIT_GRAM: - return weight - if unit == WeightUnitChoices.UNIT_POUND: - return weight * Decimal(453.592) - if unit == WeightUnitChoices.UNIT_OUNCE: - return weight * Decimal(28.3495) - raise ValueError(_("Unknown unit {unit}. Must be 'kg', 'g', 'lb', 'oz'.").format(unit=unit)) - - def render_jinja2(template_code, context): """ Render a Jinja2 template with the provided context. Return the rendered content.