simo 2.8.13__py3-none-any.whl → 2.8.14__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
simo/core/api.py CHANGED
@@ -180,16 +180,14 @@ def get_main_components_ids(instance):
180
180
 
181
181
  def get_components_queryset(instance, user):
182
182
  qs = Component.objects.filter(zone__instance=instance)
183
- if user.is_master or user.is_superuser:
184
- pass
185
- else:
183
+ if not user.is_master:
186
184
  c_ids = get_main_components_ids(instance)
187
-
188
185
  user_role = user.get_role(instance)
189
186
  if user_role:
190
187
  for cp in user_role.component_permissions.all():
191
188
  if cp.read:
192
189
  c_ids.append(cp.component.id)
190
+
193
191
  qs = qs.filter(id__in=c_ids)
194
192
 
195
193
  return qs.select_related(
simo/core/controllers.py CHANGED
@@ -318,8 +318,6 @@ class ControllerBase(ABC):
318
318
  ).first()
319
319
  self.component.save()
320
320
 
321
-
322
-
323
321
  def _receive_from_device(
324
322
  self, value, is_alive=True, battery_level=None, error_msg=None
325
323
  ):
@@ -1,5 +1,6 @@
1
1
  import os
2
2
  import shutil
3
+ from django.core.cache import cache
3
4
  from django.db import transaction
4
5
  from django.db.models.signals import post_save, post_delete
5
6
  from django.dispatch import receiver
@@ -184,6 +185,16 @@ def post_save_change_events(sender, instance, created, **kwargs):
184
185
 
185
186
  transaction.on_commit(post_update)
186
187
 
188
+ if created:
189
+ def clear_api_cache():
190
+ cache.delete(f"main-components-{instance.zone.instance.id}")
191
+ from simo.users.models import User
192
+ for user in User.objects.all():
193
+ role_cache_key = f'user-{user.id}_instance-' \
194
+ f'{instance.zone.instance.id}_role'
195
+ cache.delete(role_cache_key)
196
+ transaction.on_commit(clear_api_cache)
197
+
187
198
 
188
199
  @receiver(post_save, sender=Gateway)
189
200
  def gateway_post_save(sender, instance, created, *args, **kwargs):
Binary file
simo/fleet/api.py CHANGED
@@ -75,6 +75,14 @@ class ColonelsViewSet(InstanceMixin, viewsets.ModelViewSet):
75
75
  colonel.move_to(target)
76
76
  return RESTResponse({'status': 'success'})
77
77
 
78
+ def perform_destroy(self, instance):
79
+ if instance.components.all().count():
80
+ raise APIValidationError(
81
+ _('Deleting colonel which has components is not allowed!'),
82
+ code=400
83
+ )
84
+ instance.delete()
85
+
78
86
 
79
87
  class InterfaceViewSet(
80
88
  InstanceMixin,
@@ -8,6 +8,7 @@ from django.utils.functional import cached_property
8
8
  from django.utils.translation import gettext_lazy as _
9
9
  from django.conf import settings
10
10
  from django.urls import reverse_lazy
11
+ from simo.users.utils import get_system_user
11
12
  from simo.core.models import Component
12
13
  from simo.core.utils.helpers import get_random_string
13
14
  from simo.core.middleware import get_current_instance
@@ -78,7 +79,7 @@ class Thermostat(ControllerBase):
78
79
  }
79
80
 
80
81
  def _validate_val(self, value, occasion=None):
81
- raise ValidationError("This component type does not accept set value!")
82
+ return value
82
83
 
83
84
  def _get_default_user_config(self):
84
85
  instance = get_current_instance()
@@ -152,6 +153,7 @@ class Thermostat(ControllerBase):
152
153
  data['weekly'][str(localtime.weekday() + 1)])
153
154
 
154
155
  def evaluate(self):
156
+
155
157
  from simo.core.models import Component
156
158
  self.component.refresh_from_db()
157
159
  tz = pytz.timezone(self.component.zone.instance.timezone)
@@ -185,12 +187,12 @@ class Thermostat(ControllerBase):
185
187
  target_temp = self.get_current_target_temperature()
186
188
  mode = self.component.config['user_config'].get('mode', 'auto')
187
189
 
188
- self.component.value = {
190
+ self.component.set({
189
191
  'mode': mode,
190
192
  'current_temp': current_temp,
191
193
  'target_temp': target_temp,
192
194
  'heating': False, 'cooling': False
193
- }
195
+ }, actor=get_system_user())
194
196
 
195
197
  low = target_temp - self.component.config['reaction_difference'] / 2
196
198
  high = target_temp + self.component.config['reaction_difference'] / 2
@@ -55,7 +55,7 @@ class SIMOUserBackend(ModelBackend):
55
55
 
56
56
  class SSOBackend(ModelBackend):
