forked from shaba/openuds
Added metapools capacity of show grouped pools transports
This commit is contained in:
parent
ce73d4e29f
commit
e9a719a2eb
@ -63,7 +63,7 @@ class MetaPools(ModelHandler):
|
|||||||
}
|
}
|
||||||
|
|
||||||
save_fields = ['name', 'short_name', 'comments', 'tags',
|
save_fields = ['name', 'short_name', 'comments', 'tags',
|
||||||
'image_id', 'servicesPoolGroup_id', 'visible', 'policy', 'calendar_message']
|
'image_id', 'servicesPoolGroup_id', 'visible', 'policy', 'calendar_message', 'transport_grouping']
|
||||||
|
|
||||||
table_title = _('Meta Pools')
|
table_title = _('Meta Pools')
|
||||||
table_fields = [
|
table_fields = [
|
||||||
@ -74,6 +74,7 @@ class MetaPools(ModelHandler):
|
|||||||
{'user_services_in_preparation': {'title': _('In Preparation')}},
|
{'user_services_in_preparation': {'title': _('In Preparation')}},
|
||||||
{'visible': {'title': _('Visible'), 'type': 'callback'}},
|
{'visible': {'title': _('Visible'), 'type': 'callback'}},
|
||||||
{'pool_group_name': {'title': _('Pool Group')}},
|
{'pool_group_name': {'title': _('Pool Group')}},
|
||||||
|
{'label': {'title': _('Label')}},
|
||||||
{'tags': {'title': _('tags'), 'visible': False}},
|
{'tags': {'title': _('tags'), 'visible': False}},
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -113,6 +114,7 @@ class MetaPools(ModelHandler):
|
|||||||
'fallbackAccess': item.fallbackAccess,
|
'fallbackAccess': item.fallbackAccess,
|
||||||
'permission': permissions.getEffectivePermission(self._user, item),
|
'permission': permissions.getEffectivePermission(self._user, item),
|
||||||
'calendar_message': item.calendar_message,
|
'calendar_message': item.calendar_message,
|
||||||
|
'transport_grouping': item.transport_grouping
|
||||||
}
|
}
|
||||||
|
|
||||||
return val
|
return val
|
||||||
@ -135,7 +137,7 @@ class MetaPools(ModelHandler):
|
|||||||
'tooltip': ugettext('Image assocciated with this service'),
|
'tooltip': ugettext('Image assocciated with this service'),
|
||||||
'type': gui.InputField.IMAGECHOICE_TYPE,
|
'type': gui.InputField.IMAGECHOICE_TYPE,
|
||||||
'order': 120,
|
'order': 120,
|
||||||
'tab': ugettext('Display'),
|
'tab': gui.DISPLAY_TAB,
|
||||||
}, {
|
}, {
|
||||||
'name': 'servicesPoolGroup_id',
|
'name': 'servicesPoolGroup_id',
|
||||||
'values': [gui.choiceImage(-1, _('Default'), DEFAULT_THUMB_BASE64)] + gui.sortedChoices([gui.choiceImage(v.uuid, v.name, v.thumb64) for v in ServicePoolGroup.objects.all()]),
|
'values': [gui.choiceImage(-1, _('Default'), DEFAULT_THUMB_BASE64)] + gui.sortedChoices([gui.choiceImage(v.uuid, v.name, v.thumb64) for v in ServicePoolGroup.objects.all()]),
|
||||||
@ -143,7 +145,7 @@ class MetaPools(ModelHandler):
|
|||||||
'tooltip': ugettext('Pool group for this pool (for pool classify on display)'),
|
'tooltip': ugettext('Pool group for this pool (for pool classify on display)'),
|
||||||
'type': gui.InputField.IMAGECHOICE_TYPE,
|
'type': gui.InputField.IMAGECHOICE_TYPE,
|
||||||
'order': 121,
|
'order': 121,
|
||||||
'tab': ugettext('Display'),
|
'tab': gui.DISPLAY_TAB,
|
||||||
}, {
|
}, {
|
||||||
'name': 'visible',
|
'name': 'visible',
|
||||||
'value': True,
|
'value': True,
|
||||||
@ -151,7 +153,7 @@ class MetaPools(ModelHandler):
|
|||||||
'tooltip': ugettext('If active, metapool will be visible for users'),
|
'tooltip': ugettext('If active, metapool will be visible for users'),
|
||||||
'type': gui.InputField.CHECKBOX_TYPE,
|
'type': gui.InputField.CHECKBOX_TYPE,
|
||||||
'order': 123,
|
'order': 123,
|
||||||
'tab': ugettext('Display'),
|
'tab': gui.DISPLAY_TAB,
|
||||||
}, {
|
}, {
|
||||||
'name': 'calendar_message',
|
'name': 'calendar_message',
|
||||||
'value': '',
|
'value': '',
|
||||||
@ -159,7 +161,15 @@ class MetaPools(ModelHandler):
|
|||||||
'tooltip': ugettext('Custom message to be shown to users if access is limited by calendar rules.'),
|
'tooltip': ugettext('Custom message to be shown to users if access is limited by calendar rules.'),
|
||||||
'type': gui.InputField.TEXT_TYPE,
|
'type': gui.InputField.TEXT_TYPE,
|
||||||
'order': 124,
|
'order': 124,
|
||||||
'tab': ugettext('Display'),
|
'tab': gui.DISPLAY_TAB,
|
||||||
|
}, {
|
||||||
|
'name': 'transport_grouping',
|
||||||
|
'values': [gui.choiceItem(k, str(v)) for k, v in MetaPool.TRANSPORT_SELECT.items()],
|
||||||
|
'label': ugettext('Transport Selection'),
|
||||||
|
'tooltip': ugettext('Transport selection policy'),
|
||||||
|
'type': gui.InputField.CHOICE_TYPE,
|
||||||
|
'order': 125,
|
||||||
|
'tab': gui.DISPLAY_TAB
|
||||||
}]:
|
}]:
|
||||||
self.addField(localGUI, field)
|
self.addField(localGUI, field)
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ import typing
|
|||||||
from django.utils.translation import ugettext_lazy as _, ugettext
|
from django.utils.translation import ugettext_lazy as _, ugettext
|
||||||
from uds.models import Transport, Network, ServicePool
|
from uds.models import Transport, Network, ServicePool
|
||||||
from uds.core import transports
|
from uds.core import transports
|
||||||
|
from uds.core.ui import gui
|
||||||
from uds.core.util import permissions
|
from uds.core.util import permissions
|
||||||
from uds.core.util import os_detector as OsDetector
|
from uds.core.util import os_detector as OsDetector
|
||||||
|
|
||||||
@ -49,7 +50,7 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
class Transports(ModelHandler):
|
class Transports(ModelHandler):
|
||||||
model = Transport
|
model = Transport
|
||||||
save_fields = ['name', 'comments', 'tags', 'priority', 'nets_positive', 'allowed_oss']
|
save_fields = ['name', 'comments', 'tags', 'priority', 'nets_positive', 'allowed_oss', 'label']
|
||||||
|
|
||||||
table_title = _('Transports')
|
table_title = _('Transports')
|
||||||
table_fields = [
|
table_fields = [
|
||||||
@ -107,6 +108,16 @@ class Transports(ModelHandler):
|
|||||||
'type': 'multichoice',
|
'type': 'multichoice',
|
||||||
'order': 103
|
'order': 103
|
||||||
})
|
})
|
||||||
|
field = self.addField(field, {
|
||||||
|
'name': 'label',
|
||||||
|
'length': 32,
|
||||||
|
'value': '',
|
||||||
|
'label': ugettext('Label'),
|
||||||
|
'tooltip': ugettext('Metapool transport label (only used on metapool transports grouping)'),
|
||||||
|
'type': 'text',
|
||||||
|
'order': 201,
|
||||||
|
'tab': gui.ADVANCED_TAB
|
||||||
|
})
|
||||||
|
|
||||||
return field
|
return field
|
||||||
|
|
||||||
@ -120,6 +131,7 @@ class Transports(ModelHandler):
|
|||||||
'comments': item.comments,
|
'comments': item.comments,
|
||||||
'priority': item.priority,
|
'priority': item.priority,
|
||||||
'nets_positive': item.nets_positive,
|
'nets_positive': item.nets_positive,
|
||||||
|
'label': item.label,
|
||||||
'networks': [{'id': n.uuid} for n in item.networks.all()],
|
'networks': [{'id': n.uuid} for n in item.networks.all()],
|
||||||
'allowed_oss': [{'id': x} for x in item.allowed_oss.split(',')] if item.allowed_oss != '' else [],
|
'allowed_oss': [{'id': x} for x in item.allowed_oss.split(',')] if item.allowed_oss != '' else [],
|
||||||
'pools': pools,
|
'pools': pools,
|
||||||
|
@ -749,7 +749,7 @@ class UserServiceManager:
|
|||||||
Get service info from user service
|
Get service info from user service
|
||||||
"""
|
"""
|
||||||
if idService[0] == 'M': # Meta pool
|
if idService[0] == 'M': # Meta pool
|
||||||
return self.getMeta(user, srcIp, os, idService[1:])
|
return self.getMeta(user, srcIp, os, idService[1:], idTransport)
|
||||||
|
|
||||||
userService = self.locateUserService(user, idService, create=True)
|
userService = self.locateUserService(user, idService, create=True)
|
||||||
|
|
||||||
@ -908,6 +908,7 @@ class UserServiceManager:
|
|||||||
srcIp: str,
|
srcIp: str,
|
||||||
os: typing.MutableMapping,
|
os: typing.MutableMapping,
|
||||||
idMetaPool: str,
|
idMetaPool: str,
|
||||||
|
idTransport: str,
|
||||||
clientHostName: typing.Optional[str] = None,
|
clientHostName: typing.Optional[str] = None,
|
||||||
) -> typing.Tuple[
|
) -> typing.Tuple[
|
||||||
typing.Optional[str],
|
typing.Optional[str],
|
||||||
@ -953,7 +954,13 @@ class UserServiceManager:
|
|||||||
) -> typing.Optional[typing.Tuple[ServicePool, Transport]]:
|
) -> typing.Optional[typing.Tuple[ServicePool, Transport]]:
|
||||||
found = None
|
found = None
|
||||||
t: Transport
|
t: Transport
|
||||||
for t in pool.transports.all().order_by('priority'):
|
if idTransport == 'meta': # Autoselected:
|
||||||
|
q = pool.transports.all().order_by('priority')
|
||||||
|
elif idTransport[:6] == 'LABEL:':
|
||||||
|
q = pool.transports.filter(label=idTransport[6:])
|
||||||
|
else:
|
||||||
|
q = pool.transports.filter(uuid=idTransport)
|
||||||
|
for t in q:
|
||||||
typeTrans = t.getType()
|
typeTrans = t.getType()
|
||||||
if (
|
if (
|
||||||
t.getType()
|
t.getType()
|
||||||
|
23
server/src/uds/migrations/0040_auto_20210422_1340.py
Normal file
23
server/src/uds/migrations/0040_auto_20210422_1340.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 3.2 on 2021-04-22 13:40
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('uds', '0039_auto_20201111_1329'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='metapool',
|
||||||
|
name='transport_grouping',
|
||||||
|
field=models.IntegerField(default=0),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='transport',
|
||||||
|
name='label',
|
||||||
|
field=models.CharField(db_index=True, default='', max_length=32),
|
||||||
|
),
|
||||||
|
]
|
@ -68,12 +68,22 @@ class MetaPool(UUIDModel, TaggingMixin): # type: ignore
|
|||||||
PRIORITY_POOL = 1
|
PRIORITY_POOL = 1
|
||||||
MOST_AVAILABLE_BY_NUMBER = 2
|
MOST_AVAILABLE_BY_NUMBER = 2
|
||||||
|
|
||||||
TYPES = {
|
TYPES: typing.Mapping[int, str] = {
|
||||||
ROUND_ROBIN_POOL: _('Evenly distributed'),
|
ROUND_ROBIN_POOL: _('Evenly distributed'),
|
||||||
PRIORITY_POOL: _('Priority'),
|
PRIORITY_POOL: _('Priority'),
|
||||||
MOST_AVAILABLE_BY_NUMBER: _('Greater % available'),
|
MOST_AVAILABLE_BY_NUMBER: _('Greater % available'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Type of transport grouping
|
||||||
|
AUTO_TRANSPORT_SELECT = 0
|
||||||
|
COMMON_TRANSPORT_SELECT = 1
|
||||||
|
LABEL_TRANSPORT_SELECT = 2
|
||||||
|
TRANSPORT_SELECT: typing.Mapping[int, str] = {
|
||||||
|
AUTO_TRANSPORT_SELECT: _('Automatic selection'),
|
||||||
|
COMMON_TRANSPORT_SELECT: _('Use only common transports'),
|
||||||
|
LABEL_TRANSPORT_SELECT: _('Group Transports by label')
|
||||||
|
}
|
||||||
|
|
||||||
name = models.CharField(max_length=128, default='')
|
name = models.CharField(max_length=128, default='')
|
||||||
short_name = models.CharField(max_length=32, default='')
|
short_name = models.CharField(max_length=32, default='')
|
||||||
comments = models.CharField(max_length=256, default='')
|
comments = models.CharField(max_length=256, default='')
|
||||||
@ -103,6 +113,8 @@ class MetaPool(UUIDModel, TaggingMixin): # type: ignore
|
|||||||
|
|
||||||
# Pool selection policy
|
# Pool selection policy
|
||||||
policy = models.SmallIntegerField(default=0)
|
policy = models.SmallIntegerField(default=0)
|
||||||
|
# If use common transports instead of auto select one
|
||||||
|
transport_grouping = models.IntegerField(default=0)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.BaseManager[MetaPool]'
|
objects: 'models.BaseManager[MetaPool]'
|
||||||
|
@ -62,6 +62,8 @@ class Transport(ManagedObjectModel, TaggingMixin):
|
|||||||
nets_positive = models.BooleanField(default=False)
|
nets_positive = models.BooleanField(default=False)
|
||||||
# We store allowed oss as a comma-separated list
|
# We store allowed oss as a comma-separated list
|
||||||
allowed_oss = models.CharField(max_length=255, default='')
|
allowed_oss = models.CharField(max_length=255, default='')
|
||||||
|
# Label, to group transports on meta pools
|
||||||
|
label = models.CharField(max_length=32, default='', db_index=True)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.BaseManager[Transport]'
|
objects: 'models.BaseManager[Transport]'
|
||||||
|
File diff suppressed because one or more lines are too long
@ -93,6 +93,6 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</uds-root>
|
</uds-root>
|
||||||
<script src="/uds/res/admin/runtime.js?stamp=1619085422" defer></script><script src="/uds/res/admin/polyfills-es5.js?stamp=1619085422" nomodule defer></script><script src="/uds/res/admin/polyfills.js?stamp=1619085422" defer></script><script src="/uds/res/admin/main.js?stamp=1619085422" defer></script></body>
|
<script src="/uds/res/admin/runtime.js?stamp=1619092209" defer></script><script src="/uds/res/admin/polyfills-es5.js?stamp=1619092209" nomodule defer></script><script src="/uds/res/admin/polyfills.js?stamp=1619092209" defer></script><script src="/uds/res/admin/main.js?stamp=1619092209" defer></script></body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
@ -101,12 +101,12 @@ urlpatterns = [
|
|||||||
re_path(r'^uds/utility/download/(?P<idDownload>[a-zA-Z0-9-]*)$', uds.web.views.download, name='utility.downloader'),
|
re_path(r'^uds/utility/download/(?P<idDownload>[a-zA-Z0-9-]*)$', uds.web.views.download, name='utility.downloader'),
|
||||||
|
|
||||||
# WEB API path (not REST api, frontend)
|
# WEB API path (not REST api, frontend)
|
||||||
re_path(r'^uds/webapi/img/transport/(?P<idTrans>[a-zA-Z0-9-]+)$', uds.web.views.transportIcon, name='webapi.transportIcon'),
|
re_path(r'^uds/webapi/img/transport/(?P<idTrans>[a-zA-Z0-9:-]+)$', uds.web.views.transportIcon, name='webapi.transportIcon'),
|
||||||
re_path(r'^uds/webapi/img/gallery/(?P<idImage>[a-zA-Z0-9-]+)$', uds.web.views.image, name='webapi.galleryImage'),
|
re_path(r'^uds/webapi/img/gallery/(?P<idImage>[a-zA-Z0-9-]+)$', uds.web.views.image, name='webapi.galleryImage'),
|
||||||
|
|
||||||
re_path(r'^uds/webapi/action/(?P<idService>.+)/enable/(?P<idTransport>[a-zA-Z0-9-]+)$', uds.web.views.userServiceEnabler, name='webapi.enabler'),
|
re_path(r'^uds/webapi/action/(?P<idService>.+)/enable/(?P<idTransport>[a-zA-Z0-9:-]+)$', uds.web.views.userServiceEnabler, name='webapi.enabler'),
|
||||||
|
|
||||||
re_path(r'^uds/webapi/action/(?P<idService>.+)/(?P<actionString>[a-zA-Z0-9-]+)$', uds.web.views.action, name='webapi.action'),
|
re_path(r'^uds/webapi/action/(?P<idService>.+)/(?P<actionString>[a-zA-Z0-9:-]+)$', uds.web.views.action, name='webapi.action'),
|
||||||
|
|
||||||
# Services list, ...
|
# Services list, ...
|
||||||
path(r'uds/webapi/services', uds.web.views.modern.servicesData, name='webapi.services'),
|
path(r'uds/webapi/services', uds.web.views.modern.servicesData, name='webapi.services'),
|
||||||
|
@ -101,6 +101,34 @@ def getServicesData(
|
|||||||
|
|
||||||
logger.debug('Checking meta pools: %s', availMetaPools)
|
logger.debug('Checking meta pools: %s', availMetaPools)
|
||||||
services = []
|
services = []
|
||||||
|
|
||||||
|
# Metapool helpers
|
||||||
|
def transportIterator(member) -> typing.Iterable[Transport]:
|
||||||
|
for t in member.pool.transports.all():
|
||||||
|
typeTrans = t.getType()
|
||||||
|
if (
|
||||||
|
typeTrans
|
||||||
|
and t.validForIp(request.ip)
|
||||||
|
and typeTrans.supportsOs(osName)
|
||||||
|
and t.validForOs(osName)
|
||||||
|
):
|
||||||
|
yield t
|
||||||
|
|
||||||
|
def buildMetaTransports(
|
||||||
|
transports: typing.Iterable[Transport],
|
||||||
|
isLabel: bool,
|
||||||
|
) -> typing.List[typing.Mapping[str, typing.Any]]:
|
||||||
|
idd = lambda i: i.uuid if not isLabel else 'LABEL:' + i.label
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
'id': idd(i),
|
||||||
|
'name': i.name,
|
||||||
|
'link': html.udsAccessLink(request, 'M' + meta.uuid, idd(i)),
|
||||||
|
'priority': 0,
|
||||||
|
}
|
||||||
|
for i in transports
|
||||||
|
]
|
||||||
|
|
||||||
# Preload all assigned user services for this user
|
# Preload all assigned user services for this user
|
||||||
# Add meta pools data first
|
# Add meta pools data first
|
||||||
for meta in availMetaPools:
|
for meta in availMetaPools:
|
||||||
@ -108,35 +136,48 @@ def getServicesData(
|
|||||||
metaTransports: typing.List[typing.Mapping[str, typing.Any]] = []
|
metaTransports: typing.List[typing.Mapping[str, typing.Any]] = []
|
||||||
in_use = meta.number_in_use > 0 # type: ignore # anotated value
|
in_use = meta.number_in_use > 0 # type: ignore # anotated value
|
||||||
|
|
||||||
if True: # If meta.use_common_transports
|
inAll: typing.Optional[typing.Set[str]] = None
|
||||||
|
tmpSet: typing.Set[str]
|
||||||
|
if (
|
||||||
|
meta.transport_grouping == MetaPool.COMMON_TRANSPORT_SELECT
|
||||||
|
): # If meta.use_common_transports
|
||||||
# only keep transports that are in ALL members
|
# only keep transports that are in ALL members
|
||||||
inAll: typing.Optional[typing.Set[str]] = None
|
for member in meta.members.all().order_by('priority'):
|
||||||
for member in meta.members.all():
|
tmpSet = set()
|
||||||
tmpSet: typing.Set[str] = set()
|
# if first pool, get all its transports and check that are valid
|
||||||
for t in member.pool.transports.all():
|
for t in transportIterator(member):
|
||||||
if inAll is None: # if first...
|
if inAll is None:
|
||||||
typeTrans = t.getType()
|
|
||||||
if (
|
|
||||||
typeTrans
|
|
||||||
and t.validForIp(request.ip)
|
|
||||||
and typeTrans.supportsOs(osName)
|
|
||||||
and t.validForOs(osName)
|
|
||||||
):
|
|
||||||
tmpSet.add(t.uuid)
|
|
||||||
elif t.uuid in inAll:
|
|
||||||
tmpSet.add(t.uuid)
|
tmpSet.add(t.uuid)
|
||||||
|
elif t.uuid in inAll: # For subsequent, reduce...
|
||||||
|
tmpSet.add(t.uuid)
|
||||||
|
|
||||||
inAll = tmpSet
|
inAll = tmpSet
|
||||||
# tmpSet has ALL common transports
|
# tmpSet has ALL common transports
|
||||||
metaTransports = [
|
metaTransports = buildMetaTransports(
|
||||||
{
|
Transport.objects.filter(uuid__in=inAll or []),
|
||||||
'id': i.uuid,
|
isLabel=False
|
||||||
'name': i.name,
|
)
|
||||||
'link': html.udsAccessLink(request, 'M' + meta.uuid, i.uuid),
|
elif meta.transport_grouping == MetaPool.LABEL_TRANSPORT_SELECT:
|
||||||
'priority': 0,
|
ltrans: typing.MutableMapping[str, Transport] = {}
|
||||||
}
|
for member in meta.members.all():
|
||||||
for i in Transport.objects.filter(uuid__in=inAll or [])
|
tmpSet = set()
|
||||||
]
|
# if first pool, get all its transports and check that are valid
|
||||||
|
for t in transportIterator(member):
|
||||||
|
if not t.label:
|
||||||
|
continue
|
||||||
|
if t.label not in ltrans:
|
||||||
|
ltrans[t.label] = t
|
||||||
|
if inAll is None:
|
||||||
|
tmpSet.add(t.label)
|
||||||
|
elif t.label in inAll: # For subsequent, reduce...
|
||||||
|
tmpSet.add(t.label)
|
||||||
|
|
||||||
|
inAll = tmpSet
|
||||||
|
# tmpSet has ALL common transports
|
||||||
|
metaTransports = buildMetaTransports(
|
||||||
|
(v for k, v in ltrans.items() if k in (inAll or set())),
|
||||||
|
isLabel=True
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
for member in meta.members.all():
|
for member in meta.members.all():
|
||||||
# if pool.isInMaintenance():
|
# if pool.isInMaintenance():
|
||||||
@ -187,7 +228,7 @@ def getServicesData(
|
|||||||
'group': group,
|
'group': group,
|
||||||
'transports': metaTransports,
|
'transports': metaTransports,
|
||||||
'imageId': meta.image and meta.image.uuid or 'x',
|
'imageId': meta.image and meta.image.uuid or 'x',
|
||||||
'show_transports': False,
|
'show_transports': len(metaTransports) > 1,
|
||||||
'allow_users_remove': False,
|
'allow_users_remove': False,
|
||||||
'allow_users_reset': False,
|
'allow_users_reset': False,
|
||||||
'maintenance': meta.isInMaintenance(),
|
'maintenance': meta.isInMaintenance(),
|
||||||
@ -209,7 +250,7 @@ def getServicesData(
|
|||||||
use_count = str(sPool.usage_count) # type: ignore # anotated value
|
use_count = str(sPool.usage_count) # type: ignore # anotated value
|
||||||
left_count = str(sPool.max_srvs - sPool.usage_count) # type: ignore # anotated value
|
left_count = str(sPool.max_srvs - sPool.usage_count) # type: ignore # anotated value
|
||||||
|
|
||||||
trans = []
|
trans: typing.List[typing.MutableMapping[str, typing.Any]] = []
|
||||||
for t in sorted(
|
for t in sorted(
|
||||||
sPool.transports.all(), key=lambda x: x.priority
|
sPool.transports.all(), key=lambda x: x.priority
|
||||||
): # In memory sort, allows reuse prefetched and not too big array
|
): # In memory sort, allows reuse prefetched and not too big array
|
||||||
|
@ -100,7 +100,12 @@ def transportOwnLink(
|
|||||||
@cache_page(3600, key_prefix='img', cache='memory')
|
@cache_page(3600, key_prefix='img', cache='memory')
|
||||||
def transportIcon(request: 'ExtendedHttpRequest', idTrans: str) -> HttpResponse:
|
def transportIcon(request: 'ExtendedHttpRequest', idTrans: str) -> HttpResponse:
|
||||||
try:
|
try:
|
||||||
transport: Transport = Transport.objects.get(uuid=processUuid(idTrans))
|
transport: Transport
|
||||||
|
if idTrans[:6] == 'LABEL:':
|
||||||
|
# Get First label
|
||||||
|
transport = Transport.objects.filter(label=idTrans[6:]).order_by('priority')[0]
|
||||||
|
else:
|
||||||
|
transport = Transport.objects.get(uuid=processUuid(idTrans))
|
||||||
return HttpResponse(transport.getInstance().icon(), content_type='image/png')
|
return HttpResponse(transport.getInstance().icon(), content_type='image/png')
|
||||||
except Exception:
|
except Exception:
|
||||||
return HttpResponse(DEFAULT_IMAGE, content_type='image/png')
|
return HttpResponse(DEFAULT_IMAGE, content_type='image/png')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user