simo 2.0.24__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.

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
- from django.db.models import Q, Prefetch
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
- return HttpResponse(
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(InstanceMixin, viewsets.ModelViewSet):
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):
@@ -210,10 +214,10 @@ class ComponentViewSet(InstanceMixin, viewsets.ModelViewSet):
210
214
  return RESTResponse(result)
211
215
 
212
216
  # TODO: remove post when app is updated for all users
213
- @action(detail=True, methods=['post', 'put'])
217
+ @action(detail=True, methods=['post'])
214
218
  def subcomponent(self, request, pk=None, *args, **kwargs):
215
219
  component = self.get_object()
216
- json_data = request.data
220
+ json_data = restore_json(request.data.dict())
217
221
  subcomponent_id = json_data.pop('id', -1)
218
222
  try:
219
223
  subcomponent = component.slaves.get(pk=subcomponent_id)
@@ -230,18 +234,21 @@ class ComponentViewSet(InstanceMixin, viewsets.ModelViewSet):
230
234
  self.check_object_permissions(self.request, subcomponent)
231
235
  return self.perform_controller_method(json_data, subcomponent)
232
236
 
233
- @action(detail=True, methods=['post', 'put'])
237
+ @action(detail=True, methods=['post'])
234
238
  def controller(self, request, pk=None, *args, **kwargs):
235
239
  component = self.get_object()
236
- return self.perform_controller_method(request.data, component)
240
+ return self.perform_controller_method(
241
+ restore_json(request.data.dict()), component
242
+ )
237
243
 
238
- @action(detail=False, methods=['post', 'put'])
244
+ @action(detail=False, methods=['post'])
239
245
  def control(self, request, *args, **kwargs):
240
- component = self.get_queryset().filter(id=request.data.pop('id', 0))
246
+ request_data = restore_json(request.data.dict())
247
+ component = self.get_queryset().filter(id=request_data.pop('id', 0)).first()
241
248
  if not component:
242
249
  raise Http404()
243
250
  self.check_object_permissions(self.request, component)
244
- return self.perform_controller_method(request.data, component)
251
+ return self.perform_controller_method(request_data, component)
245
252
 
246
253
  @action(detail=True, methods=['get'])
247
254
  def value_history(self, request, pk=None, *args, **kwargs):
@@ -532,9 +539,7 @@ class StatesViewSet(InstanceMixin, viewsets.GenericViewSet):
532
539
  ).exclude(email__in=('system@simo.io', 'device@simo.io'))
533
540
  component_values = get_components_queryset(
534
541
  self.instance, request.user
535
- ).filter(zone__instance=self.instance).prefetch_related(
536
- Prefetch('history', queryset=ComponentHistory.objects.filter())
537
- ).values(
542
+ ).filter(zone__instance=self.instance).values(
538
543
  'id', 'value', 'last_change', 'arm_status', 'battery_level',
539
544
  'alive', 'meta'
540
545
  )
@@ -623,6 +628,4 @@ class RunningDiscoveries(InstanceMixin, viewsets.GenericViewSet):
623
628
  if 'controller_uid' in request.GET:
624
629
  for gateway in gateways:
625
630
  gateway.retry_discovery()
626
- return RESTResponse(self.get_data(gateways))
627
-
628
-
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 not isinstance(value, bool):
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
@@ -1,5 +1,6 @@
1
1
  import pytz
2
2
  import threading
3
+ import time
3
4
  from django.urls import set_script_prefix
4
5
  from django.utils import timezone
5
6
  from simo.conf import dynamic_settings
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
- return False
17
+ raise Http404()
17
18
 
18
19
  if instance not in request.user.instances:
19
20
  return False
@@ -37,12 +38,14 @@ class InstanceSuperuserCanEdit(BasePermission):
37
38
  def has_object_permission(self, request, view, obj):
38
39
  '''
39
40
  in this permission we only care about:
40
- POST - create new object
41
+ POST - new object can be created
42
+ PUT - create new object
41
43
  PATCH - modify an object
42
44
  DELETE - delete an oject
43
45
  '''