57
57
 
58
- @transaction.atomic
58
+
59
59
  def authenticate(self, request, user_data=None, **kwargs):
60
60
  system_user_emails = ('system@simo.io', 'device@simo.io')
61
61
  if not user_data:
@@ -81,13 +81,12 @@ class SSOBackend(ModelBackend):
81
81
  token=user_data.get('invitation_token'),
82
82
  taken_by__isnull=True, expire_date__gt=timezone.now()
83
83
  )
84
- except InstanceInvitation.DoesNotExist:
85
- invitation = None
86
- else:
87
84
  if not user:
88
85
  user = User.objects.create(
89
86
  email=user_data['email'], name=user_data['name']
90
87
  )
88
+ except InstanceInvitation.DoesNotExist:
89
+ invitation = None
91
90
 
92
91
  if not user:
93
92
  return
@@ -95,13 +94,14 @@ class SSOBackend(ModelBackend):
95
94
  if invitation:
96
95
  invitation.taken_by = user
97
96
  invitation.save()
97
+ from simo.core.middleware import introduce_instance
98
+ introduce_instance(invitation.instance)
98
99
  InstanceUser.objects.update_or_create(
99
100
  user=user, instance=invitation.instance,
100
101
  defaults={'role': invitation.role}
101
102
  )
102
- if not user.is_active:
103
- user.is_active = True
104
- user.save()
103
+ user.is_active = True
104
+ user.save()
105
105
 
106
106
  if not user.is_active:
107
107
  return
@@ -113,9 +113,12 @@ class SSOBackend(ModelBackend):
113
113
  if user_data.get('avatar_url') \
114
114
  and user.avatar_url != user_data.get('avatar_url'):
115
115
  user.avatar_url = user_data.get('avatar_url')
116
- resp = requests.get(user.avatar_url)
117
- user.avatar.save(
118
- os.path.basename(user.avatar_url), io.BytesIO(resp.content)
119
- )
116
+ try:
117
+ resp = requests.get(user.avatar_url)
118
+ user.avatar.save(
119
+ os.path.basename(user.avatar_url), io.BytesIO(resp.content)
120
+ )
121
+ except:
122
+ pass
120
123
 
121
124
  return user
simo/users/models.py CHANGED
@@ -280,7 +280,7 @@ class User(AbstractBaseUser, SimoAdminMixin):
280
280
  'component_permissions', 'component_permissions__component'
281
281
  ).first()
282
282
  if role:
283
- cache.set(cache_key, role, 20)
283
+ cache.set(cache_key, role, 60)
284
284
  self._instance_roles[instance.id] = role
285
285
  return self._instance_roles[instance.id]
286
286
 
@@ -297,7 +297,7 @@ class User(AbstractBaseUser, SimoAdminMixin):
297
297
  for role in self.roles.all().select_related('instance'):
298
298
  if role.instance == instance:
299
299
  cached_val = role.id
300
- cache.set(cache_key, role.id, 20)
300
+ cache.set(cache_key, role.id, 60)
301
301
  return cached_val
302
302
  return cached_val
303
303
 
@@ -354,7 +354,6 @@ class User(AbstractBaseUser, SimoAdminMixin):
354
354
  role__in=self.roles.all()
355
355
  )
356
356
 
357
-
358
357
  @property
359
358
  def is_active(self):
360
359
  if self._is_active is not None:
@@ -364,7 +363,7 @@ class User(AbstractBaseUser, SimoAdminMixin):
364
363
  if cached_value is None:
365
364
  if self.is_master:
366
365
  if not self.instance_roles.all().count():
367
- # Master who have no roles on any instance are in GOD mode!
366
+ # Masters who have no roles on any instances are in GOD mode!
368
367
  # It can not be disabled by anybody, nor it is seen by anybody. :)
369
368
  cached_value = True
370
369
  else:
@@ -397,7 +396,7 @@ class User(AbstractBaseUser, SimoAdminMixin):
397
396
  self.instance_roles.filter(
398
397
  instance=instance
399
398
  ).update(is_active=bool(val))
400
- cache_key = f'user-{self.id}_is_active_instance-{instance.id}'
399
+ cache_key = f'user-{self.id}_is_active'
401
400
  try:
402
401
  cache.delete(cache_key)
403
402
  except:
simo/users/serializers.py CHANGED
@@ -29,7 +29,10 @@ class UserSerializer(serializers.ModelSerializer):
29
29
  )
30
30
 
31
31
  def get_is_active(self, obj):
32
- return obj.is_active
32
+ iu = InstanceUser.objects.filter(
33
+ user=obj, instance=get_current_instance()
34
+ ).first()
35
+ return iu.is_active
33
36
 
34
37
  def get_avatar(self, obj):
35
38
  if not obj.avatar:
