simo 2.0.23__py3-none-any.whl → 2.0.25__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__/admin.cpython-38.pyc +0 -0
- simo/core/__pycache__/api.cpython-38.pyc +0 -0
- simo/core/__pycache__/controllers.cpython-38.pyc +0 -0
- simo/core/__pycache__/middleware.cpython-38.pyc +0 -0
- simo/core/__pycache__/models.cpython-38.pyc +0 -0
- simo/core/__pycache__/permissions.cpython-38.pyc +0 -0
- simo/core/admin.py +1 -0
- simo/core/api.py +21 -17
- simo/core/controllers.py +5 -1
- simo/core/middleware.py +1 -0
- simo/core/models.py +4 -2
- simo/core/permissions.py +15 -9
- simo/core/utils/__pycache__/json.cpython-38.pyc +0 -0
- simo/core/utils/json.py +20 -0
- simo/fleet/__pycache__/forms.cpython-38.pyc +0 -0
- simo/fleet/forms.py +10 -2
- simo/users/__pycache__/admin.cpython-38.pyc +0 -0
- simo/users/admin.py +0 -5
- {simo-2.0.23.dist-info → simo-2.0.25.dist-info}/METADATA +1 -1
- {simo-2.0.23.dist-info → simo-2.0.25.dist-info}/RECORD +23 -21
- {simo-2.0.23.dist-info → simo-2.0.25.dist-info}/LICENSE.md +0 -0
- {simo-2.0.23.dist-info → simo-2.0.25.dist-info}/WHEEL +0 -0
- {simo-2.0.23.dist-info → simo-2.0.25.dist-info}/top_level.txt +0 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
simo/core/admin.py
CHANGED
|
@@ -60,6 +60,7 @@ class IconAdmin(admin.ModelAdmin):
|
|
|
60
60
|
@admin.register(Instance)
|
|
61
61
|
class InstanceAdmin(admin.ModelAdmin):
|
|
62
62
|
list_display = 'name', 'timezone', 'uid'
|
|
63
|
+
exclude = 'learn_fingerprints_start', 'learn_fingerprints'
|
|
63
64
|
|
|
64
65
|
|
|
65
66
|
def has_module_permission(self, request):
|
simo/core/api.py
CHANGED
|
@@ -2,11 +2,13 @@ import datetime
|
|
|
2
2
|
from calendar import monthrange
|
|
3
3
|
import pytz
|
|
4
4
|
import time
|
|
5
|
-
|
|
5
|
+
import json
|
|
6
|
+
from django.db.models import Q
|
|
6
7
|
from django.utils.translation import gettext_lazy as _
|
|
7
8
|
from django.utils import timezone
|
|
8
9
|
from django.http import HttpResponse, Http404
|
|
9
10
|
from simo.core.utils.helpers import get_self_ip, search_queryset
|
|
11
|
+
from rest_framework import status
|
|
10
12
|
from rest_framework.pagination import PageNumberPagination
|
|
11
13
|
from rest_framework import viewsets
|
|
12
14
|
from django_filters.rest_framework import DjangoFilterBackend
|
|
@@ -14,6 +16,7 @@ from rest_framework.decorators import action
|
|
|
14
16
|
from rest_framework.response import Response as RESTResponse
|
|
15
17
|
from rest_framework.exceptions import ValidationError as APIValidationError
|
|
16
18
|
from simo.core.utils.config_values import ConfigException
|
|
19
|
+
from simo.core.utils.json import restore_json
|
|
17
20
|
from .models import (
|
|
18
21
|
Instance, Category, Zone, Component, Icon, ComponentHistory,
|
|
19
22
|
HistoryAggregate, Gateway
|
|
@@ -35,11 +38,7 @@ class InstanceMixin:
|
|
|
35
38
|
slug=self.request.resolver_match.kwargs.get('instance_slug')
|
|
36
39
|
)
|
|
37
40
|
except Instance.DoesNotExist:
|
|
38
|
-
|
|
39
|
-
f"Instance {self.request.resolver_match.kwargs.get('instance_slug')} "
|
|
40
|
-
"is not found on this SIMO.io hub!",
|
|
41
|
-
status=400
|
|
42
|
-
)
|
|
41
|
+
raise Http404()
|
|
43
42
|
return super().dispatch(request, *args, **kwargs)
|
|
44
43
|
|
|
45
44
|
def get_serializer_context(self):
|
|
@@ -159,7 +158,9 @@ def get_components_queryset(instance, user):
|
|
|
159
158
|
return qs
|
|
160
159
|
|
|
161
160
|
|
|
162
|
-
class ComponentViewSet(
|
|
161
|
+
class ComponentViewSet(
|
|
162
|
+
InstanceMixin, viewsets.ModelViewSet
|
|
163
|
+
):
|
|
163
164
|
url = 'core/components'
|
|
164
165
|
basename = 'components'
|
|
165
166
|
serializer_class = ComponentSerializer
|
|
@@ -185,11 +186,14 @@ class ComponentViewSet(InstanceMixin, viewsets.ModelViewSet):
|
|
|
185
186
|
|
|
186
187
|
def perform_controller_method(self, json_data, component):
|
|
187
188
|
for method_name, param in json_data.items():
|
|
189
|
+
if method_name in ('id', 'secret'):
|
|
190
|
+
continue
|
|
188
191
|
if not hasattr(component, method_name):
|
|
189
192
|
raise APIValidationError(
|
|
190
193
|
_('"%s" method not found on controller') % method_name,
|
|
191
194
|
code=400
|
|
192
195
|
)
|
|
196
|
+
print("VARYSIM: ", method_name, param, type(param))
|
|
193
197
|
call = getattr(component, method_name)
|
|
194
198
|
|
|
195
199
|
if not isinstance(param, list) and not isinstance(param, dict):
|
|
@@ -209,10 +213,11 @@ class ComponentViewSet(InstanceMixin, viewsets.ModelViewSet):
|
|
|
209
213
|
|
|
210
214
|
return RESTResponse(result)
|
|
211
215
|
|
|
216
|
+
# TODO: remove post when app is updated for all users
|
|
212
217
|
@action(detail=True, methods=['post'])
|
|
213
218
|
def subcomponent(self, request, pk=None, *args, **kwargs):
|
|
214
219
|
component = self.get_object()
|
|
215
|
-
json_data = request.data
|
|
220
|
+
json_data = restore_json(request.data.dict())
|
|
216
221
|
subcomponent_id = json_data.pop('id', -1)
|
|
217
222
|
try:
|
|
218
223
|
subcomponent = component.slaves.get(pk=subcomponent_id)
|
|
@@ -232,15 +237,18 @@ class ComponentViewSet(InstanceMixin, viewsets.ModelViewSet):
|
|
|
232
237
|
@action(detail=True, methods=['post'])
|
|
233
238
|
def controller(self, request, pk=None, *args, **kwargs):
|
|
234
239
|
component = self.get_object()
|
|
235
|
-
return self.perform_controller_method(
|
|
240
|
+
return self.perform_controller_method(
|
|
241
|
+
restore_json(request.data.dict()), component
|
|
242
|
+
)
|
|
236
243
|
|
|
237
244
|
@action(detail=False, methods=['post'])
|
|
238
245
|
def control(self, request, *args, **kwargs):
|
|
239
|
-
|
|
246
|
+
request_data = restore_json(request.data.dict())
|
|
247
|
+
component = self.get_queryset().filter(id=request_data.pop('id', 0)).first()
|
|
240
248
|
if not component:
|
|
241
249
|
raise Http404()
|
|
242
250
|
self.check_object_permissions(self.request, component)
|
|
243
|
-
return self.perform_controller_method(
|
|
251
|
+
return self.perform_controller_method(request_data, component)
|
|
244
252
|
|
|
245
253
|
@action(detail=True, methods=['get'])
|
|
246
254
|
def value_history(self, request, pk=None, *args, **kwargs):
|
|
@@ -531,9 +539,7 @@ class StatesViewSet(InstanceMixin, viewsets.GenericViewSet):
|
|
|
531
539
|
).exclude(email__in=('system@simo.io', 'device@simo.io'))
|
|
532
540
|
component_values = get_components_queryset(
|
|
533
541
|
self.instance, request.user
|
|
534
|
-
).filter(zone__instance=self.instance).
|
|
535
|
-
Prefetch('history', queryset=ComponentHistory.objects.filter())
|
|
536
|
-
).values(
|
|
542
|
+
).filter(zone__instance=self.instance).values(
|
|
537
543
|
'id', 'value', 'last_change', 'arm_status', 'battery_level',
|
|
538
544
|
'alive', 'meta'
|
|
539
545
|
)
|
|
@@ -622,6 +628,4 @@ class RunningDiscoveries(InstanceMixin, viewsets.GenericViewSet):
|
|
|
622
628
|
if 'controller_uid' in request.GET:
|
|
623
629
|
for gateway in gateways:
|
|
624
630
|
gateway.retry_discovery()
|
|
625
|
-
return RESTResponse(self.get_data(gateways))
|
|
626
|
-
|
|
627
|
-
|
|
631
|
+
return RESTResponse(self.get_data(gateways))
|
simo/core/controllers.py
CHANGED
|
@@ -187,6 +187,8 @@ class ControllerBase(ABC):
|
|
|
187
187
|
bulk_send_map = {self.component: value}
|
|
188
188
|
for slave in self.component.slaves.all():
|
|
189
189
|
bulk_send_map[slave] = value
|
|
190
|
+
|
|
191
|
+
print("BULK SEND MAP: ", bulk_send_map)
|
|
190
192
|
from .models import Component
|
|
191
193
|
Component.objects.bulk_send(bulk_send_map)
|
|
192
194
|
return
|
|
@@ -652,7 +654,9 @@ class MultiSwitchBase(ControllerBase):
|
|
|
652
654
|
if not(0 < number_of_values < 16):
|
|
653
655
|
raise ValidationError("Wrong number of values")
|
|
654
656
|
if number_of_values == 1:
|
|
655
|
-
if
|
|
657
|
+
if isinstance(value, int):
|
|
658
|
+
value = bool(value)
|
|
659
|
+
elif not isinstance(value, bool):
|
|
656
660
|
raise ValidationError("Must be a boolean value")
|
|
657
661
|
else:
|
|
658
662
|
if not isinstance(value, list):
|
simo/core/middleware.py
CHANGED
simo/core/models.py
CHANGED
|
@@ -80,7 +80,7 @@ class Instance(DirtyFieldsMixin, models.Model, SimoAdminMixin):
|
|
|
80
80
|
name = models.CharField(max_length=100, db_index=True, unique=True)
|
|
81
81
|
slug = models.CharField(max_length=100, db_index=True, unique=True)
|
|
82
82
|
cover_image = models.ImageField(
|
|
83
|
-
upload_to='hub_covers', null=True, blank=True
|
|
83
|
+
name='cover_image', upload_to='hub_covers', null=True, blank=True
|
|
84
84
|
)
|
|
85
85
|
cover_image_synced = models.BooleanField(default=False)
|
|
86
86
|
secret_key = models.CharField(max_length=100, blank=True)
|
|
@@ -100,7 +100,8 @@ class Instance(DirtyFieldsMixin, models.Model, SimoAdminMixin):
|
|
|
100
100
|
|
|
101
101
|
)
|
|
102
102
|
indoor_climate_sensor = models.ForeignKey(
|
|
103
|
-
'Component', null=True, blank=True, on_delete=models.SET_NULL
|
|
103
|
+
'Component', null=True, blank=True, on_delete=models.SET_NULL,
|
|
104
|
+
limit_choices_to={'base_type__in': ['numeric-sensor', 'multi-sensor']}
|
|
104
105
|
)
|
|
105
106
|
history_days = models.PositiveIntegerField(
|
|
106
107
|
default=90, help_text="How many days of component history do we keep?"
|
|
@@ -128,6 +129,7 @@ class Instance(DirtyFieldsMixin, models.Model, SimoAdminMixin):
|
|
|
128
129
|
def components(self):
|
|
129
130
|
return Component.objects.filter(zone__instance=self)
|
|
130
131
|
|
|
132
|
+
|
|
131
133
|
class Zone(DirtyFieldsMixin, models.Model, SimoAdminMixin):
|
|
132
134
|
instance = models.ForeignKey(Instance, on_delete=models.CASCADE)
|
|
133
135
|
name = models.CharField(_('name'), max_length=40)
|
simo/core/permissions.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from rest_framework.permissions import BasePermission, SAFE_METHODS, IsAuthenticated
|
|
2
|
+
from django.http import Http404
|
|
2
3
|
from .models import Instance, Category, Zone
|
|
3
4
|
|
|
4
5
|
|
|
@@ -13,7 +14,7 @@ class InstancePermission(BasePermission):
|
|
|
13
14
|
slug=request.resolver_match.kwargs.get('instance_slug')
|
|
14
15
|
).first()
|
|
15
16
|
if not instance:
|
|
16
|
-
|
|
17
|
+
raise Http404()
|
|
17
18
|
|
|
18
19
|
if instance not in request.user.instances:
|
|
19
20
|
return False
|
|
@@ -35,6 +36,17 @@ class InstanceSuperuserCanEdit(BasePermission):
|
|
|
35
36
|
message = "Only superusers are allowed to perform this action."
|
|
36
37
|
|
|
37
38
|
def has_object_permission(self, request, view, obj):
|
|
39
|
+
'''
|
|
40
|
+
in this permission we only care about:
|
|
41
|
+
POST - new object can be created
|
|
42
|
+
PUT - create new object
|
|
43
|
+
PATCH - modify an object
|
|
44
|
+
DELETE - delete an oject
|
|
45
|
+
'''
|
|
46
|
+
# TODO: allow object creation only with PUT method, this way proper permissions system will be guaranteed.
|
|
47
|
+
|
|
48
|
+
if request.method in SAFE_METHODS + ('POST',):
|
|
49
|
+
return True
|
|
38
50
|
|
|
39
51
|
# allow deleting only empty categories and zones
|
|
40
52
|
if type(obj) in (Zone, Category) and request.method == 'DELETE'\
|
|
@@ -46,29 +58,23 @@ class InstanceSuperuserCanEdit(BasePermission):
|
|
|
46
58
|
user_role = request.user.get_role(view.instance)
|
|
47
59
|
if user_role.is_superuser:
|
|
48
60
|
return True
|
|
49
|
-
|
|
61
|
+
|
|
62
|
+
return False
|
|
50
63
|
|
|
51
64
|
|
|
52
65
|
class ComponentPermission(BasePermission):
|
|
53
66
|
message = "You do not have permission to do this on this component."
|
|
54
67
|
|
|
55
|
-
# TODO: clean this up once the app is tested and running 100% correctly for at least 6 months.
|
|
56
68
|
def has_object_permission(self, request, view, obj):
|
|
57
|
-
print(f"Check permission of {request.user} on {obj}")
|
|
58
69
|
if request.method in SAFE_METHODS:
|
|
59
|
-
print("THIS IS SAFE METHOD!")
|
|
60
70
|
return True
|
|
61
71
|
if request.user.is_master:
|
|
62
|
-
print("USER IS MASTER!")
|
|
63
72
|
return True
|
|
64
73
|
user_role = request.user.get_role(view.instance)
|
|
65
74
|
if user_role.is_superuser:
|
|
66
|
-
print("USER IS SUPERUSER!")
|
|
67
75
|
return True
|
|
68
76
|
if request.method == 'POST' and user_role.component_permissions.filter(
|
|
69
77
|
write=True, component=obj
|
|
70
78
|
).count():
|
|
71
|
-
print("USER HAS RIGHT TO DO THIS!")
|
|
72
79
|
return True
|
|
73
|
-
print("USER IS NOT ALLOWED TO DO THIS!")
|
|
74
80
|
return False
|
|
Binary file
|
simo/core/utils/json.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
|
|
2
|
+
def restore_json(data):
|
|
3
|
+
for key, val in data.items():
|
|
4
|
+
if not isinstance(val, str):
|
|
5
|
+
continue
|
|
6
|
+
try:
|
|
7
|
+
data[key] = int(val)
|
|
8
|
+
continue
|
|
9
|
+
except:
|
|
10
|
+
pass
|
|
11
|
+
try:
|
|
12
|
+
data[key] = float(val)
|
|
13
|
+
continue
|
|
14
|
+
except:
|
|
15
|
+
pass
|
|
16
|
+
if val.lower() == 'true':
|
|
17
|
+
data[key] = True
|
|
18
|
+
elif val.lower() == 'false':
|
|
19
|
+
data[key] = False
|
|
20
|
+
return data
|
|
Binary file
|
simo/fleet/forms.py
CHANGED
|
@@ -701,6 +701,14 @@ class ColonelRGBLightConfigForm(ColonelComponentForm):
|
|
|
701
701
|
help_text="Custom addressable led strip timing (T0H, T0L, T1H, T1L). <br>"
|
|
702
702
|
"For example SK6812 is: (300, 900, 600, 600)"
|
|
703
703
|
)
|
|
704
|
+
sustain_color = forms.BooleanField(
|
|
705
|
+
initial=True, required=False,
|
|
706
|
+
help_text="Recommended to leave this enabled. <br>"
|
|
707
|
+
"Addressible signal wire might pick up electrical "
|
|
708
|
+
"noise from it's surroundings which might cause color change "
|
|
709
|
+
"on random pixels. Colonel will send color update every 20s "
|
|
710
|
+
"to sustain last set color if this is enabled. "
|
|
711
|
+
)
|
|
704
712
|
controls = FormsetField(
|
|
705
713
|
formset_factory(
|
|
706
714
|
ControlPinForm, can_delete=True, can_order=True, extra=0, max_num=2
|
|
@@ -779,7 +787,7 @@ class DualMotorValveForm(ColonelComponentForm):
|
|
|
779
787
|
)
|
|
780
788
|
open_duration = forms.FloatField(
|
|
781
789
|
required=True, min_value=0.01, max_value=1000000000,
|
|
782
|
-
help_text="Time in seconds to open."
|
|
790
|
+
initial=2, help_text="Time in seconds to open."
|
|
783
791
|
)
|
|
784
792
|
close_pin = ColonelPinChoiceField(
|
|
785
793
|
queryset=ColonelPin.objects.filter(output=True),
|
|
@@ -797,7 +805,7 @@ class DualMotorValveForm(ColonelComponentForm):
|
|
|
797
805
|
)
|
|
798
806
|
close_duration = forms.FloatField(
|
|
799
807
|
required=True, min_value=0.01, max_value=1000000000,
|
|
800
|
-
help_text="Time in seconds to close."
|
|
808
|
+
initial=10, help_text="Time in seconds to close."
|
|
801
809
|
)
|
|
802
810
|
|
|
803
811
|
|
|
Binary file
|
simo/users/admin.py
CHANGED
|
@@ -16,11 +16,6 @@ class ComponentPermissionInline(admin.TabularInline):
|
|
|
16
16
|
fields = 'component', 'read', 'write'
|
|
17
17
|
readonly_fields = 'component',
|
|
18
18
|
|
|
19
|
-
def get_queryset(self, request):
|
|
20
|
-
return super().get_queryset(request).filter(
|
|
21
|
-
component__show_in_app=True
|
|
22
|
-
)
|
|
23
|
-
|
|
24
19
|
def has_delete_permission(self, request, obj=None):
|
|
25
20
|
return False
|
|
26
21
|
|
|
@@ -25,8 +25,8 @@ simo/_hub_template/hub/settings.py,sha256=4QhvhbtLRxHvAntwqG_qeAAtpDUqKvN4jzw9u3
|
|
|
25
25
|
simo/_hub_template/hub/supervisor.conf,sha256=IY3fdK0fDD2eAothB0n54xhjQj8LYoXIR96-Adda5Z8,1353
|
|
26
26
|
simo/_hub_template/hub/urls.py,sha256=Ydm-1BkYAzWeEF-MKSDIFf-7aE4qNLPm48-SA51XgJQ,25
|
|
27
27
|
simo/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
|
-
simo/core/admin.py,sha256=
|
|
29
|
-
simo/core/api.py,sha256=
|
|
28
|
+
simo/core/admin.py,sha256=vZp2TZTt41YararDkIEs35X6ARqRp94wrIddsIfe-Bs,17738
|
|
29
|
+
simo/core/api.py,sha256=9lPX8ShvAorn5p1qjPUxOKv_cmkOxoWyiIlHtCzgl5Q,23088
|
|
30
30
|
simo/core/api_auth.py,sha256=_3hG4e1eLKrcRnSAOB_xTL6cwtOJ2_7JS7GZU_iqTgA,1251
|
|
31
31
|
simo/core/api_meta.py,sha256=ySmmhtVrWatI3yqnYPuP5ipapmJfyfEbl32w-7_W5O4,3551
|
|
32
32
|
simo/core/app_widgets.py,sha256=EEQOto3fGR0syDqpJE38tQrx8DoTTyg26nF5kYzHY38,2018
|
|
@@ -34,7 +34,7 @@ simo/core/auto_urls.py,sha256=0gu-IL7PHobrmKW6ksffiOkAYu-aIorykWdxRNtwGYo,1194
|
|
|
34
34
|
simo/core/autocomplete_views.py,sha256=JT5LA2_Wtr60XYSAIqaXFKFYPjrmkEf6yunXD9y2zco,4022
|
|
35
35
|
simo/core/base_types.py,sha256=yqbIZqBksrAkEuHRbt6iExwPDDy0K5II2NzRCkmOvMU,589
|
|
36
36
|
simo/core/context.py,sha256=98PXAMie43faRVBFkOG22uNpvGRNprcGhzjBFkrxaRY,1367
|
|
37
|
-
simo/core/controllers.py,sha256=
|
|
37
|
+
simo/core/controllers.py,sha256=iJ7cIGv2WhSGjyxCFfK49pZXuEMfSe75bMEAkRN8G4g,27107
|
|
38
38
|
simo/core/dynamic_settings.py,sha256=U2WNL96JzVXdZh0EqMPWrxqO6BaRR2Eo5KTDqz7MC4o,1943
|
|
39
39
|
simo/core/events.py,sha256=LvtonJGNyCb6HLozs4EG0WZItnDwNdtnGQ4vTcnKvUs,4438
|
|
40
40
|
simo/core/filters.py,sha256=ghtOZcrwNAkIyF5_G9Sn73NkiI71mXv0NhwCk4IyMIM,411
|
|
@@ -42,9 +42,9 @@ simo/core/forms.py,sha256=FnnK4pHZ8EaMvubN0NQbz2SdTTgMXvGM-heklzN4RZo,22465
|
|
|
42
42
|
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
|
-
simo/core/middleware.py,sha256=
|
|
46
|
-
simo/core/models.py,sha256=
|
|
47
|
-
simo/core/permissions.py,sha256=
|
|
45
|
+
simo/core/middleware.py,sha256=pO52hQOJV_JRmNyUe7zfufSnJFlRITOWX6jwkoPWJhk,2052
|
|
46
|
+
simo/core/models.py,sha256=m05fXzOtLrq4LEGknU1mjTHzaTmIEBi1zhwvtDWDknE,19773
|
|
47
|
+
simo/core/permissions.py,sha256=m0GmmSeVQiXl1EZWgaVlK-Ud4lbwc1CLlcryomhKg6Y,2534
|
|
48
48
|
simo/core/routing.py,sha256=X1_IHxyA-_Q7hw1udDoviVP4_FSBDl8GYETTC2zWTbY,499
|
|
49
49
|
simo/core/serializers.py,sha256=kmja52o-BUOcUTX2ZsKWixvKRZSXB7lGe866Q1ajlmo,17563
|
|
50
50
|
simo/core/signal_receivers.py,sha256=EZ8NSYZxUgSaLS16YZdK7T__l8dl0joMRllOxx5PUt4,2809
|
|
@@ -56,8 +56,8 @@ simo/core/types.py,sha256=WJEq48mIbFi_5Alt4wxWMGXxNxUTXqfQU5koH7wqHHI,1108
|
|
|
56
56
|
simo/core/views.py,sha256=hlAKpAbCbqI3a-uL5tDp532T2oLFiF0MBzKUJ_SNzo0,5833
|
|
57
57
|
simo/core/widgets.py,sha256=J9e06C6I22F6xKic3VMgG7WeX07glAcl-4bF2Mg180A,2827
|
|
58
58
|
simo/core/__pycache__/__init__.cpython-38.pyc,sha256=y0IW37wBUIGa3Eh_ZG28pRqHKoLiPyTgUX2OnbkEPlc,158
|
|
59
|
-
simo/core/__pycache__/admin.cpython-38.pyc,sha256=
|
|
60
|
-
simo/core/__pycache__/api.cpython-38.pyc,sha256=
|
|
59
|
+
simo/core/__pycache__/admin.cpython-38.pyc,sha256=gZpNwM9f-JMbGe9sbQKt2hU2BBYhRzKSH9XRJYKN3Vo,13534
|
|
60
|
+
simo/core/__pycache__/api.cpython-38.pyc,sha256=FaLLTnRx1VwRVRsuJKT3v2gWzLtI26iTq2BYb3lq0r4,18458
|
|
61
61
|
simo/core/__pycache__/api_auth.cpython-38.pyc,sha256=5UTBr3rDMERAfc0OuOVDwGeQkt6Q7GLBtZJAMBse1sg,1712
|
|
62
62
|
simo/core/__pycache__/api_meta.cpython-38.pyc,sha256=94T3_rybn2T1_bkaDQnQRyjy21LBaGOnz-mmkJ6T0N8,2840
|
|
63
63
|
simo/core/__pycache__/app_widgets.cpython-38.pyc,sha256=9Es2wZNduzUJv-jZ_HX0-L3vqwpXWBbseEwoC5K6b-w,3465
|
|
@@ -65,7 +65,7 @@ simo/core/__pycache__/auto_urls.cpython-38.pyc,sha256=SVl4fF0-yiq7e9gt08jIM6_rL4
|
|
|
65
65
|
simo/core/__pycache__/autocomplete_views.cpython-38.pyc,sha256=hJ6JILI1LqrAtpQMvxnLvljGdW1v1gpvBsD79vFkZ58,3972
|
|
66
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
|
-
simo/core/__pycache__/controllers.cpython-38.pyc,sha256=
|
|
68
|
+
simo/core/__pycache__/controllers.cpython-38.pyc,sha256=40wJ3mu0CnzexxDzXyDIlSxaZUeuRXR-GMCLpEfM86g,23885
|
|
69
69
|
simo/core/__pycache__/dynamic_settings.cpython-38.pyc,sha256=ELu06Hub4DOidja71ybvD3ZM4HdXiyZjNJrZfnXZXNA,2476
|
|
70
70
|
simo/core/__pycache__/events.cpython-38.pyc,sha256=A1Axx-qftd1r7st7wkO3DkvTdt9-RkcJe5KJhpzJVk8,5109
|
|
71
71
|
simo/core/__pycache__/filters.cpython-38.pyc,sha256=VIMADCBiYhziIyRmxAyUDJluZvuZmiC4bNYWTRsGSao,721
|
|
@@ -73,9 +73,9 @@ simo/core/__pycache__/forms.cpython-38.pyc,sha256=U5pV_JyfoGwymn3tsws8FR2GrxihjK
|
|
|
73
73
|
simo/core/__pycache__/gateways.cpython-38.pyc,sha256=XBiwMfBkjoQ2re6jvADJOwK0_0Aav-crzie9qtfqT9U,4599
|
|
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
|
-
simo/core/__pycache__/middleware.cpython-38.pyc,sha256=
|
|
77
|
-
simo/core/__pycache__/models.cpython-38.pyc,sha256=
|
|
78
|
-
simo/core/__pycache__/permissions.cpython-38.pyc,sha256=
|
|
76
|
+
simo/core/__pycache__/middleware.cpython-38.pyc,sha256=ESR5JPtITo9flczO0672sfzYUxrc_cQU0e0w5DFL-60,2038
|
|
77
|
+
simo/core/__pycache__/models.cpython-38.pyc,sha256=kYcojazryAAgZCXMoqqutIG2p8ofSKxza9TMx1SR2dQ,17233
|
|
78
|
+
simo/core/__pycache__/permissions.cpython-38.pyc,sha256=uk2NsUixTKBM31T08YixwPO35TRp99hF5BmAf8bj5Vw,2720
|
|
79
79
|
simo/core/__pycache__/routing.cpython-38.pyc,sha256=3T3FPJ8Cn99xZCGvMyg2xjl7al-Shm9CelbSpkJtNP8,599
|
|
80
80
|
simo/core/__pycache__/serializers.cpython-38.pyc,sha256=x-obnrdPnoYRhriP_51_Jy_0saCsasWdFQSH1kalVqo,16869
|
|
81
81
|
simo/core/__pycache__/signal_receivers.cpython-38.pyc,sha256=sgjH_wv-1U99auH5uHb3or0qettPeHAlsz8P7B03ajY,2430
|
|
@@ -10141,6 +10141,7 @@ simo/core/utils/form_fields.py,sha256=UOzYdPd71qgCw1H3qH01u85YjrOlETPJAHOJrZKhyD
|
|
|
10141
10141
|
simo/core/utils/form_widgets.py,sha256=Zxn9jJqPle9Q_BKNJnyTDn7MosYwNp1TFu5LoKs0bfc,408
|
|
10142
10142
|
simo/core/utils/formsets.py,sha256=1u34QGZ2P67cxZD2uUJS3lAf--E8XsiiqFmZ4P41Vw4,6463
|
|
10143
10143
|
simo/core/utils/helpers.py,sha256=TOWy3slspaEYEhe9zDcb0RgzHUYslF6LZDlrWPGSqUI,3791
|
|
10144
|
+
simo/core/utils/json.py,sha256=x3kMiiK30vuyWSYfghLVsDKo0N2JlCxZ5n8cwel85Vk,464
|
|
10144
10145
|
simo/core/utils/logs.py,sha256=Zn9JQxqCH9Odx2J1BWT84nFCfkJ4Z4p5X8psdll7hNc,2366
|
|
10145
10146
|
simo/core/utils/mixins.py,sha256=X6kUPKAi_F-uw7tgm8LEaYalBXpvDA-yrLNFCGr2rks,259
|
|
10146
10147
|
simo/core/utils/model_helpers.py,sha256=3IzJeOvBoYdUJVXCJkY20npOZXPjNPAiEFvuT0OPhwA,884
|
|
@@ -10157,6 +10158,7 @@ simo/core/utils/__pycache__/form_fields.cpython-38.pyc,sha256=nBk6k9aj6BpWwdkpce
|
|
|
10157
10158
|
simo/core/utils/__pycache__/form_widgets.cpython-38.pyc,sha256=MYAYEq0I4P0WErG9FamTJYWue7-cPartAWbFAiSSg5w,908
|
|
10158
10159
|
simo/core/utils/__pycache__/formsets.cpython-38.pyc,sha256=10Fe8s0Wx2ISyuKt9TX0rg7_vbFneV0Hvjbj8V4VIqA,4637
|
|
10159
10160
|
simo/core/utils/__pycache__/helpers.cpython-38.pyc,sha256=jTGaN7kSJRwouP0EuYSaiJeMylo_RzJwSm-DKRwceHA,4291
|
|
10161
|
+
simo/core/utils/__pycache__/json.cpython-38.pyc,sha256=akSSiSUOnza4N15GAH399gTz-X8x-5gijxZdjZoPz5Q,504
|
|
10160
10162
|
simo/core/utils/__pycache__/logs.cpython-38.pyc,sha256=BVVeQoOhfRHm3SHnCoE1d5G84kTpJZFmr_btc3jDYTU,2156
|
|
10161
10163
|
simo/core/utils/__pycache__/mixins.cpython-38.pyc,sha256=8Js2T7jVQ7hugRUIRu3rdxW86dJW4KeUUWqKqSkIGb0,615
|
|
10162
10164
|
simo/core/utils/__pycache__/model_helpers.cpython-38.pyc,sha256=QzO0rh1NuQePHDCSLmUCRrAZEnV4o8jh9CF_jp7IoUo,1351
|
|
@@ -10171,7 +10173,7 @@ simo/fleet/auto_urls.py,sha256=X04oKJWA48wFW5iXg3PPROY2KDdHn_a99orQSE28QC4,518
|
|
|
10171
10173
|
simo/fleet/base_types.py,sha256=wL9RVkHr0gA7HI1wZq0pruGEIgvQqpfnCL4cC3ywsvw,102
|
|
10172
10174
|
simo/fleet/ble.py,sha256=eHA_9ABjbmH1vUVCv9hiPXQL2GZZSEVwfO0xyI1S0nI,1081
|
|
10173
10175
|
simo/fleet/controllers.py,sha256=rTxRFf-LKWAZxzixrsLZHHm51BmMx9a1PLdgf6inlNM,20533
|
|
10174
|
-
simo/fleet/forms.py,sha256=
|
|
10176
|
+
simo/fleet/forms.py,sha256=QzHmAsWC258w2mFkQrnxL0k7h3Y9aN8oduEmrPGnqI4,38430
|
|
10175
10177
|
simo/fleet/gateways.py,sha256=KV5i5fxXIrlK-k6zyEkk83x11GJt-ELQ0npb4Ac83cM,3693
|
|
10176
10178
|
simo/fleet/managers.py,sha256=XOpDOA9L-f_550TNSyXnJbun2EmtGz1TenVTMlUSb8E,807
|
|
10177
10179
|
simo/fleet/models.py,sha256=ve-97F1cwGt-AmwfSJK0d-57pP3NyZpeu0XlHu2oK28,14494
|
|
@@ -10188,7 +10190,7 @@ simo/fleet/__pycache__/auto_urls.cpython-38.pyc,sha256=SqyTuaz_kEBvx-bL46SclsZEE
|
|
|
10188
10190
|
simo/fleet/__pycache__/base_types.cpython-38.pyc,sha256=deyPwjpT6xZiFxBGFnj5b7R-lbdOTh2krgpJhrcGVhc,274
|
|
10189
10191
|
simo/fleet/__pycache__/ble.cpython-38.pyc,sha256=Nrof9w7cm4OlpFWHeVnmvvanh2_oF9oQ3TknJiV93-0,1267
|
|
10190
10192
|
simo/fleet/__pycache__/controllers.cpython-38.pyc,sha256=l9bz18Qp33C12TJOKPSn9vIXnlBKnBusODNk7Fg64qA,18103
|
|
10191
|
-
simo/fleet/__pycache__/forms.cpython-38.pyc,sha256=
|
|
10193
|
+
simo/fleet/__pycache__/forms.cpython-38.pyc,sha256=H3-EYmeHeNWIghaKBqduJk3DAKvayStrPrNp2i43274,27751
|
|
10192
10194
|
simo/fleet/__pycache__/gateways.cpython-38.pyc,sha256=YAcgTOqJbtjGI03lvEcU6keFfrwAHkObVmErYzfRvjk,3569
|
|
10193
10195
|
simo/fleet/__pycache__/managers.cpython-38.pyc,sha256=8uz-xpUiqbGDgXIZ_XRZtFb-Tju6NGxflGg-Ee4Yo6k,1310
|
|
10194
10196
|
simo/fleet/__pycache__/models.cpython-38.pyc,sha256=pHNRUiPRjH0SLp14pzbSIxHi_-27SpZFgSh_7lzA8Wo,12359
|
|
@@ -10357,7 +10359,7 @@ simo/notifications/migrations/__pycache__/0001_initial.cpython-38.pyc,sha256=YnO
|
|
|
10357
10359
|
simo/notifications/migrations/__pycache__/0002_notification_instance.cpython-38.pyc,sha256=Gkb3Qwr_zglGibQg9g5ekIgxtGapS4ENXVWQVHqM56I,794
|
|
10358
10360
|
simo/notifications/migrations/__pycache__/__init__.cpython-38.pyc,sha256=YMBRHVon2nWDtIUbghckjnC12sIg_ykPWhV5aM0tto4,178
|
|
10359
10361
|
simo/users/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10360
|
-
simo/users/admin.py,sha256=
|
|
10362
|
+
simo/users/admin.py,sha256=6RKGnwcrmewJFPzpqnxYn8rxjHO4tJPVFJvA3eMum2s,6746
|
|
10361
10363
|
simo/users/api.py,sha256=FVo2bHkGA9VKavyjQm8_wfvI5rQ5KcMZliRiTJjixmI,9462
|
|
10362
10364
|
simo/users/auth_backends.py,sha256=I5pnaTa20-Lxfw_dFG8471xDITb0_fQl1PVhJalp5vU,3992
|
|
10363
10365
|
simo/users/auto_urls.py,sha256=lcJvteBsbHQMJieZpDz-63tDYejLApqsW3CUnDakd7k,272
|
|
@@ -10372,7 +10374,7 @@ simo/users/tasks.py,sha256=v9J7t4diB0VnqUDVZAQ8H-rlr4ZR14bgEUuEGpODyOI,854
|
|
|
10372
10374
|
simo/users/utils.py,sha256=uOyCNHQJ_tpn054L89keuQwKAzFd0Y2VSUmDVPq6oaY,1335
|
|
10373
10375
|
simo/users/views.py,sha256=dOQVvmlHG7ihWKJLFUBcqKOA0UDctlMKR0pTc36JZqg,3487
|
|
10374
10376
|
simo/users/__pycache__/__init__.cpython-38.pyc,sha256=9otuYxq331c4lGy0DR8pigaPpzq0lQ4nrNLhlYiFAF0,159
|
|
10375
|
-
simo/users/__pycache__/admin.cpython-38.pyc,sha256=
|
|
10377
|
+
simo/users/__pycache__/admin.cpython-38.pyc,sha256=53Do-W6tvaOUPJ1BDx0abBbtvmQxAgdI2ShlqmYfUvI,7500
|
|
10376
10378
|
simo/users/__pycache__/api.cpython-38.pyc,sha256=4Fmi4fvgQqc8bM1lyQFVN3nKyWol9RgnUvy7YSNhwuE,8256
|
|
10377
10379
|
simo/users/__pycache__/auth_backends.cpython-38.pyc,sha256=MuOieBIXt6lrDx83-UQtdDyI_U8kE3pU9XR4yFLKBnE,3007
|
|
10378
10380
|
simo/users/__pycache__/auto_urls.cpython-38.pyc,sha256=K-3sz2h-cEitoflSmZk1t0eUg5mQMMGLNZFREVwG7_o,430
|
|
@@ -10448,8 +10450,8 @@ simo/users/templates/invitations/expired_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCe
|
|
|
10448
10450
|
simo/users/templates/invitations/expired_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10449
10451
|
simo/users/templates/invitations/taken_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10450
10452
|
simo/users/templates/invitations/taken_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10451
|
-
simo-2.0.
|
|
10452
|
-
simo-2.0.
|
|
10453
|
-
simo-2.0.
|
|
10454
|
-
simo-2.0.
|
|
10455
|
-
simo-2.0.
|
|
10453
|
+
simo-2.0.25.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
|
|
10454
|
+
simo-2.0.25.dist-info/METADATA,sha256=z4jsvR3Vf9Zbu9KiGZv12Q0IwiW5FHorEehCTxsVjx0,1730
|
|
10455
|
+
simo-2.0.25.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
10456
|
+
simo-2.0.25.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
|
|
10457
|
+
simo-2.0.25.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|