mirror of
https://github.com/netbox-community/netbox.git
synced 2026-04-21 08:21:48 +02:00
This commit is contained in:
@@ -14,6 +14,7 @@ __all__ = (
|
||||
'expand_alphanumeric_pattern',
|
||||
'expand_ipaddress_pattern',
|
||||
'form_from_model',
|
||||
'get_capacity_unit_label',
|
||||
'get_field_value',
|
||||
'get_selected_values',
|
||||
'parse_alphanumeric_range',
|
||||
@@ -130,6 +131,13 @@ def expand_ipaddress_pattern(string, family):
|
||||
yield ''.join([lead, format(i, 'x' if family == 6 else 'd'), remnant])
|
||||
|
||||
|
||||
def get_capacity_unit_label(divisor=1000):
|
||||
"""
|
||||
Return the appropriate base unit label: 'MiB' for binary (1024), 'MB' for decimal (1000).
|
||||
"""
|
||||
return 'MiB' if divisor == 1024 else 'MB'
|
||||
|
||||
|
||||
def get_field_value(form, field_name):
|
||||
"""
|
||||
Return the current bound or initial value associated with a form field, prior to calling
|
||||
|
||||
@@ -20,8 +20,8 @@ __all__ = (
|
||||
'divide',
|
||||
'get_item',
|
||||
'get_key',
|
||||
'humanize_disk_megabytes',
|
||||
'humanize_ram_megabytes',
|
||||
'humanize_disk_capacity',
|
||||
'humanize_ram_capacity',
|
||||
'humanize_speed',
|
||||
'icon_from_status',
|
||||
'kg_to_pounds',
|
||||
@@ -208,42 +208,52 @@ def humanize_speed(speed):
|
||||
return '{} Kbps'.format(speed)
|
||||
|
||||
|
||||
def _humanize_megabytes(mb, divisor=1000):
|
||||
def _humanize_capacity(value, divisor=1000):
|
||||
"""
|
||||
Express a number of megabytes in the most suitable unit (e.g. gigabytes, terabytes, etc.).
|
||||
Express a capacity value in the most suitable unit (e.g. GB, TiB, etc.).
|
||||
|
||||
The value is treated as a unitless base-unit quantity; the divisor determines
|
||||
both the scaling thresholds and the label convention:
|
||||
- 1000: SI labels (MB, GB, TB, PB)
|
||||
- 1024: IEC labels (MiB, GiB, TiB, PiB)
|
||||
"""
|
||||
if not mb:
|
||||
if not value:
|
||||
return ""
|
||||
|
||||
if divisor == 1024:
|
||||
labels = ('MiB', 'GiB', 'TiB', 'PiB')
|
||||
else:
|
||||
labels = ('MB', 'GB', 'TB', 'PB')
|
||||
|
||||
PB_SIZE = divisor**3
|
||||
TB_SIZE = divisor**2
|
||||
GB_SIZE = divisor
|
||||
|
||||
if mb >= PB_SIZE:
|
||||
return f"{mb / PB_SIZE:.2f} PB"
|
||||
if mb >= TB_SIZE:
|
||||
return f"{mb / TB_SIZE:.2f} TB"
|
||||
if mb >= GB_SIZE:
|
||||
return f"{mb / GB_SIZE:.2f} GB"
|
||||
return f"{mb} MB"
|
||||
if value >= PB_SIZE:
|
||||
return f"{value / PB_SIZE:.2f} {labels[3]}"
|
||||
if value >= TB_SIZE:
|
||||
return f"{value / TB_SIZE:.2f} {labels[2]}"
|
||||
if value >= GB_SIZE:
|
||||
return f"{value / GB_SIZE:.2f} {labels[1]}"
|
||||
return f"{value} {labels[0]}"
|
||||
|
||||
|
||||
@register.filter()
|
||||
def humanize_disk_megabytes(mb):
|
||||
def humanize_disk_capacity(value):
|
||||
"""
|
||||
Express a number of megabytes in the most suitable unit (e.g. gigabytes, terabytes, etc.).
|
||||
Use the DISK_BASE_UNIT setting to determine the divisor. Default is 1000.
|
||||
Express a disk capacity in the most suitable unit, using the DISK_BASE_UNIT
|
||||
setting to select SI (MB/GB) or IEC (MiB/GiB) labels.
|
||||
"""
|
||||
return _humanize_megabytes(mb, DISK_BASE_UNIT)
|
||||
return _humanize_capacity(value, DISK_BASE_UNIT)
|
||||
|
||||
|
||||
@register.filter()
|
||||
def humanize_ram_megabytes(mb):
|
||||
def humanize_ram_capacity(value):
|
||||
"""
|
||||
Express a number of megabytes in the most suitable unit (e.g. gigabytes, terabytes, etc.).
|
||||
Use the RAM_BASE_UNIT setting to determine the divisor. Default is 1000.
|
||||
Express a RAM capacity in the most suitable unit, using the RAM_BASE_UNIT
|
||||
setting to select SI (MB/GB) or IEC (MiB/GiB) labels.
|
||||
"""
|
||||
return _humanize_megabytes(mb, RAM_BASE_UNIT)
|
||||
return _humanize_capacity(value, RAM_BASE_UNIT)
|
||||
|
||||
|
||||
@register.filter()
|
||||
|
||||
@@ -6,7 +6,12 @@ from netbox.choices import ImportFormatChoices
|
||||
from utilities.forms.bulk_import import BulkImportForm
|
||||
from utilities.forms.fields.csv import CSVSelectWidget
|
||||
from utilities.forms.forms import BulkRenameForm
|
||||
from utilities.forms.utils import expand_alphanumeric_pattern, expand_ipaddress_pattern, get_field_value
|
||||
from utilities.forms.utils import (
|
||||
expand_alphanumeric_pattern,
|
||||
expand_ipaddress_pattern,
|
||||
get_capacity_unit_label,
|
||||
get_field_value,
|
||||
)
|
||||
from utilities.forms.widgets.select import AvailableOptions, SelectedOptions
|
||||
|
||||
|
||||
@@ -550,3 +555,15 @@ class SelectMultipleWidgetTest(TestCase):
|
||||
self.assertEqual(widget.choices[0][1], [(2, 'Option 2')])
|
||||
self.assertEqual(widget.choices[1][0], 'Group B')
|
||||
self.assertEqual(widget.choices[1][1], [(3, 'Option 3')])
|
||||
|
||||
|
||||
class GetCapacityUnitLabelTest(TestCase):
|
||||
"""
|
||||
Test the get_capacity_unit_label function for correct base unit label.
|
||||
"""
|
||||
|
||||
def test_si_label(self):
|
||||
self.assertEqual(get_capacity_unit_label(1000), 'MB')
|
||||
|
||||
def test_iec_label(self):
|
||||
self.assertEqual(get_capacity_unit_label(1024), 'MiB')
|
||||
|
||||
@@ -3,6 +3,7 @@ from unittest.mock import patch
|
||||
from django.test import TestCase, override_settings
|
||||
|
||||
from utilities.templatetags.builtins.tags import static_with_params
|
||||
from utilities.templatetags.helpers import _humanize_capacity
|
||||
|
||||
|
||||
class StaticWithParamsTest(TestCase):
|
||||
@@ -46,3 +47,46 @@ class StaticWithParamsTest(TestCase):
|
||||
# Check that new parameter value is used
|
||||
self.assertIn('v=new_version', result)
|
||||
self.assertNotIn('v=old_version', result)
|
||||
|
||||
|
||||
class HumanizeCapacityTest(TestCase):
|
||||
"""
|
||||
Test the _humanize_capacity function for correct SI/IEC unit label selection.
|
||||
"""
|
||||
|
||||
# Tests with divisor=1000 (SI/decimal units)
|
||||
|
||||
def test_si_megabytes(self):
|
||||
self.assertEqual(_humanize_capacity(500, divisor=1000), '500 MB')
|
||||
|
||||
def test_si_gigabytes(self):
|
||||
self.assertEqual(_humanize_capacity(2000, divisor=1000), '2.00 GB')
|
||||
|
||||
def test_si_terabytes(self):
|
||||
self.assertEqual(_humanize_capacity(2000000, divisor=1000), '2.00 TB')
|
||||
|
||||
def test_si_petabytes(self):
|
||||
self.assertEqual(_humanize_capacity(2000000000, divisor=1000), '2.00 PB')
|
||||
|
||||
# Tests with divisor=1024 (IEC/binary units)
|
||||
|
||||
def test_iec_megabytes(self):
|
||||
self.assertEqual(_humanize_capacity(500, divisor=1024), '500 MiB')
|
||||
|
||||
def test_iec_gigabytes(self):
|
||||
self.assertEqual(_humanize_capacity(2048, divisor=1024), '2.00 GiB')
|
||||
|
||||
def test_iec_terabytes(self):
|
||||
self.assertEqual(_humanize_capacity(2097152, divisor=1024), '2.00 TiB')
|
||||
|
||||
def test_iec_petabytes(self):
|
||||
self.assertEqual(_humanize_capacity(2147483648, divisor=1024), '2.00 PiB')
|
||||
|
||||
# Edge cases
|
||||
|
||||
def test_empty_value(self):
|
||||
self.assertEqual(_humanize_capacity(0, divisor=1000), '')
|
||||
self.assertEqual(_humanize_capacity(None, divisor=1000), '')
|
||||
|
||||
def test_default_divisor_is_1000(self):
|
||||
self.assertEqual(_humanize_capacity(2000), '2.00 GB')
|
||||
|
||||
Reference in New Issue
Block a user