@@ -46,7 +49,6 @@ class UserSerializer(serializers.ModelSerializer):
46
49
  'last_change': obj.avatar_last_change.timestamp()
47
50
  }
48
51
 
49
-
50
52
  def get_at_home(self, obj):
51
53
  iu = InstanceUser.objects.filter(
52
54
  user=obj, instance=get_current_instance()
@@ -80,6 +82,7 @@ class InstanceInvitationSerializer(serializers.ModelSerializer):
80
82
  'instance', 'token', 'from_user', 'taken_by',
81
83
  )
82
84
 
85
+
83
86
  class FingerprintSerializer(serializers.ModelSerializer):
84
87
  type = serializers.SerializerMethodField()
85
88
 
simo/users/sso_views.py CHANGED
@@ -103,7 +103,6 @@ class AuthenticateView(LoginView):
103
103
  )
104
104
  })
105
105
 
106
-
107
106
  login(request, user, backend=user.backend)
108
107
  next = self.get_next()
109
108
  if request.headers.get('User-Agent', '').startswith("SIMO"):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: simo
3
- Version: 2.8.13
3
+ Version: 2.8.14
4
4
  Summary: Smart Home Supremacy
5
5
  Author-email: Simanas Venčkauskas <simanas@simo.io>
6
6
  Project-URL: Homepage, https://simo.io
@@ -89,7 +89,7 @@ simo/backups/migrations/__pycache__/__init__.cpython-312.pyc,sha256=s5eIx8UcBwZR
89
89
  simo/backups/migrations/__pycache__/__init__.cpython-38.pyc,sha256=Lz1fs6V05h2AoxTOLNye0do9bEMnyuaXB_hHOjG5-HU,172
90
90
  simo/core/__init__.py,sha256=_s2TjJfQImsMrTIxqLAx9AZie1Ojmm6sCHASdl3WLGU,50
91
91
  simo/core/admin.py,sha256=j07Dy3IsW7SRRsAJ2XXGzE0MTxmfY87CEEbT22kLlS4,18550
92
- simo/core/api.py,sha256=vqh4jOE4Y2LtykXVGLUiyoNdhcbiItSAzLJILlV5Y7k,29964
92
+ simo/core/api.py,sha256=yqGxO0dQC3aUfIfZw2XpVeeVuGEjKgtO5hLhOhqAD6g,29924
93
93
  simo/core/api_auth.py,sha256=I9bALko_L7M2dodUkVLRHPctdwR-KPbyZ-r1HygDyEU,1229
94
94
  simo/core/api_meta.py,sha256=Y-kq5lLwjymARnKOx0jHCS4OOH9PhyWNwIUxLUJMny8,5350
95
95
  simo/core/app_widgets.py,sha256=VxZzapuc-a29wBH7JzpvNF2SK1ECrgNUySId5ke1ffc,2509
@@ -98,7 +98,7 @@ simo/core/auto_urls.py,sha256=FqKhH0fF7cGO6P2YrjblwG4JA2UkVXj3lreJUOB2Jq4,1194
98
98
  simo/core/autocomplete_views.py,sha256=x3MKOZvXYS3xVQ-V1S7Liv_U5bxr-uc0gePa85wv5nA,4561
99
99
  simo/core/base_types.py,sha256=WypW8hTfzveuTQtruGjLYAGQZIuczxTlW-SdRk3iQug,666
100
100
  simo/core/context.py,sha256=LKw1I4iIRnlnzoTCuSLLqDX7crHdBnMo3hjqYvVmzFc,1557
101
- simo/core/controllers.py,sha256=P4D0Tw1_t0CGM3JzRRMdyW9941xxrMsJVwikJz62ffE,37928
101
+ simo/core/controllers.py,sha256=LMtfno8vUf5QQspBGJCTxXqYjNnyFtK2VzXiKoP9sN8,37926
102
102
  simo/core/dynamic_settings.py,sha256=bUs58XEZOCIEhg1TigR3LmYggli13KMryBZ9pC7ugAQ,1872
103
103
  simo/core/events.py,sha256=hnv17g37kqwpfrkMUStfk_Rk_-G28MU1HEjolwWNNFg,4978
104
104
  simo/core/filters.py,sha256=6wbn8C2WvKTTjtfMwwLBp2Fib1V0-DMpS4iqJd6jJQo,2540
@@ -112,7 +112,7 @@ simo/core/models.py,sha256=brZPs8clR49VKm_Uo1wgPgCbjkS0fTLvzz3rROBeob4,23211
112
112
  simo/core/permissions.py,sha256=Ef4NO7QwwDd3Z-v61R0BeCBXxTOJz9qBvzRTIB5tHwI,2943
113
113
  simo/core/routing.py,sha256=X1_IHxyA-_Q7hw1udDoviVP4_FSBDl8GYETTC2zWTbY,499