46
+ # TODO: allow object creation only with PUT method, this way proper permissions system will be guaranteed.
44
47
 
45
- if request.method in SAFE_METHODS + ('PUT', 'POST', ): # TODO: remove POST
48
+ if request.method in SAFE_METHODS + ('POST',):
46
49
  return True
47
50
 
48
51
  # allow deleting only empty categories and zones
@@ -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
@@ -787,7 +787,7 @@ class DualMotorValveForm(ColonelComponentForm):
787
787
  )
788
788
  open_duration = forms.FloatField(
789
789
  required=True, min_value=0.01, max_value=1000000000,
790
- help_text="Time in seconds to open."
790
+ initial=2, help_text="Time in seconds to open."
791
791
  )
792
792
  close_pin = ColonelPinChoiceField(
793
793
  queryset=ColonelPin.objects.filter(output=True),
@@ -805,7 +805,7 @@ class DualMotorValveForm(ColonelComponentForm):
805
805
  )
806
806
  close_duration = forms.FloatField(
807
807
  required=True, min_value=0.01, max_value=1000000000,
808
- help_text="Time in seconds to close."
808
+ initial=10, help_text="Time in seconds to close."
809
809
  )
810
810
 
811
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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: simo
3
- Version: 2.0.24
3
+ Version: 2.0.25
4
4
  Summary: Smart Home on Steroids!
5
5
  Author-email: Simanas Venčkauskas <simanas@simo.io>
6
6
  Project-URL: Homepage, https://simo.io
@@ -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=cPOC2x45Gjf0T8MKtmE2wJZk7DAuHMsvvy5Nk3YUIG8,17675
29
- simo/core/api.py,sha256=uMbczzV6gLIOJWRe6sHJGwvZrDhzOPU-zePSihi3MqE,23048
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=SHqdSRhF7G-hmRtcWEODkUs-b17y6gEHDdZM3V01uVs,26977
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=64PYjnyRnYf4sgMvPfR0oQqf9UEtxUwnhJe3RV6z_HI,2040
46
- simo/core/models.py,sha256=zqbPDYLHOsavrBzw5uOmUgcWBnBbjGLvezgETX-pD_E,19672
47
- simo/core/permissions.py,sha256=3PEmEVoRXSN6HjQKoRq7ONU6Yt2mv8c_Ya5KZH815RA,2372
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=EqwHQhU8qQrjfSChyCZXN6J-1Eira9alYIqR45-3OnE,13475
60
- simo/core/__pycache__/api.cpython-38.pyc,sha256=wyjCPKUQtjiQ9xg9kOVhycu8Jm_2ZE1HPPqCRyLRyLE,18383
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=vGRcRD7VPUdpP2WMtn2IIrnkoFbFaC-DYb8kqushWGQ,23820
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=bGOFJNEhJeLbpsZp8LYn1VA3paLF5HULHQ6IFKa7Juc,2022
77
- simo/core/__pycache__/models.cpython-38.pyc,sha256=meQeK2mVoSDP9cTMSZDW-Ofi53QzwjfHSUlAGlnhyfs,17127
78
- simo/core/__pycache__/permissions.cpython-38.pyc,sha256=das7lo0PAfQsiRgkqOxP-rd1p2EElyk4wE8XUhVccuA,2635
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=7qe-Izd3yMc43BFdpfgqtz_9dkVxhp4krB-iKsTA5_I,38407
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=3MAf9dL-HZjMiOhaLmMjMh_KR0so_9Rq4XYS4htX-zQ,27711
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=IY501Ewbn8KkBJ3ryBPelHU37ac2--dd6NNGsmYQ6FE,6887
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=T7gzc4xv2JIh3nkJEr4aRZAzyaaweX4m9JXJ-xzwsd0,7705
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.24.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
10452
- simo-2.0.24.dist-info/METADATA,sha256=iakv_6SOidRd-FQnFU6PzDNjrtBwjGUHzd-7LK3mW3k,1730
10453
- simo-2.0.24.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
10454
- simo-2.0.24.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
10455
- simo-2.0.24.dist-info/RECORD,,
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