Introduce array_to_string() utility function; add port_list property to Service

This commit is contained in:
Jeremy Stretch 2020-09-21 13:31:38 -04:00
parent f97d8963f2
commit e77f1bdd85
5 changed files with 24 additions and 18 deletions

View File

@ -1,5 +1,4 @@
from collections import OrderedDict
from itertools import count, groupby
from django.conf import settings
from django.contrib.auth.models import User
@ -22,7 +21,7 @@ from utilities.choices import ColorChoices
from utilities.fields import ColorField, NaturalOrderingField
from utilities.querysets import RestrictedQuerySet
from utilities.mptt import TreeManager
from utilities.utils import serialize_object
from utilities.utils import array_to_string, serialize_object
from .devices import Device
from .power import PowerFeed
@ -642,9 +641,4 @@ class RackReservation(ChangeLoggedModel, CustomFieldModel):
@property
def unit_list(self):
"""
Express the assigned units as a string of summarized ranges. For example:
[0, 1, 2, 10, 14, 15, 16] => "0-2, 10, 14-16"
"""
group = (list(x) for _, x in groupby(sorted(self.units), lambda x, c=count(): next(c) - x))
return ', '.join('-'.join(map(str, (g[0], g[-1])[:len(g)])) for g in group)
return array_to_string(self.units)

View File

@ -14,7 +14,7 @@ from dcim.models import Device, Interface
from extras.models import ChangeLoggedModel, CustomFieldModel, ObjectChange, TaggedItem
from extras.utils import extras_features
from utilities.querysets import RestrictedQuerySet
from utilities.utils import serialize_object
from utilities.utils import array_to_string, serialize_object
from virtualization.models import VirtualMachine, VMInterface
from .choices import *
from .constants import *
@ -1038,7 +1038,7 @@ class Service(ChangeLoggedModel, CustomFieldModel):
ordering = ('protocol', 'ports', 'pk') # (protocol, port) may be non-unique
def __str__(self):
return f'{self.name} ({self.get_protocol_display()}/{self.ports})'
return f'{self.name} ({self.get_protocol_display()}/{self.port_list})'
def get_absolute_url(self):
return reverse('ipam:service', args=[self.pk])
@ -1064,3 +1064,7 @@ class Service(ChangeLoggedModel, CustomFieldModel):
self.ports,
self.description,
)
@property
def port_list(self):
return array_to_string(self.ports)

View File

@ -1,13 +1,10 @@
<tr>
<td>
<a href="{{ service.get_absolute_url }}">{{ service.name }}</a>
</td>
<td>
{{ service.get_protocol_display }}/{{ service.port }}
</td>
<td><a href="{{ service.get_absolute_url }}">{{ service.name }}</a></td>
<td>{{ service.get_protocol_display }}</td>
<td>{{ service.port_list }}</td>
<td>
{% for ip in service.ipaddresses.all %}
<span>{{ ip.address.ip }}</span><br />
<a href="{{ ip.get_absolute_url }}">{{ ip.address.ip }}</a><br />
{% empty %}
<span class="text-muted">All IPs</span>
{% endfor %}

View File

@ -63,7 +63,7 @@
</tr>
<tr>
<td>Ports</td>
<td>{{ service.ports|join:", " }}</td>
<td>{{ service.port_list }}</td>
</tr>
<tr>
<td>IP Addresses</td>

View File

@ -1,6 +1,7 @@
import datetime
import json
from collections import OrderedDict
from itertools import count, groupby
from django.core.serializers import serialize
from django.db.models import Count, OuterRef, Subquery
@ -282,6 +283,16 @@ def curry(_curried_func, *args, **kwargs):
return _curried
def array_to_string(array):
"""
Generate an efficient, human-friendly string from a set of integers. Intended for use with ArrayField.
For example:
[0, 1, 2, 10, 14, 15, 16] => "0-2, 10, 14-16"
"""
group = (list(x) for _, x in groupby(sorted(array), lambda x, c=count(): next(c) - x))
return ', '.join('-'.join(map(str, (g[0], g[-1])[:len(g)])) for g in group)
#
# Fake request object
#