114
114
  simo/core/serializers.py,sha256=adqe8oYP5f7hGFXcxa-Zmce2KOwy3hZOaWE3MaAFtpM,23157
115
- simo/core/signal_receivers.py,sha256=GijhDPB_9TLL2cCedAh5KceqnCXGCnfHpi549uqWyiY,6642
115
+ simo/core/signal_receivers.py,sha256=PsAHAvdFKuNLjxNbb7UqjrX7VHtjdPAhP2y3vbhVGXs,7114
116
116
  simo/core/socket_consumers.py,sha256=UlxV9OvTUUXaoKKYT3-qf1TyGxyOPxIpFH5cPFepH1o,9584
117
117
  simo/core/storage.py,sha256=_5igjaoWZAiExGWFEJMElxUw55DzJG1jqFty33xe8BE,342
118
118
  simo/core/tasks.py,sha256=-yBjOPILEnKRga-6MK-hBpEINQcY5mpwZwUWiDpqISs,17091
@@ -122,9 +122,9 @@ simo/core/views.py,sha256=08H4Bm7KrHxB3p3ZKx1vrFR4d0DjCqMbqQosEsRWpkY,2841
122
122
  simo/core/widgets.py,sha256=J9e06C6I22F6xKic3VMgG7WeX07glAcl-4bF2Mg180A,2827
123
123
  simo/core/__pycache__/__init__.cpython-312.pyc,sha256=n24Th9iLDCEciqsZdLD2hjnO-I1m4bCkR_sLgYKY35k,220
124
124
  simo/core/__pycache__/__init__.cpython-38.pyc,sha256=ZJFM_XN0RmJMULQulgA_wFiOnEtsMoedcOWnXjH-Y8o,208
125
- simo/core/__pycache__/admin.cpython-312.pyc,sha256=P8TOAzWJ96D4krjOvfGvRBE6Vo97gZruEdHTC_M5E3o,23162
125
+ simo/core/__pycache__/admin.cpython-312.pyc,sha256=pIlxbFqRrnM3bqCG9VSou7ZVhd4zwUm7XKjVcr2fAPg,23162
126
126
  simo/core/__pycache__/admin.cpython-38.pyc,sha256=zdegA3IsH3QhT7Hm6Aj08F2sv-3h1X7VBcwN05fhVis,14155
127
- simo/core/__pycache__/api.cpython-312.pyc,sha256=nEmBSNxFuYGTBbY5sVS8k2iF4u8j8R4lhJdBrsN7tvU,41475
127
+ simo/core/__pycache__/api.cpython-312.pyc,sha256=PuEVKwK6CC9dCYhMPSN5KWEO7akT1qfR1qyYXJt65wk,41433
128
128
  simo/core/__pycache__/api.cpython-38.pyc,sha256=TOa0p4h-zWzYdLpscveY4mY1NSYAVM4fDPvRkIDuSOQ,22905
129
129
  simo/core/__pycache__/api_auth.cpython-312.pyc,sha256=OreF9SvNrzUKgFBJ42ZA8MJjaC2XAOj04njdEk6-scw,2132
130
130
  simo/core/__pycache__/api_auth.cpython-38.pyc,sha256=mi3mu5qEKio_PvfQEvr3Q6AhdPLAHxzxAxrMbAz_pKU,1712
@@ -142,7 +142,7 @@ simo/core/__pycache__/base_types.cpython-312.pyc,sha256=Lnq2NL9B5hfwJARJYC447Rdv
142
142
  simo/core/__pycache__/base_types.cpython-38.pyc,sha256=CX-qlF7CefRi_mCE954wYa9rUFR88mOl6g7fybDRu7g,803
143
143
  simo/core/__pycache__/context.cpython-312.pyc,sha256=8rsN2Er-Sx3rrVmO0Gk4cem3euGh0kTELXj667GGZ5E,2193
144
144
  simo/core/__pycache__/context.cpython-38.pyc,sha256=NlTHt2GvXxA21AhBkeyOLfRFUuXw7wmwqyNhhcDl2cw,1373
145
- simo/core/__pycache__/controllers.cpython-312.pyc,sha256=T14yGqHLl-fAFMjvb0ITEmZo-3WT5Gj7TWmX2ZkfAcU,53852
145
+ simo/core/__pycache__/controllers.cpython-312.pyc,sha256=mbnxFDZniVSHOPfIQ9S9R5aEZfrZrklsYWmJw9MXbXE,53852
146
146
  simo/core/__pycache__/controllers.cpython-38.pyc,sha256=LtrQQ8egOIOuQbAckeM-z8OfbzS4W8VQ3vBnryAm3iU,32086
