simo 2.0.7__py3-none-any.whl → 2.0.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of simo might be problematic. Click here for more details.
- simo/core/__pycache__/base_types.cpython-38.pyc +0 -0
- simo/core/__pycache__/models.cpython-38.pyc +0 -0
- simo/core/models.py +29 -20
- simo/fleet/__pycache__/base_types.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/controllers.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/forms.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/gateways.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/models.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/socket_consumers.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/views.cpython-38.pyc +0 -0
- simo/fleet/base_types.py +5 -0
- simo/fleet/controllers.py +57 -20
- simo/fleet/forms.py +16 -22
- simo/fleet/gateways.py +15 -6
- simo/fleet/migrations/0033_auto_20240415_0736.py +1 -1
- simo/fleet/migrations/__pycache__/0033_auto_20240415_0736.cpython-38.pyc +0 -0
- simo/fleet/models.py +1 -0
- simo/fleet/socket_consumers.py +8 -12
- simo/fleet/views.py +2 -2
- simo/generic/__pycache__/controllers.cpython-38.pyc +0 -0
- simo/generic/controllers.py +1 -1
- simo/users/__pycache__/api.cpython-38.pyc +0 -0
- simo/users/api.py +4 -2
- {simo-2.0.7.dist-info → simo-2.0.9.dist-info}/METADATA +1 -1
- {simo-2.0.7.dist-info → simo-2.0.9.dist-info}/RECORD +28 -26
- {simo-2.0.7.dist-info → simo-2.0.9.dist-info}/LICENSE.md +0 -0
- {simo-2.0.7.dist-info → simo-2.0.9.dist-info}/WHEEL +0 -0
- {simo-2.0.7.dist-info → simo-2.0.9.dist-info}/top_level.txt +0 -0
|
Binary file
|
|
Binary file
|
simo/core/models.py
CHANGED
|
@@ -267,29 +267,38 @@ class Gateway(DirtyFieldsMixin, models.Model, SimoAdminMixin):
|
|
|
267
267
|
|
|
268
268
|
def process_discovery(self, data):
|
|
269
269
|
self.refresh_from_db()
|
|
270
|
+
if self.discovery.get('finished'):
|
|
271
|
+
print(
|
|
272
|
+
f"Gateway is not in pairing mode at the moment!"
|
|
273
|
+
)
|
|
274
|
+
return
|
|
275
|
+
if self.discovery['controller_uid'] != data.get('type'):
|
|
276
|
+
print(f"Gateway is not in pairing mode for {self.discovery['controller_uid']} "
|
|
277
|
+
f"but not for {data.get('type')} at the moment!")
|
|
278
|
+
return
|
|
279
|
+
|
|
270
280
|
from .utils.type_constants import CONTROLLER_TYPES_MAP
|
|
271
|
-
ControllerClass = CONTROLLER_TYPES_MAP.get(
|
|
272
|
-
|
|
281
|
+
ControllerClass = CONTROLLER_TYPES_MAP.get(data.get('type'))
|
|
282
|
+
if not hasattr(ControllerClass, '_process_discovery'):
|
|
283
|
+
print(f"{data.get('type')} controller has no _process_discovery method." )
|
|
284
|
+
return
|
|
285
|
+
|
|
286
|
+
result = ControllerClass._process_discovery(
|
|
287
|
+
started_with=self.discovery['init_data'], data=data
|
|
273
288
|
)
|
|
274
|
-
if
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
if result:
|
|
281
|
-
self.refresh_from_db()
|
|
282
|
-
if not isinstance(result, dict) and isinstance(result, Iterable):
|
|
283
|
-
for res in result:
|
|
284
|
-
if isinstance(res, models.Model):
|
|
285
|
-
self.discovery['result'].append(res.pk)
|
|
286
|
-
else:
|
|
287
|
-
self.discovery['result'].append(res)
|
|
288
|
-
else:
|
|
289
|
-
if isinstance(result, models.Model):
|
|
290
|
-
self.discovery['result'].append(result.pk)
|
|
289
|
+
if result:
|
|
290
|
+
self.refresh_from_db()
|
|
291
|
+
if not isinstance(result, dict) and isinstance(result, Iterable):
|
|
292
|
+
for res in result:
|
|
293
|
+
if isinstance(res, models.Model):
|
|
294
|
+
self.discovery['result'].append(res.pk)
|
|
291
295
|
else:
|
|
292
|
-
self.discovery['result'].append(
|
|
296
|
+
self.discovery['result'].append(res)
|
|
297
|
+
else:
|
|
298
|
+
if isinstance(result, models.Model):
|
|
299
|
+
self.discovery['result'].append(result.pk)
|
|
300
|
+
else:
|
|
301
|
+
self.discovery['result'].append(result)
|
|
293
302
|
|
|
294
303
|
self.save(update_fields=['discovery'])
|
|
295
304
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
simo/fleet/base_types.py
ADDED
simo/fleet/controllers.py
CHANGED
|
@@ -8,7 +8,7 @@ from simo.core.controllers import (
|
|
|
8
8
|
)
|
|
9
9
|
from simo.conf import dynamic_settings
|
|
10
10
|
from simo.core.app_widgets import NumericSensorWidget
|
|
11
|
-
from simo.core.controllers import Lock
|
|
11
|
+
from simo.core.controllers import Lock, ControllerBase, SingleSwitchWidget
|
|
12
12
|
from simo.core.utils.helpers import heat_index
|
|
13
13
|
from simo.core.utils.serialization import (
|
|
14
14
|
serialize_form_data, deserialize_form_data
|
|
@@ -24,7 +24,7 @@ from .forms import (
|
|
|
24
24
|
ColonelDHTSensorConfigForm, DS18B20SensorConfigForm,
|
|
25
25
|
BME680SensorConfigForm, MPC9808SensorConfigForm,
|
|
26
26
|
DualMotorValveForm, BlindsConfigForm, BurglarSmokeDetectorConfigForm,
|
|
27
|
-
TTLockConfigForm, DALIDeviceConfigForm
|
|
27
|
+
TTLockConfigForm, DALIDeviceConfigForm, DaliSwitchForm
|
|
28
28
|
)
|
|
29
29
|
|
|
30
30
|
|
|
@@ -91,14 +91,14 @@ class BurglarSmokeDetector(BinarySensor):
|
|
|
91
91
|
]
|
|
92
92
|
|
|
93
93
|
|
|
94
|
-
class AnalogSensor(FleeDeviceMixin, BasicSensorMixin, BaseNumericSensor):
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
94
|
+
# class AnalogSensor(FleeDeviceMixin, BasicSensorMixin, BaseNumericSensor):
|
|
95
|
+
# config_form = ColonelNumericSensorConfigForm
|
|
96
|
+
# name = "Analog sensor"
|
|
97
|
+
#
|
|
98
|
+
# def _get_occupied_pins(self):
|
|
99
|
+
# return [
|
|
100
|
+
# self.component.config['pin_no'],
|
|
101
|
+
# ]
|
|
102
102
|
|
|
103
103
|
|
|
104
104
|
class DS18B20Sensor(FleeDeviceMixin, BasicSensorMixin, BaseNumericSensor):
|
|
@@ -112,6 +112,7 @@ class DS18B20Sensor(FleeDeviceMixin, BasicSensorMixin, BaseNumericSensor):
|
|
|
112
112
|
|
|
113
113
|
|
|
114
114
|
class BaseClimateSensor(FleeDeviceMixin, BasicSensorMixin, BaseMultiSensor):
|
|
115
|
+
manual_add = False
|
|
115
116
|
app_widget = NumericSensorWidget
|
|
116
117
|
|
|
117
118
|
def __init__(self, *args, **kwargs):
|
|
@@ -196,7 +197,7 @@ class Switch(FleeDeviceMixin, BasicOutputMixin, BaseSwitch):
|
|
|
196
197
|
|
|
197
198
|
|
|
198
199
|
class PWMOutput(FleeDeviceMixin, BasicOutputMixin, BaseDimmer):
|
|
199
|
-
name = "
|
|
200
|
+
name = "Dimmer"
|
|
200
201
|
config_form = ColonelPWMOutputConfigForm
|
|
201
202
|
|
|
202
203
|
def _prepare_for_send(self, value):
|
|
@@ -303,7 +304,7 @@ class TTLock(FleeDeviceMixin, Lock):
|
|
|
303
304
|
)
|
|
304
305
|
GatewayObjectCommand(
|
|
305
306
|
gateway, form_cleaned_data['colonel'],
|
|
306
|
-
command='discover
|
|
307
|
+
command='discover', type=self.uid
|
|
307
308
|
).publish()
|
|
308
309
|
|
|
309
310
|
@classmethod
|
|
@@ -385,6 +386,14 @@ class TTLock(FleeDeviceMixin, Lock):
|
|
|
385
386
|
command='call', method='delete_code', args=[str(code)]
|
|
386
387
|
).publish()
|
|
387
388
|
|
|
389
|
+
def clear_codes(self):
|
|
390
|
+
GatewayObjectCommand(
|
|
391
|
+
self.component.gateway,
|
|
392
|
+
Colonel(id=self.component.config['colonel']),
|
|
393
|
+
id=self.component.id,
|
|
394
|
+
command='call', method='clear_codes'
|
|
395
|
+
).publish()
|
|
396
|
+
|
|
388
397
|
def get_codes(self):
|
|
389
398
|
GatewayObjectCommand(
|
|
390
399
|
self.component.gateway,
|
|
@@ -410,6 +419,14 @@ class TTLock(FleeDeviceMixin, Lock):
|
|
|
410
419
|
command='call', method='delete_fingerprint', args=[str(code)]
|
|
411
420
|
).publish()
|
|
412
421
|
|
|
422
|
+
def clear_fingerprints(self):
|
|
423
|
+
GatewayObjectCommand(
|
|
424
|
+
self.component.gateway,
|
|
425
|
+
Colonel(id=self.component.config['colonel']),
|
|
426
|
+
id=self.component.id,
|
|
427
|
+
command='call', method='clear_fingerprints'
|
|
428
|
+
).publish()
|
|
429
|
+
|
|
413
430
|
def get_fingerprints(self):
|
|
414
431
|
GatewayObjectCommand(
|
|
415
432
|
self.component.gateway,
|
|
@@ -419,11 +436,19 @@ class TTLock(FleeDeviceMixin, Lock):
|
|
|
419
436
|
).publish()
|
|
420
437
|
|
|
421
438
|
|
|
422
|
-
class DALIDevice(FleeDeviceMixin):
|
|
439
|
+
class DALIDevice(FleeDeviceMixin, ControllerBase):
|
|
423
440
|
gateway_class = FleetGatewayHandler
|
|
424
441
|
config_form = DALIDeviceConfigForm
|
|
442
|
+
name = "DALI Device"
|
|
425
443
|
discovery_msg = _("Please hook up your new DALI device to your DALI bus.")
|
|
426
444
|
|
|
445
|
+
base_type = 'dali'
|
|
446
|
+
default_value = False
|
|
447
|
+
app_widget = SingleSwitchWidget
|
|
448
|
+
|
|
449
|
+
def _validate_val(self, value, occasion=None):
|
|
450
|
+
pass
|
|
451
|
+
|
|
427
452
|
@classmethod
|
|
428
453
|
def init_discovery(self, form_cleaned_data):
|
|
429
454
|
from simo.core.models import Gateway
|
|
@@ -434,14 +459,25 @@ class DALIDevice(FleeDeviceMixin):
|
|
|
434
459
|
)
|
|
435
460
|
GatewayObjectCommand(
|
|
436
461
|
gateway, form_cleaned_data['colonel'],
|
|
437
|
-
command=
|
|
438
|
-
|
|
462
|
+
command='discover', type=self.uid,
|
|
463
|
+
i=form_cleaned_data['interface'].no
|
|
439
464
|
).publish()
|
|
440
465
|
|
|
441
466
|
@classmethod
|
|
442
467
|
def _process_discovery(cls, started_with, data):
|
|
468
|
+
if data['discovery-result'] == 'fail':
|
|
469
|
+
if data['result'] == 1:
|
|
470
|
+
return {'error': 'DALI interface is unavailable!'}
|
|
471
|
+
else:
|
|
472
|
+
return {'error': 'Unknown error!'}
|
|
473
|
+
|
|
474
|
+
controller_cls = globals().get(data['result']['type'])
|
|
475
|
+
|
|
443
476
|
started_with = deserialize_form_data(started_with)
|
|
444
|
-
|
|
477
|
+
started_with['name'] += f" {data['result']['config']['da']}"
|
|
478
|
+
form = controller_cls.config_form(
|
|
479
|
+
controller_uid=controller_cls.uid, data=started_with
|
|
480
|
+
)
|
|
445
481
|
|
|
446
482
|
if form.is_valid():
|
|
447
483
|
new_component = form.save()
|
|
@@ -452,11 +488,9 @@ class DALIDevice(FleeDeviceMixin):
|
|
|
452
488
|
'config': {
|
|
453
489
|
'type': cls.uid.split('.')[-1],
|
|
454
490
|
'config': new_component.config,
|
|
455
|
-
'val': False,
|
|
456
491
|
},
|
|
457
492
|
}
|
|
458
493
|
new_component.save()
|
|
459
|
-
new_component.gateway.finish_discovery()
|
|
460
494
|
GatewayObjectCommand(
|
|
461
495
|
new_component.gateway, Colonel(
|
|
462
496
|
id=new_component.config['colonel']
|
|
@@ -470,6 +504,7 @@ class DALIDevice(FleeDeviceMixin):
|
|
|
470
504
|
|
|
471
505
|
|
|
472
506
|
class DALIGear(DALIDevice):
|
|
507
|
+
manual_add = False
|
|
473
508
|
|
|
474
509
|
def _send_to_device(self, value):
|
|
475
510
|
GatewayObjectCommand(
|
|
@@ -481,13 +516,15 @@ class DALIGear(DALIDevice):
|
|
|
481
516
|
|
|
482
517
|
|
|
483
518
|
class DALILamp(DALIGear, BaseSwitch):
|
|
519
|
+
family = 'dali'
|
|
484
520
|
manual_add = False
|
|
485
521
|
name = 'DALI Lamp'
|
|
486
|
-
|
|
522
|
+
config_form = DaliSwitchForm
|
|
487
523
|
|
|
488
524
|
|
|
489
525
|
class DALIDimmableLamp(DALIGear, BaseDimmer):
|
|
526
|
+
family = 'dali'
|
|
490
527
|
manual_add = False
|
|
491
528
|
name = 'DALI Dimmable Lamp'
|
|
492
|
-
|
|
529
|
+
|
|
493
530
|
|
simo/fleet/forms.py
CHANGED
|
@@ -6,7 +6,9 @@ from django.contrib.contenttypes.models import ContentType
|
|
|
6
6
|
from dal import autocomplete
|
|
7
7
|
from dal import forward
|
|
8
8
|
from simo.core.models import Component
|
|
9
|
-
from simo.core.forms import
|
|
9
|
+
from simo.core.forms import (
|
|
10
|
+
BaseComponentForm, ValueLimitForm, NumericSensorForm, SwitchForm
|
|
11
|
+
)
|
|
10
12
|
from simo.core.utils.formsets import FormsetField
|
|
11
13
|
from simo.core.widgets import LogOutputWidget
|
|
12
14
|
from simo.core.utils.easing import EASING_CHOICES
|
|
@@ -64,7 +66,6 @@ class InterfaceAdminForm(forms.ModelForm):
|
|
|
64
66
|
model = Interface
|
|
65
67
|
fields = '__all__'
|
|
66
68
|
|
|
67
|
-
|
|
68
69
|
def clean(self):
|
|
69
70
|
if self.instance.pk:
|
|
70
71
|
return self.cleaned_data
|
|
@@ -80,26 +81,6 @@ class InterfaceAdminForm(forms.ModelForm):
|
|
|
80
81
|
)
|
|
81
82
|
|
|
82
83
|
|
|
83
|
-
|
|
84
|
-
def clean_scl_pin(self):
|
|
85
|
-
if self.cleaned_data['scl_pin'].occupied_by \
|
|
86
|
-
and self.cleaned_data['scl_pin'].occupied_by != self.instance:
|
|
87
|
-
raise forms.ValidationError(
|
|
88
|
-
f"This pin is already occupied by "
|
|
89
|
-
f"{self.cleaned_data['scl_pin'].occupied_by}!"
|
|
90
|
-
)
|
|
91
|
-
return self.cleaned_data['scl_pin']
|
|
92
|
-
|
|
93
|
-
def clean_sda_pin(self):
|
|
94
|
-
if self.cleaned_data['sda_pin'].occupied_by \
|
|
95
|
-
and self.cleaned_data['sda_pin'].occupied_by != self.instance:
|
|
96
|
-
raise forms.ValidationError(
|
|
97
|
-
f"This pin is already occupied by "
|
|
98
|
-
f"{self.cleaned_data['sda_pin'].occupied_by}!"
|
|
99
|
-
)
|
|
100
|
-
return self.cleaned_data['sda_pin']
|
|
101
|
-
|
|
102
|
-
|
|
103
84
|
class ColonelComponentForm(BaseComponentForm):
|
|
104
85
|
colonel = forms.ModelChoiceField(
|
|
105
86
|
label="Colonel", queryset=Colonel.objects.all(),
|
|
@@ -1045,3 +1026,16 @@ class DALIDeviceConfigForm(ColonelComponentForm):
|
|
|
1045
1026
|
return super().save(commit=commit)
|
|
1046
1027
|
|
|
1047
1028
|
|
|
1029
|
+
class DaliSwitchForm(DALIDeviceConfigForm, SwitchForm):
|
|
1030
|
+
|
|
1031
|
+
auto_off = forms.FloatField(
|
|
1032
|
+
required=False, min_value=0.01, max_value=1000000000,
|
|
1033
|
+
help_text="If provided, switch will be turned off after "
|
|
1034
|
+
"given amount of seconds after last turn on event."
|
|
1035
|
+
)
|
|
1036
|
+
inverse = forms.BooleanField(
|
|
1037
|
+
label=_("Inverse switch value"), required=False
|
|
1038
|
+
)
|
|
1039
|
+
|
|
1040
|
+
|
|
1041
|
+
|
simo/fleet/gateways.py
CHANGED
|
@@ -5,7 +5,7 @@ from simo.core.gateways import BaseObjectCommandsGatewayHandler
|
|
|
5
5
|
from simo.core.forms import BaseGatewayForm
|
|
6
6
|
from simo.core.models import Gateway
|
|
7
7
|
from simo.core.events import GatewayObjectCommand
|
|
8
|
-
|
|
8
|
+
from simo.core.utils.serialization import deserialize_form_data
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class FleetGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
@@ -15,7 +15,7 @@ class FleetGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
|
15
15
|
periodic_tasks = (
|
|
16
16
|
('look_for_updates', 600),
|
|
17
17
|
('watch_colonels_connection', 30),
|
|
18
|
-
('push_discoveries',
|
|
18
|
+
('push_discoveries', 6),
|
|
19
19
|
)
|
|
20
20
|
|
|
21
21
|
def _on_mqtt_message(self, client, userdata, msg):
|
|
@@ -47,7 +47,16 @@ class FleetGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
|
47
47
|
colonel = Colonel.objects.get(
|
|
48
48
|
id=gw.discovery['init_data']['colonel']['val'][0]['pk']
|
|
49
49
|
)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
if gw.discovery['controller_uid'] == 'simo.fleet.controllers.TTLock':
|
|
51
|
+
GatewayObjectCommand(
|
|
52
|
+
gw, colonel, command='discover',
|
|
53
|
+
type=gw.discovery['controller_uid']
|
|
54
|
+
).publish()
|
|
55
|
+
elif gw.discovery['controller_uid'] == 'simo.fleet.controllers.DALIDevice':
|
|
56
|
+
form_cleaned_data = deserialize_form_data(gw.discovery['init_data'])
|
|
57
|
+
GatewayObjectCommand(
|
|
58
|
+
gw, colonel,
|
|
59
|
+
command=f'discover',
|
|
60
|
+
type=gw.discovery['controller_uid'],
|
|
61
|
+
i=form_cleaned_data['interface'].no
|
|
62
|
+
).publish()
|
|
@@ -7,7 +7,7 @@ def create_objects(apps, schema_editor):
|
|
|
7
7
|
Interface = apps.get_model("fleet", "Interface")
|
|
8
8
|
for i2c_i in I2CInterface.objects.filter(no__gt=0):
|
|
9
9
|
Interface.objects.create(
|
|
10
|
-
colonel=i2c_i.colonel, type='i2c',
|
|
10
|
+
no=i2c_i.no, colonel=i2c_i.colonel, type='i2c',
|
|
11
11
|
pin_a=i2c_i.scl_pin, pin_b=i2c_i.sda_pin
|
|
12
12
|
)
|
|
13
13
|
|
|
Binary file
|
simo/fleet/models.py
CHANGED
simo/fleet/socket_consumers.py
CHANGED
|
@@ -240,6 +240,8 @@ class FleetConsumer(AsyncWebsocketConsumer):
|
|
|
240
240
|
),
|
|
241
241
|
'config': comp.controller._get_colonel_config()
|
|
242
242
|
}
|
|
243
|
+
if hasattr(comp.controller, 'family'):
|
|
244
|
+
comp_config['family'] = comp.controller.family
|
|
243
245
|
slaves = [
|
|
244
246
|
s.id for s in comp.slaves.all()
|
|
245
247
|
if s.config.get('colonel') == self.colonel.id
|
|
@@ -313,16 +315,10 @@ class FleetConsumer(AsyncWebsocketConsumer):
|
|
|
313
315
|
'command': 'set_config', 'data': config
|
|
314
316
|
}, compress=True)
|
|
315
317
|
asyncio.run(send_config())
|
|
316
|
-
elif payload.get('command') == 'discover
|
|
317
|
-
print("SEND discover
|
|
318
|
-
asyncio.run(self.send_data(
|
|
319
|
-
|
|
320
|
-
}))
|
|
321
|
-
elif payload.get('command') == 'discover-dali':
|
|
322
|
-
print("SEND discover-dali command!")
|
|
323
|
-
asyncio.run(self.send_data({
|
|
324
|
-
'command': 'discover-dali', 'i': payload['interface']
|
|
325
|
-
}))
|
|
318
|
+
elif payload.get('command') == 'discover':
|
|
319
|
+
print(f"SEND discover command for {payload['type']}")
|
|
320
|
+
asyncio.run(self.send_data(payload))
|
|
321
|
+
|
|
326
322
|
elif payload.get('command') == 'finalize':
|
|
327
323
|
asyncio.run(self.send_data({
|
|
328
324
|
'command': 'finalize',
|
|
@@ -409,7 +405,7 @@ class FleetConsumer(AsyncWebsocketConsumer):
|
|
|
409
405
|
save_codes, thread_sensitive=True
|
|
410
406
|
)(data['codes'])
|
|
411
407
|
if 'fingerprints' in data and component.controller_uid == TTLock.uid:
|
|
412
|
-
def
|
|
408
|
+
def save_fingerprints(codes):
|
|
413
409
|
component.meta['fingerprints'] = codes
|
|
414
410
|
for code in codes:
|
|
415
411
|
Fingerprint.objects.get_or_create(
|
|
@@ -418,7 +414,7 @@ class FleetConsumer(AsyncWebsocketConsumer):
|
|
|
418
414
|
)
|
|
419
415
|
component.save()
|
|
420
416
|
await sync_to_async(
|
|
421
|
-
|
|
417
|
+
save_fingerprints, thread_sensitive=True
|
|
422
418
|
)(data['fingerprints'])
|
|
423
419
|
|
|
424
420
|
except Exception as e:
|
simo/fleet/views.py
CHANGED
|
@@ -42,9 +42,9 @@ class PinsSelectAutocomplete(autocomplete.Select2QuerySetView):
|
|
|
42
42
|
return qs
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
class InterfaceSelectAutocomplete(autocomplete.
|
|
45
|
+
class InterfaceSelectAutocomplete(autocomplete.Select2QuerySetView):
|
|
46
46
|
|
|
47
|
-
def
|
|
47
|
+
def get_queryset(self):
|
|
48
48
|
if not self.request.user.is_staff:
|
|
49
49
|
return Interface.objects.none()
|
|
50
50
|
|
|
Binary file
|
simo/generic/controllers.py
CHANGED
|
Binary file
|
simo/users/api.py
CHANGED
|
@@ -227,11 +227,13 @@ class FingerprintViewSet(
|
|
|
227
227
|
basename = 'fingerprints'
|
|
228
228
|
serializer_class = FingerprintSerializer
|
|
229
229
|
|
|
230
|
-
|
|
231
230
|
def get_queryset(self):
|
|
232
|
-
|
|
231
|
+
qs = Fingerprint.objects.filter(
|
|
233
232
|
Q(user=None) | Q(user__roles__instance=self.instance)
|
|
234
233
|
)
|
|
234
|
+
if 'values' in self.request.GET:
|
|
235
|
+
qs = qs.filter(value__in=self.request.GET['values'].split(','))
|
|
236
|
+
return qs
|
|
235
237
|
|
|
236
238
|
def check_can_manage_user(self, request):
|
|
237
239
|
user_role = request.user.get_role(self.instance)
|
|
@@ -43,7 +43,7 @@ simo/core/gateways.py,sha256=s_c2W0v2_te89i6LS4Nj7F2wn9UwjZXPT7pfy6SToVo,3714
|
|
|
43
43
|
simo/core/loggers.py,sha256=EBdq23gTQScVfQVH-xeP90-wII2DQFDjoROAW6ggUP4,1645
|
|
44
44
|
simo/core/managers.py,sha256=WoQ4OX3akIvoroSYji-nLVqXBSJzCiC1u_IiWkKbKmA,2413
|
|
45
45
|
simo/core/middleware.py,sha256=64PYjnyRnYf4sgMvPfR0oQqf9UEtxUwnhJe3RV6z_HI,2040
|
|
46
|
-
simo/core/models.py,sha256=
|
|
46
|
+
simo/core/models.py,sha256=j5AymbJFt5HOIOYsHJ8UUKhb1TvIoqgH0T1y3BeGJuM,19408
|
|
47
47
|
simo/core/permissions.py,sha256=UmFjGPDWtAUbaWxJsWORb2q6BREHqndv9mkSIpnmdLk,1379
|
|
48
48
|
simo/core/routing.py,sha256=X1_IHxyA-_Q7hw1udDoviVP4_FSBDl8GYETTC2zWTbY,499
|
|
49
49
|
simo/core/serializers.py,sha256=miEh2Sd47KmB0viyNlwrEG_1kxYiTUrvQQvisEoLYuA,15759
|
|
@@ -63,7 +63,7 @@ simo/core/__pycache__/api_meta.cpython-38.pyc,sha256=bdk1PG7FuRfFwcvQtF103H0kQrx
|
|
|
63
63
|
simo/core/__pycache__/app_widgets.cpython-38.pyc,sha256=9Es2wZNduzUJv-jZ_HX0-L3vqwpXWBbseEwoC5K6b-w,3465
|
|
64
64
|
simo/core/__pycache__/auto_urls.cpython-38.pyc,sha256=SVl4fF0-yiq7e9gt08jIM6_rL4JYcR0cNHzR9jCEi1M,931
|
|
65
65
|
simo/core/__pycache__/autocomplete_views.cpython-38.pyc,sha256=hJ6JILI1LqrAtpQMvxnLvljGdW1v1gpvBsD79vFkZ58,3972
|
|
66
|
-
simo/core/__pycache__/base_types.cpython-38.pyc,sha256=
|
|
66
|
+
simo/core/__pycache__/base_types.cpython-38.pyc,sha256=CasZJN42cK_ymoQgn5E4s8oOkuZJ18fVHCgN4GPuT7c,735
|
|
67
67
|
simo/core/__pycache__/context.cpython-38.pyc,sha256=MSZPDhqMhCpUuBJl3HCIBHZA3BntYeP8RAnQcdqAH9k,1278
|
|
68
68
|
simo/core/__pycache__/controllers.cpython-38.pyc,sha256=-NjuX7iGheE_ZMqkZ6g4ZnnVjdUnFCTlH0awAJxZt2Y,24110
|
|
69
69
|
simo/core/__pycache__/dynamic_settings.cpython-38.pyc,sha256=ELu06Hub4DOidja71ybvD3ZM4HdXiyZjNJrZfnXZXNA,2476
|
|
@@ -74,7 +74,7 @@ simo/core/__pycache__/gateways.cpython-38.pyc,sha256=XBiwMfBkjoQ2re6jvADJOwK0_0A
|
|
|
74
74
|
simo/core/__pycache__/loggers.cpython-38.pyc,sha256=Z-cdQnC6XlIonPV4Sl4E52tP4NMEdPAiHK0cFaIL7I8,1623
|
|
75
75
|
simo/core/__pycache__/managers.cpython-38.pyc,sha256=5vstOMfm997CZBBkaSiaS7EojhLTWZlbeA_EQ8u-yfg,2554
|
|
76
76
|
simo/core/__pycache__/middleware.cpython-38.pyc,sha256=bGOFJNEhJeLbpsZp8LYn1VA3paLF5HULHQ6IFKa7Juc,2022
|
|
77
|
-
simo/core/__pycache__/models.cpython-38.pyc,sha256=
|
|
77
|
+
simo/core/__pycache__/models.cpython-38.pyc,sha256=Gm36LWRxswvWiB3Wz0F7g32ZVXugh7chSSBz1lgBPZs,16995
|
|
78
78
|
simo/core/__pycache__/permissions.cpython-38.pyc,sha256=uygjPbfRQiEzyo5-McCxsuMDJLbDYO_TLu55U7bJbR0,1809
|
|
79
79
|
simo/core/__pycache__/routing.cpython-38.pyc,sha256=3T3FPJ8Cn99xZCGvMyg2xjl7al-Shm9CelbSpkJtNP8,599
|
|
80
80
|
simo/core/__pycache__/serializers.cpython-38.pyc,sha256=tJf8jV9pPJXnJjUPXCc103wQxC5ZrZaC9SlIR41JomQ,15707
|
|
@@ -10165,32 +10165,34 @@ simo/fleet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
10165
10165
|
simo/fleet/admin.py,sha256=aQulOPtrIQUKj8WvA4GfINfqVA52fcU72yK2hVlcmJ0,5681
|
|
10166
10166
|
simo/fleet/api.py,sha256=Hxn84xI-Q77HxjINgRbjSJQOv9jii4OL20LxK0VSrS8,2499
|
|
10167
10167
|
simo/fleet/auto_urls.py,sha256=X04oKJWA48wFW5iXg3PPROY2KDdHn_a99orQSE28QC4,518
|
|
10168
|
+
simo/fleet/base_types.py,sha256=wL9RVkHr0gA7HI1wZq0pruGEIgvQqpfnCL4cC3ywsvw,102
|
|
10168
10169
|
simo/fleet/ble.py,sha256=eHA_9ABjbmH1vUVCv9hiPXQL2GZZSEVwfO0xyI1S0nI,1081
|
|
10169
|
-
simo/fleet/controllers.py,sha256=
|
|
10170
|
-
simo/fleet/forms.py,sha256=
|
|
10171
|
-
simo/fleet/gateways.py,sha256=
|
|
10170
|
+
simo/fleet/controllers.py,sha256=LF5-Mst617BuZHyRErk_6diAk85pa5uelGoTelBY184,17743
|
|
10171
|
+
simo/fleet/forms.py,sha256=lWJ9luZiRJD4yLQCdCMmkvezk-vY3yVb3q7Y5C4r9qc,35649
|
|
10172
|
+
simo/fleet/gateways.py,sha256=EbSxv1DGSuv8MT7MmpZxKgV041umOteFW2Xo4LybzWI,2284
|
|
10172
10173
|
simo/fleet/managers.py,sha256=XOpDOA9L-f_550TNSyXnJbun2EmtGz1TenVTMlUSb8E,807
|
|
10173
|
-
simo/fleet/models.py,sha256=
|
|
10174
|
+
simo/fleet/models.py,sha256=J-rnn7Ew-7s3646NNRVY947Sbz21mUD_nBHtuHAKXds,14160
|
|
10174
10175
|
simo/fleet/routing.py,sha256=cofGsVWXMfPDwsJ6HM88xxtRxHwERhJ48Xyxc8mxg5o,149
|
|
10175
10176
|
simo/fleet/serializers.py,sha256=zEpXAXxjk4Rf1JhlNnLTrs20qJggqjvIySbeHVo4Tt4,1505
|
|
10176
|
-
simo/fleet/socket_consumers.py,sha256=
|
|
10177
|
+
simo/fleet/socket_consumers.py,sha256=e_PtRWLPIrJxNBhtQIAC7idk1oaV-LVZWQchz5iffUk,19680
|
|
10177
10178
|
simo/fleet/utils.py,sha256=2gcjbwQawsGw2edr_wm9q6XacGpYqO-gd4BF1t0Hg6U,3511
|
|
10178
|
-
simo/fleet/views.py,sha256=
|
|
10179
|
+
simo/fleet/views.py,sha256=YKkcf8KcLgiPjr-brIHvu5yr1zZUIs8aytAgwdo49Pg,1694
|
|
10179
10180
|
simo/fleet/__pycache__/__init__.cpython-38.pyc,sha256=pIZE7EL6-cuJ3pQtaSwjKLrKLsTYelp1k9sRhXKLh6s,159
|
|
10180
10181
|
simo/fleet/__pycache__/admin.cpython-38.pyc,sha256=Tw3g9JKzJ3ICjWnHQedU8qV7RSZeJL81jSYpvTLK5bM,5798
|
|
10181
10182
|
simo/fleet/__pycache__/api.cpython-38.pyc,sha256=rL9fb7cCQatyFvXyKmlNOKmxVo8vHYeYhfSiAgchyAs,3110
|
|
10182
10183
|
simo/fleet/__pycache__/auto_urls.cpython-38.pyc,sha256=SqyTuaz_kEBvx-bL46SclsZEEP5RFh6U6TGKyXDdiOE,565
|
|
10184
|
+
simo/fleet/__pycache__/base_types.cpython-38.pyc,sha256=deyPwjpT6xZiFxBGFnj5b7R-lbdOTh2krgpJhrcGVhc,274
|
|
10183
10185
|
simo/fleet/__pycache__/ble.cpython-38.pyc,sha256=Nrof9w7cm4OlpFWHeVnmvvanh2_oF9oQ3TknJiV93-0,1267
|
|
10184
|
-
simo/fleet/__pycache__/controllers.cpython-38.pyc,sha256=
|
|
10185
|
-
simo/fleet/__pycache__/forms.cpython-38.pyc,sha256=
|
|
10186
|
-
simo/fleet/__pycache__/gateways.cpython-38.pyc,sha256=
|
|
10186
|
+
simo/fleet/__pycache__/controllers.cpython-38.pyc,sha256=2XWWfU0zkbha_MMPD0KbSOnh9CHUNLcsI-VKmr8Z7e0,15559
|
|
10187
|
+
simo/fleet/__pycache__/forms.cpython-38.pyc,sha256=pHgx8ulx_2v0L0bkUHaW13Tn9KcfOP6ROhgHXPVvKJE,25510
|
|
10188
|
+
simo/fleet/__pycache__/gateways.cpython-38.pyc,sha256=xg7fW5JusYwl6epn5nEjxQJlFOyQ18SVybOaRBcpwl8,2418
|
|
10187
10189
|
simo/fleet/__pycache__/managers.cpython-38.pyc,sha256=8uz-xpUiqbGDgXIZ_XRZtFb-Tju6NGxflGg-Ee4Yo6k,1310
|
|
10188
|
-
simo/fleet/__pycache__/models.cpython-38.pyc,sha256=
|
|
10190
|
+
simo/fleet/__pycache__/models.cpython-38.pyc,sha256=S9pPqRjIxASXahoIOkkjQX7cBwjkdu4d2nXMju0-Cf8,12283
|
|
10189
10191
|
simo/fleet/__pycache__/routing.cpython-38.pyc,sha256=aPrCmxFKVyB8R8ZbJDwdPdFfvT7CvobovvZeq_mqRgY,314
|
|
10190
10192
|
simo/fleet/__pycache__/serializers.cpython-38.pyc,sha256=yuY2H7jcboQGZdjb5WIsgNHXFhI9IPMUrEu9NgSiXNo,2452
|
|
10191
|
-
simo/fleet/__pycache__/socket_consumers.cpython-38.pyc,sha256=
|
|
10193
|
+
simo/fleet/__pycache__/socket_consumers.cpython-38.pyc,sha256=dAq59u6jcxHZ3W9dR0HSp_kfiZUhMPVja0SqJ38crhk,14399
|
|
10192
10194
|
simo/fleet/__pycache__/utils.cpython-38.pyc,sha256=dTuvW9MnhUycwdCc6eHYfHsMlvZw-CmEWXWYu18X8Uw,1955
|
|
10193
|
-
simo/fleet/__pycache__/views.cpython-38.pyc,sha256=
|
|
10195
|
+
simo/fleet/__pycache__/views.cpython-38.pyc,sha256=7hhRBlf6Vczg0TTdwTE5Hc5B-F7VcvFg1iS6mfs-fgo,1790
|
|
10194
10196
|
simo/fleet/migrations/0001_initial.py,sha256=lce8nkD8Sz6pYr-XJSpDm4CMDuB6TA__WtnHpIp-eA4,1326
|
|
10195
10197
|
simo/fleet/migrations/0002_auto_20220422_0743.py,sha256=sFOfAjnQOzcJjE8lHrrHgTaGilJNYswMdXphgVzUZqY,825
|
|
10196
10198
|
simo/fleet/migrations/0003_auto_20220422_0752.py,sha256=VcH7DyMAniEwT76hDVofS8FTNpM3nxz_J9AC2zKHDSA,543
|
|
@@ -10223,7 +10225,7 @@ simo/fleet/migrations/0029_alter_i2cinterface_scl_pin_and_more.py,sha256=aquymc1
|
|
|
10223
10225
|
simo/fleet/migrations/0030_colonelpin_label_alter_colonel_type.py,sha256=5T5bmQxPZrG0UseCLd7ssV-AeFF3O4T_DFxLu3whSqg,706
|
|
10224
10226
|
simo/fleet/migrations/0031_alter_colonel_type.py,sha256=Kv_Gld-X0NZ7d2P9WBXfIlhq4iPH1_NnzDrPyy9_Pos,522
|
|
10225
10227
|
simo/fleet/migrations/0032_auto_20240415_0736.py,sha256=yBT48pIfDBm7J1Y3LrvNtmihRbwEXjmBGBB1ghc2z5Y,1800
|
|
10226
|
-
simo/fleet/migrations/0033_auto_20240415_0736.py,sha256=
|
|
10228
|
+
simo/fleet/migrations/0033_auto_20240415_0736.py,sha256=3ysmu-fkzwY_7l4tDIHEylcoqXGdW_KMKHs1J3_0i5w,771
|
|
10227
10229
|
simo/fleet/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10228
10230
|
simo/fleet/migrations/__pycache__/0001_initial.cpython-38.pyc,sha256=9kc1UyMEYkRNVnZ7iwZbiW1t3qWXROvWrI2G1BdzIaA,1250
|
|
10229
10231
|
simo/fleet/migrations/__pycache__/0002_auto_20220422_0743.cpython-38.pyc,sha256=8oxhGb7rL8QYKlBLU3pOYcd8aHeQWDB9I8awkK04mXg,841
|
|
@@ -10257,12 +10259,12 @@ simo/fleet/migrations/__pycache__/0029_alter_i2cinterface_scl_pin_and_more.cpyth
|
|
|
10257
10259
|
simo/fleet/migrations/__pycache__/0030_colonelpin_label_alter_colonel_type.cpython-38.pyc,sha256=sfglSDxXLKJ0qE8Dl3MYjv5hbszpDtb9CDxatoEzPSw,853
|
|
10258
10260
|
simo/fleet/migrations/__pycache__/0031_alter_colonel_type.cpython-38.pyc,sha256=zXX254ZgEE4uSV8xnLdH9DM3qy-ICmbrT05i0Q287bU,733
|
|
10259
10261
|
simo/fleet/migrations/__pycache__/0032_auto_20240415_0736.cpython-38.pyc,sha256=QD3JNIDQhzseXKLRYysYY3Q9_vDaurIhlWBcri83FMw,1655
|
|
10260
|
-
simo/fleet/migrations/__pycache__/0033_auto_20240415_0736.cpython-38.pyc,sha256=
|
|
10262
|
+
simo/fleet/migrations/__pycache__/0033_auto_20240415_0736.cpython-38.pyc,sha256=zN3KrYHzE40Wfnt48zp7AGCIa8Jj9-fPXxo3adZIxwo,1046
|
|
10261
10263
|
simo/fleet/migrations/__pycache__/__init__.cpython-38.pyc,sha256=5k1KW0jeSDzw6RnVPRq4CaO13Lg7M0F-pxA_gqqZ6Mg,170
|
|
10262
10264
|
simo/generic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10263
10265
|
simo/generic/app_widgets.py,sha256=E_pnpA1hxMIhenRCrHoQ5cik06jm2BAHCkl_eo-OudU,1264
|
|
10264
10266
|
simo/generic/base_types.py,sha256=djymox_boXTHX1BTTCLXrCH7ED-uAsV_idhaDOc3OLI,409
|
|
10265
|
-
simo/generic/controllers.py,sha256=
|
|
10267
|
+
simo/generic/controllers.py,sha256=Mn4jmOx-1Yb5rAZb9ZcfMcYBMf7r61NQV2p8JgxbYvQ,51675
|
|
10266
10268
|
simo/generic/forms.py,sha256=p-gzH1z7J0CV8bKMmWTQluzpYmgc7fF1aEHL7eL-fJI,20075
|
|
10267
10269
|
simo/generic/gateways.py,sha256=BEHjNZ2VpblXxpuADZzRs4IAO7fsj2Heb2peGXFXNec,15156
|
|
10268
10270
|
simo/generic/models.py,sha256=d00Q-UXtt7mG9MdPpZ3mXnxKjwlTI2FgCEklZpGBk7s,3629
|
|
@@ -10271,7 +10273,7 @@ simo/generic/socket_consumers.py,sha256=NfTQGYtVAc864IoogZRxf_0xpDPM0eMCWn0SlKA5
|
|
|
10271
10273
|
simo/generic/__pycache__/__init__.cpython-38.pyc,sha256=mLu54WS9KIl-pHwVCBKpsDFIlOqml--JsOVzAUHg6cU,161
|
|
10272
10274
|
simo/generic/__pycache__/app_widgets.cpython-38.pyc,sha256=0IoKRG9n1tkNRRkrqAeOQwWBPd_33u98JBcVtMVVCio,2374
|
|
10273
10275
|
simo/generic/__pycache__/base_types.cpython-38.pyc,sha256=ptw6axyAqemZA35oa6vzr7EihzvbhW9w7Y-G6kfDedU,555
|
|
10274
|
-
simo/generic/__pycache__/controllers.cpython-38.pyc,sha256=
|
|
10276
|
+
simo/generic/__pycache__/controllers.cpython-38.pyc,sha256=3U3W-EgpKdqh7MN94ZaoCEGvY4SSq2zsTptJoZbysgM,32795
|
|
10275
10277
|
simo/generic/__pycache__/forms.cpython-38.pyc,sha256=Uvh-YQxcN-0RCinRi13fyITM1Jxm6FwYQyXs3OLNruA,15699
|
|
10276
10278
|
simo/generic/__pycache__/gateways.cpython-38.pyc,sha256=43zzltUplgyKIBN9Knk-YNstFgm2Mjk2CvW6vwuzeio,11582
|
|
10277
10279
|
simo/generic/__pycache__/models.cpython-38.pyc,sha256=ItjBjJaioJttzSUJsHCKV4xiqH6QX90kRw1C_Xx7mMk,3065
|
|
@@ -10349,7 +10351,7 @@ simo/notifications/migrations/__pycache__/0002_notification_instance.cpython-38.
|
|
|
10349
10351
|
simo/notifications/migrations/__pycache__/__init__.cpython-38.pyc,sha256=YMBRHVon2nWDtIUbghckjnC12sIg_ykPWhV5aM0tto4,178
|
|
10350
10352
|
simo/users/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10351
10353
|
simo/users/admin.py,sha256=IY501Ewbn8KkBJ3ryBPelHU37ac2--dd6NNGsmYQ6FE,6887
|
|
10352
|
-
simo/users/api.py,sha256=
|
|
10354
|
+
simo/users/api.py,sha256=w5nmU-to1-ULnPcRKDpa6uaOUwWfbHMTQKfmSJx3qPg,9185
|
|
10353
10355
|
simo/users/auth_backends.py,sha256=I5pnaTa20-Lxfw_dFG8471xDITb0_fQl1PVhJalp5vU,3992
|
|
10354
10356
|
simo/users/auto_urls.py,sha256=lcJvteBsbHQMJieZpDz-63tDYejLApqsW3CUnDakd7k,272
|
|
10355
10357
|
simo/users/dynamic_settings.py,sha256=sEIsi4yJw3kH46Jq_aOkSuK7QTfQACGUE-lkyBogCaM,570
|
|
@@ -10364,7 +10366,7 @@ simo/users/utils.py,sha256=uOyCNHQJ_tpn054L89keuQwKAzFd0Y2VSUmDVPq6oaY,1335
|
|
|
10364
10366
|
simo/users/views.py,sha256=dOQVvmlHG7ihWKJLFUBcqKOA0UDctlMKR0pTc36JZqg,3487
|
|
10365
10367
|
simo/users/__pycache__/__init__.cpython-38.pyc,sha256=9otuYxq331c4lGy0DR8pigaPpzq0lQ4nrNLhlYiFAF0,159
|
|
10366
10368
|
simo/users/__pycache__/admin.cpython-38.pyc,sha256=T7gzc4xv2JIh3nkJEr4aRZAzyaaweX4m9JXJ-xzwsd0,7705
|
|
10367
|
-
simo/users/__pycache__/api.cpython-38.pyc,sha256=
|
|
10369
|
+
simo/users/__pycache__/api.cpython-38.pyc,sha256=rFjlT4o4Ossop70GlljQPTm1-_TH-omnr8aDvOnMgH8,7981
|
|
10368
10370
|
simo/users/__pycache__/auth_backends.cpython-38.pyc,sha256=MuOieBIXt6lrDx83-UQtdDyI_U8kE3pU9XR4yFLKBnE,3007
|
|
10369
10371
|
simo/users/__pycache__/auto_urls.cpython-38.pyc,sha256=K-3sz2h-cEitoflSmZk1t0eUg5mQMMGLNZFREVwG7_o,430
|
|
10370
10372
|
simo/users/__pycache__/dynamic_settings.cpython-38.pyc,sha256=6F8JBjZkHykySnmZjNEzjS0ijbmPdcp9yUAZ5kqq_Fo,864
|
|
@@ -10437,8 +10439,8 @@ simo/users/templates/invitations/expired_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCe
|
|
|
10437
10439
|
simo/users/templates/invitations/expired_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10438
10440
|
simo/users/templates/invitations/taken_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10439
10441
|
simo/users/templates/invitations/taken_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10440
|
-
simo-2.0.
|
|
10441
|
-
simo-2.0.
|
|
10442
|
-
simo-2.0.
|
|
10443
|
-
simo-2.0.
|
|
10444
|
-
simo-2.0.
|
|
10442
|
+
simo-2.0.9.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
|
|
10443
|
+
simo-2.0.9.dist-info/METADATA,sha256=IBLtc0JzeJ7o-RPgd4LblELV30WxBumyHeejuRcT7EE,1699
|
|
10444
|
+
simo-2.0.9.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
10445
|
+
simo-2.0.9.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
|
|
10446
|
+
simo-2.0.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|