147
147
  simo/core/__pycache__/dynamic_settings.cpython-312.pyc,sha256=WUZ6XF4kZb6zPf541PkKmiQaBIw-r5C6F3EUUZiTEnE,3331
148
148
  simo/core/__pycache__/dynamic_settings.cpython-38.pyc,sha256=wGpnscX1DxFpRl54MQURhjz2aD3NJohSzw9JCFnzh2Y,2384
@@ -170,7 +170,7 @@ simo/core/__pycache__/routing.cpython-312.pyc,sha256=bDvF5HTZ8POSOHKwREyhSPO7oh9
170
170
  simo/core/__pycache__/routing.cpython-38.pyc,sha256=3T3FPJ8Cn99xZCGvMyg2xjl7al-Shm9CelbSpkJtNP8,599
171
171
  simo/core/__pycache__/serializers.cpython-312.pyc,sha256=LW6xmjKG5Ex5y8kslVd2xGy9eRqjNP2E29GxdJaAq48,32997
172
172
  simo/core/__pycache__/serializers.cpython-38.pyc,sha256=H3K_retN44wOj-ew0cvoxUSXqrUOhHCMV_oJabNF0Xg,20431
173
- simo/core/__pycache__/signal_receivers.cpython-312.pyc,sha256=MW6xZvs4mbZglSmB6cEhm9T99x6ohYoh-ZIl5MBPElo,9032
173
+ simo/core/__pycache__/signal_receivers.cpython-312.pyc,sha256=tA5hMaZQcvLiC-3UxpjNeZ2zf0EBhFm0-0XAxxPBHSo,9896
174
174
  simo/core/__pycache__/signal_receivers.cpython-38.pyc,sha256=R_h1GHkoZXR-nrwiRJWQ9xE69JB1R_mP_fNYIBX4lrE,5165
175
175
  simo/core/__pycache__/socket_consumers.cpython-312.pyc,sha256=Yph9SQTj6c3xr2HXKnSm7r2M7dp1ks2lp8Q6v8TJ7cM,15322
176
176
  simo/core/__pycache__/socket_consumers.cpython-38.pyc,sha256=Mr1-x-vGjBNffbz0S6AKpJCuzHJgRm8kXefv3qVVY_E,8397
@@ -10405,7 +10405,7 @@ simo/core/utils/__pycache__/validators.cpython-312.pyc,sha256=w8-XwptooefG-7gIIn
10405
10405
  simo/core/utils/__pycache__/validators.cpython-38.pyc,sha256=gjeBOjL_keMoRDjdn8v-3F3wcjPIT3Xx5KpTalo0e-Y,1247
10406
10406
  simo/fleet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10407
10407
  simo/fleet/admin.py,sha256=J_kiwYIGMTxnRuytl_YoM7Pxrj5LzlN9xC8E7Ag5yvQ,7006
10408
- simo/fleet/api.py,sha256=rJwAYJvp0uslW7O6Q4XOpOa8hfCdy3keUD7b3UNL43E,3424
10408
+ simo/fleet/api.py,sha256=Ja8N3QwoTYebKvi4hCoUrKZim77SWKnD8_Dv3WsHY-g,3691
10409
10409
  simo/fleet/apps.py,sha256=je8mRXMcRq4lABQZlyF2G2hOCkBUicR9I2jvrLDA8eI,238
10410
10410
  simo/fleet/auto_urls.py,sha256=vrfrooPyY4pDuQjya-eLxCgZldfhwbEeEiXa7diO_CY,847
10411
10411
  simo/fleet/base_types.py,sha256=wL9RVkHr0gA7HI1wZq0pruGEIgvQqpfnCL4cC3ywsvw,102
@@ -10425,7 +10425,7 @@ simo/fleet/__pycache__/__init__.cpython-312.pyc,sha256=-BZyG4uq87W18Ra1pKTjSzDgi
10425
10425
  simo/fleet/__pycache__/__init__.cpython-38.pyc,sha256=pIZE7EL6-cuJ3pQtaSwjKLrKLsTYelp1k9sRhXKLh6s,159
10426
10426
  simo/fleet/__pycache__/admin.cpython-312.pyc,sha256=8TOuku1Atv-LyaVi4OICTc43iBFPgxCjrgjA9q6CN1s,9890
10427
10427
  simo/fleet/__pycache__/admin.cpython-38.pyc,sha256=iweeu5AkaggBhQntP6-VF_eEodkNc6E7zKy0VjfwC2o,6652
10428
- simo/fleet/__pycache__/api.cpython-312.pyc,sha256=OM7s1FqGqTC2vwOOto0GhZrObEnI58SxMcTWaPtHD4Y,5892
10428
+ simo/fleet/__pycache__/api.cpython-312.pyc,sha256=DdWj8a7GSyiTthkZ52QyR6ED0ZXGopE5IpiS8XzxGn4,6353
10429
10429
  simo/fleet/__pycache__/api.cpython-38.pyc,sha256=rZ1mkfkaMBEXhi9sw_jTKdk2CPJhBNxoImtjQ3Rf1VY,4016
10430
10430
  simo/fleet/__pycache__/apps.cpython-312.pyc,sha256=S8OK4R0W9VbNfD4Nos_CybjZ3AXS8CxvRaRUJO57xQA,707
10431
10431
  simo/fleet/__pycache__/auto_urls.cpython-312.pyc,sha256=32yXKNoqMxNgYvsspUgx1A84LVQqr8LP4BRvURNCgeY,1026
@@ -10596,7 +10596,7 @@ simo/fleet/templates/fleet/controllers_info/ENS160AirQualitySensor.md,sha256=3LS
10596
10596
  simo/generic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10597
10597
  simo/generic/app_widgets.py,sha256=y8W3jR76Hh26O9pPQyg2SophMbYIOtAWD33MPKbB8Mg,856
10598
10598
  simo/generic/base_types.py,sha256=u3SlfpNYaCwkVBwomWgso4ODzL71ay9MhiAW-bxgnDU,341
10599
- simo/generic/controllers.py,sha256=n2qb_ipPHgSX5aW5kuhmQJOh244BVgBp37CUS_AOqxQ,46402
10599
+ simo/generic/controllers.py,sha256=JQnRl_gbaX0rzPhr4wORnBiswRJePEq9VZA_KsoN4VA,46410
10600
10600
  simo/generic/forms.py,sha256=GJ17Ah00NlfqkD1Smt_Hu5U2fAg_S7QMVDObSfsBZqk,26347
10601
10601
  simo/generic/gateways.py,sha256=kjqGMjlLXlGNreKLQtHoSnw4xan1IB8-KF8AqiZ82T0,16057
10602
10602
  simo/generic/models.py,sha256=59fkYowOX0imviIhA6uwupvuharrpBykmBm674rJNoI,7279
@@ -10609,7 +10609,7 @@ simo/generic/__pycache__/app_widgets.cpython-312.pyc,sha256=ywoKk91YSEZxpyt9haG5
10609
10609
  simo/generic/__pycache__/app_widgets.cpython-38.pyc,sha256=D9b13pbMlirgHmjDnQhfLIDGSVINoSouHb4SWOeCRrs,1642
10610
10610
  simo/generic/__pycache__/base_types.cpython-312.pyc,sha256=h8Mwu49i-zmwTbL33JaLJfRDGOgkQh2_VqrfzEc4UQ4,616
10611
10611
  simo/generic/__pycache__/base_types.cpython-38.pyc,sha256=aV5NdIuvXR-ItKpI__MwcyPZHD6Z882TFdgYkPCkr1I,493
10612
- simo/generic/__pycache__/controllers.cpython-312.pyc,sha256=Y3jut3t_Dq-s_-ZkHqgvQBQMtpytefQIHtyPoBLVDBo,53021
10612
+ simo/generic/__pycache__/controllers.cpython-312.pyc,sha256=ihZ7CV_OKrnZYift5uROgu_fSbvUFebTQlpVHsz6CVg,53145
10613
10613
  simo/generic/__pycache__/controllers.cpython-38.pyc,sha256=jJjwKVaDYyazrRGNjUFoY74nr_jX_DEnsC9KjyxZCgc,30427
10614
10614
  simo/generic/__pycache__/forms.cpython-312.pyc,sha256=tFyHfKkUz_V5aL7_BHTTCreE5Vbk_iW4bDCSd9wT_cQ,34869
10615
10615
  simo/generic/__pycache__/forms.cpython-38.pyc,sha256=k8lz3taXdWAg5P9jcnw66mWH51pCc4SOsg32kVEtBCg,19416
@@ -10744,16 +10744,16 @@ simo/users/__init__.py,sha256=6a7uBpCWB_DR7p54rbHusc0xvi1qfT1ZCCQGb6TiBh8,52
10744
10744
  simo/users/admin.py,sha256=2J_ZwrwAPw03Stb6msx5GvRpGCsDSC39RPpYBLGf8UY,7441
10745
10745
  simo/users/api.py,sha256=hOLwJhA5Ik8UbW0Qmp2Vl7tB8_uDHnP4EZq-OSaknyw,13218
10746
10746
  simo/users/apps.py,sha256=cq0A8-U1HALEwev0TicgFhr4CAu7Icz8rwq0HfOaL4E,207
10747
- simo/users/auth_backends.py,sha256=KIw2AdjCUKfm_7Lql6aC4qdE6JznP0ECIMA5MVMLeiM,4251
10747
+ simo/users/auth_backends.py,sha256=HxRp9iFvU1KqUhE7pA9YKEjqtBCJDbDqk_UMCD2Dwww,4361
10748
10748
  simo/users/auto_urls.py,sha256=RSUW3ai5LbMTknS8M7M5aOnG_YlFOVQrnNVNH-fkwlg,357
10749
10749
  simo/users/dynamic_settings.py,sha256=sEIsi4yJw3kH46Jq_aOkSuK7QTfQACGUE-lkyBogCaM,570
10750
10750
  simo/users/managers.py,sha256=OHgEP85MBtdkdYxdstBd8RavTBT8F_2WyDxUJ9aCqqM,246
10751
10751
  simo/users/middleware.py,sha256=tNPmnzo0eTrJ25SLHP7NotqYKI2cKnmv8hf6v5DLOWo,427
10752
- simo/users/models.py,sha256=EUsYX8PtPgRkpmCZXg0mRkYHV6e69TqGB-UkbZGe5Cw,20549
10752
+ simo/users/models.py,sha256=TKHs7mVjVC84WK-qXDz--4YfaD_TsUDrxxZ-oEXF-Pc,20527
10753
10753
  simo/users/permissions.py,sha256=IwtYS8yQdupWbYKR9VimSRDV3qCJ2jXP57Lyjpb2EQM,242
10754
- simo/users/serializers.py,sha256=REgXD9Af6nTRu_wUm1dt5YoCB6C_KNDaPqHZj726zZ0,2497
10754
+ simo/users/serializers.py,sha256=Uy5JsZp6nEGNMuK9HgLbA0KJdsbjG8GDIyF7z7Ue_so,2610
10755
10755
  simo/users/sso_urls.py,sha256=gQOaPvGMYFD0NCVSwyoWO-mTEHe5j9sbzV_RK7kdvp0,251
10756
- simo/users/sso_views.py,sha256=5J0D4qUFQDvd-Fcqx_xLJWLJgPdqtVD5DDiPJyPsT2Q,4336
10756
+ simo/users/sso_views.py,sha256=qHjiw3Ru-hWZRJAcLJa46DrQuDORl5ZKUHgRwmN3XlE,4335
10757
10757
  simo/users/tasks.py,sha256=FhbczWFHRFI6To4xqkx4gUX4p0vCwwTT297GWBPAoIg,1162
10758
10758
  simo/users/utils.py,sha256=vR5SlWdMKkMgNZdJXUI14pASVue8WMqJSQpVKruX25I,2305
10759
10759
  simo/users/views.py,sha256=iIfv8DqNztzBB3fiZcnHOyzp4eFtjrC-gCv5rBX3XsQ,4136
@@ -10765,7 +10765,7 @@ simo/users/__pycache__/api.cpython-312.pyc,sha256=p8nEOe95slqWK0QxhAkmXXbyPiZd-0
10765
10765
  simo/users/__pycache__/api.cpython-38.pyc,sha256=zZ4DfNktgeVvLAtMpaPUv7AoAgbKr7SCt-4ghJk1zp4,10386
10766
10766
  simo/users/__pycache__/apps.cpython-312.pyc,sha256=6KefztC11cSg6VHJ7-sVDvOA-oq_jNMB8jMvmhcVZD4,707
10767
10767
  simo/users/__pycache__/apps.cpython-38.pyc,sha256=dgbWL8CxzzISJQTmq_4IztPJ2UzykNVdqA2Ae1PmeGk,605
10768
- simo/users/__pycache__/auth_backends.cpython-312.pyc,sha256=63popQIO8sxcaOGOWxol_5RpKNbYiQhJtPEWEm31xc4,5469
10768
+ simo/users/__pycache__/auth_backends.cpython-312.pyc,sha256=NrdX57hAzX0sRI7BHiSxkGPpa8xB3XDsheYqBsjDYXs,5559
10769
10769
  simo/users/__pycache__/auth_backends.cpython-38.pyc,sha256=jYS2hlbTZh_ZtPeWcN50pc0IpyfCSO7_MvIbuVwEp8M,3144
10770
10770
  simo/users/__pycache__/auto_urls.cpython-312.pyc,sha256=nRaBVD1YnibleMC8AdZdk1ZpwEgMyIPm9VW0quIuj5E,565
10771
10771
  simo/users/__pycache__/auto_urls.cpython-38.pyc,sha256=bc6BOgghLdMzUroGMj7eB6YX9kIDWB9JvTc0iJQrEa4,478
@@ -10775,15 +10775,15 @@ simo/users/__pycache__/managers.cpython-312.pyc,sha256=A9-yF1dilDc1H_-BtrIw9USpH
10775
10775
  simo/users/__pycache__/managers.cpython-38.pyc,sha256=O0Y8ABp42RAosrbODmYsPMaj9AyOPyJ-aqzuO0Qpi2s,679
10776
10776
  simo/users/__pycache__/middleware.cpython-312.pyc,sha256=9pkiIkMriu0ExLK479hyPfaN-DOfp6WErqQlrZY1Mvk,927
10777
10777
  simo/users/__pycache__/middleware.cpython-38.pyc,sha256=Tj4nVEAvxEW3xA63fBRiJWRJpz_M848ZOqbHioc_IPE,1149
10778
- simo/users/__pycache__/models.cpython-312.pyc,sha256=DownCK4FLYKjE-QMM1-ciZ0koLzwsnc_RFgyq5sIi8k,29596
10778
+ simo/users/__pycache__/models.cpython-312.pyc,sha256=52wjquH0mXIIWZ0oGaJiM6fXnyg7zTi4zeBVRQ2dIMo,29546
10779
10779
  simo/users/__pycache__/models.cpython-38.pyc,sha256=qNtAn_eWVmRTWhTxN8GtCc549dcJsTdaF7Uk19yNMgg,18330
10780
10780
  simo/users/__pycache__/permissions.cpython-312.pyc,sha256=NCaxeIz4qmG_mF18lKTYXqOSUvJkFLnUZjfYIQFUCkU,718
10781
10781
  simo/users/__pycache__/permissions.cpython-38.pyc,sha256=ez5NxoL_JUeeH6GsKhvFreuA3FCBgGf9floSypdXUtM,633
10782
- simo/users/__pycache__/serializers.cpython-312.pyc,sha256=2xqTf8TIqmt7mKNEPfc6Aiy1iVShNShKugNGMIyttCQ,4751
10782
+ simo/users/__pycache__/serializers.cpython-312.pyc,sha256=LOqzwbP1wL2UYErYR6C9jPSR4KAq4e_zfsWZtgaT0Qs,4938
10783
10783
  simo/users/__pycache__/serializers.cpython-38.pyc,sha256=Dy8RAcwNkNSXoJHvLp8fozURyHCtucqpSPyqZtbnMZc,3732
10784
10784
  simo/users/__pycache__/sso_urls.cpython-312.pyc,sha256=FQLOFu310j7pOhTNlg2wyUybqts1anZnLTLbYaSpi7U,534
10785
10785
  simo/users/__pycache__/sso_urls.cpython-38.pyc,sha256=uAwDozpOmrhUald-8tOHANILXkH7-TI8fNYXOtPkSY8,402
10786
- simo/users/__pycache__/sso_views.cpython-312.pyc,sha256=FZGDRdt7pb8qROe8ZAEGSTfeZtLCGNBvQiXpDtrc4dE,6011
10786
+ simo/users/__pycache__/sso_views.cpython-312.pyc,sha256=H_QKISIIAr4NQKwesU83qlp_Tpp-JdJi-9zigc4RzFU,6011
10787
10787
  simo/users/__pycache__/sso_views.cpython-38.pyc,sha256=PLRF6FYCxRhnmgnN_gUS-pdQlH7lofLU1Xhgw3vDO_Y,4019
10788
10788
  simo/users/__pycache__/tasks.cpython-312.pyc,sha256=cu-VV1HWXToHR875DFC2E9_x1cn1mD5mXYqltk0QOuw,1955
10789
10789
  simo/users/__pycache__/tasks.cpython-38.pyc,sha256=XLMKt3suT7BlcXrJZoH9ZIhhtBuqyiW4lsOB9IbBkko,1225
@@ -10933,9 +10933,9 @@ simo/users/templates/invitations/expired_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCe
10933
10933
  simo/users/templates/invitations/expired_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10934
10934
  simo/users/templates/invitations/taken_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10935
10935
  simo/users/templates/invitations/taken_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10936
- simo-2.8.13.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
10937
- simo-2.8.13.dist-info/METADATA,sha256=As563zVMgLqQ9Ixf4QReHUSn3_uB8XWgno_z8LUnVOI,2006
10938
- simo-2.8.13.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
10939
- simo-2.8.13.dist-info/entry_points.txt,sha256=S9PwnUYmTSW7681GKDCxUbL0leRJIaRk6fDQIKgbZBA,135
10940
- simo-2.8.13.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
10941
- simo-2.8.13.dist-info/RECORD,,
10936
+ simo-2.8.14.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
10937
+ simo-2.8.14.dist-info/METADATA,sha256=S-5QLByGR7buSxLAJtReVr_3LnccUxAziVxUnxZiqzI,2006
10938
+ simo-2.8.14.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
10939
+ simo-2.8.14.dist-info/entry_points.txt,sha256=S9PwnUYmTSW7681GKDCxUbL0leRJIaRk6fDQIKgbZBA,135
10940
+ simo-2.8.14.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
10941
+ simo-2.8.14.dist-info/RECORD,,
File without changes