simo 2.5.9__py3-none-any.whl → 2.5.11__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/api.py CHANGED
@@ -175,10 +175,10 @@ def get_components_queryset(instance, user):
175
175
  c_ids.add(state['id'])
176
176
 
177
177
  user_role = user.get_role(instance)
178
-
179
- for cp in user_role.component_permissions.all():
180
- if cp.read:
181
- c_ids.add(cp.component.id)
178
+ if user_role:
179
+ for cp in user_role.component_permissions.all():
180
+ if cp.read:
181
+ c_ids.add(cp.component.id)
182
182
 
183
183
  return qs.filter(id__in=c_ids).select_related(
184
184
  'zone', 'category', 'icon'
@@ -134,6 +134,8 @@ class ComponentAutocomplete(autocomplete.Select2QuerySetView):
134
134
  return qs.distinct()
135
135
 
136
136
  def get_result_label(self, item):
137
+ if self.request.META.get('HTTP_USER_AGENT') == 'SIMO-app':
138
+ return super().get_result_label(item)
137
139
  return render_to_string(
138
140
  'core/object_acutocomplete_select_item.html', {
139
141
  'object': item
simo/core/serializers.py CHANGED
@@ -104,6 +104,34 @@ class HiddenSerializerField(serializers.CharField):
104
104
  class TextAreaSerializerField(serializers.CharField):
105
105
  pass
106
106
 
107
+ class ComponentPrimaryKeyRelatedField(PrimaryKeyRelatedField):
108
+
109
+ def get_attribute(self, instance):
110
+ if self.queryset.model in (Icon, Zone, Category):
111
+ return super().get_attribute(instance)
112
+ return self.queryset.model.objects.filter(
113
+ pk=instance.config.get(self.source_attrs[0])
114
+ ).first()
115
+
116
+
117
+ class ComponentManyToManyRelatedField(serializers.Field):
118
+
119
+ def __init__(self, *args, **kwargs):
120
+ self.queryset = kwargs.pop('queryset')
121
+ self.choices = {obj.pk: str(obj) for obj in self.queryset}
122
+ self.allow_blank = kwargs.pop('allow_blank', False)
123
+ super().__init__(*args, **kwargs)
124
+
125
+
126
+ def to_representation(self, value):
127
+ return [obj.pk for obj in value.all()]
128
+
129
+ def to_internal_value(self, data):
130
+ if data == [] and self.allow_blank:
131
+ return []
132
+ return self.queryset.filter(pk__in=data)
133
+
134
+
107
135
 
108
136
  class ComponentFormsetField(FormSerializer):
109
137
 
@@ -114,6 +142,10 @@ class ComponentFormsetField(FormSerializer):
114
142
  field_mapping = {
115
143
  HiddenField: HiddenSerializerField,
116
144
  Select2ListChoiceField: serializers.ChoiceField,
145
+ Select2ModelChoiceField: ComponentPrimaryKeyRelatedField,
146
+ forms.ModelMultipleChoiceField: ComponentManyToManyRelatedField,
147
+ Select2ListMultipleChoiceField: ComponentManyToManyRelatedField,
148
+ Select2ModelMultipleChoiceField: ComponentManyToManyRelatedField,
117
149
  forms.ModelChoiceField: FormsetPrimaryKeyRelatedField,
118
150
  forms.TypedChoiceField: serializers.ChoiceField,
119
151
  forms.FloatField: serializers.FloatField,
@@ -167,8 +199,18 @@ class ComponentFormsetField(FormSerializer):
167
199
  def _get_field_kwargs(self, form_field, serializer_field_class):
168
200
  kwargs = super()._get_field_kwargs(form_field, serializer_field_class)
169
201
  kwargs['style'] = {'form_field': form_field}
170
- if serializer_field_class == FormsetPrimaryKeyRelatedField:
171
- kwargs['queryset'] = form_field.queryset
202
+
203
+ if serializer_field_class in (
204
+ ComponentPrimaryKeyRelatedField, ComponentManyToManyRelatedField
205
+ ):
206
+ qs = form_field.queryset
207
+ if hasattr(qs.model, 'instance'):
208
+ qs = qs.filter(instance=self.context['instance'])
209
+ elif hasattr(qs.model, 'instances'):
210
+ qs = qs.filter(instances=self.context['instance'])
211
+ elif qs.model == Component:
212
+ qs = qs.filter(zone__instance=self.context['instance'])
213
+ kwargs['queryset'] = qs
172
214
 
173
215
  attrs = find_matching_class_kwargs(form_field, serializer_field_class)
174
216
  if 'choices' in attrs:
@@ -176,6 +218,7 @@ class ComponentFormsetField(FormSerializer):
176
218
 
177
219
  return kwargs
178
220
 
221
+
179
222
  def to_representation(self, instance):
180
223
  """
181
224
  Object instance -> Dict of primitive datatypes.
@@ -211,32 +254,6 @@ class ComponentFormsetField(FormSerializer):
211
254
  return validated_data
212
255
 
213
256
 
214
- class ComponentPrimaryKeyRelatedField(PrimaryKeyRelatedField):
215
-
216
- def get_attribute(self, instance):
217
- if self.queryset.model in (Icon, Zone, Category):
218
- return super().get_attribute(instance)
219
- return self.queryset.model.objects.filter(
220
- pk=instance.config.get(self.source_attrs[0])
221
- ).first()
222
-
223
-
224
- class ComponentManyToManyRelatedField(serializers.Field):
225
-
226
- def __init__(self, *args, **kwargs):
227
- self.queryset = kwargs.pop('queryset')
228
- self.choices = {obj.pk: str(obj) for obj in self.queryset}
229
- self.allow_blank = kwargs.pop('allow_blank', False)
230
- super().__init__(*args, **kwargs)
231
-
232
-
233
- def to_representation(self, value):
234
- return [obj.pk for obj in value.all()]
235
-
236
- def to_internal_value(self, data):
237
- if data == [] and self.allow_blank:
238
- return []
239
- return self.queryset.filter(pk__in=data)
240
257
 
241
258
 
242
259
  class ComponentSerializer(FormSerializer):
@@ -291,7 +308,6 @@ class ComponentSerializer(FormSerializer):
291
308
  self.instance = Component.objects.filter(id=res[0]).first()
292
309
 
293
310
  def get_fields(self):
294
-
295
311
  self.set_form_cls()
296
312
 
297
313
  ret = OrderedDict()
simo/generic/forms.py CHANGED
@@ -271,7 +271,7 @@ class PresenceLightingConfigForm(BaseComponentForm):
271
271
  ['lights', 'on_value', 'off_value', 'presence_sensors',
272
272
  'act_on', 'hold_time', 'conditions', 'autostart', 'keep_alive']
273
273
  )
274
- if self.instance.pk:
274
+ if self.instance.pk and 'log' in self.fields:
275
275
  prefix = get_script_prefix()
276
276
  if prefix == '/':
277
277
  prefix = ''
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: simo
3
- Version: 2.5.9
3
+ Version: 2.5.11
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
@@ -33,13 +33,13 @@ simo/backups/migrations/__pycache__/0004_alter_backup_options_alter_backuplog_op
33
33
  simo/backups/migrations/__pycache__/__init__.cpython-38.pyc,sha256=Lz1fs6V05h2AoxTOLNye0do9bEMnyuaXB_hHOjG5-HU,172
34
34
  simo/core/__init__.py,sha256=_s2TjJfQImsMrTIxqLAx9AZie1Ojmm6sCHASdl3WLGU,50
35
35
  simo/core/admin.py,sha256=5mi0Qe9TM-OILCxbcRfGJvq397QCPxjYX30K3CIZrPs,18133
36
- simo/core/api.py,sha256=A8P47OFFcqw-AXQPF3XqIV3pshEyqQGwLdM8aByddns,28288
36
+ simo/core/api.py,sha256=KIy7mpNbMWKtNPrcnbzeHXmPRboF5RPxmi_NssJXkQk,28317
37
37
  simo/core/api_auth.py,sha256=vCxvczA8aWNcW0VyKs5WlC_ytlqeGP_H_hkKUNVkCwM,1247
38
38
  simo/core/api_meta.py,sha256=EaiY-dCADP__9MvLpoHvhjytFT92IrxPZDv95xgqasU,4955
39
39
  simo/core/app_widgets.py,sha256=VxZzapuc-a29wBH7JzpvNF2SK1ECrgNUySId5ke1ffc,2509
40
40
  simo/core/apps.py,sha256=CsqpiQerhmrMsH-wGiG-gQgXd9qEkIi-LUaA9cXpKSw,425
41
41
  simo/core/auto_urls.py,sha256=nNXEgLAAAQAhRWQDA9AbDtw-zcPKmu_pufJaSa8g818,1102
42
- simo/core/autocomplete_views.py,sha256=JT5LA2_Wtr60XYSAIqaXFKFYPjrmkEf6yunXD9y2zco,4022
42
+ simo/core/autocomplete_views.py,sha256=NEzZ27h5VRWqipwYdKrxlGl7GCaA_i8ho2nibpS6FiQ,4139
43
43
  simo/core/base_types.py,sha256=WypW8hTfzveuTQtruGjLYAGQZIuczxTlW-SdRk3iQug,666
44
44
  simo/core/context.py,sha256=snfPIGcZQTrx8iiZc5PI91A0dRQH6y5kH4uG_lfhU6Q,1486
45
45
  simo/core/controllers.py,sha256=JvXdwXD7iotA7fIjZmBVshKLQGSt9Na48FMAyHRDh84,35615
@@ -55,7 +55,7 @@ simo/core/middleware.py,sha256=hExD7Vmw7eitk0vAjOwKzkwrtuw8YxpflF92j_CA2YY,3193
55
55
  simo/core/models.py,sha256=Z6WLvU4K-LWIXghCBwTyZAOW5n2hCFNU-pteiPnpOAQ,22617
56
56
  simo/core/permissions.py,sha256=v0iJM4LOeYoEfMiw3OLPYio272G1aUEAg_z9Wd1q5m0,2993
57
57
  simo/core/routing.py,sha256=X1_IHxyA-_Q7hw1udDoviVP4_FSBDl8GYETTC2zWTbY,499
58
- simo/core/serializers.py,sha256=JoMsGoeeTfnoNSdLPMlx4ZbaFyhtw5Kh4KpbAIUovX8,20869
58
+ simo/core/serializers.py,sha256=i6AWIfhJq86AHs8jq3GrCfW3iSQDS3fQiLmcjHd3K5E,21593
59
59
  simo/core/signal_receivers.py,sha256=qCpzEUv5Bl9--K8fe08GVDmE6EBOj292YBia1TYDdSE,9267
60
60
  simo/core/socket_consumers.py,sha256=trRZvBGTJ7xIbfdmVvn7zoiWp_qssSkMZykDrI5YQyE,9783
61
61
  simo/core/storage.py,sha256=_5igjaoWZAiExGWFEJMElxUw55DzJG1jqFty33xe8BE,342
@@ -88,7 +88,7 @@ simo/core/__pycache__/middleware.cpython-38.pyc,sha256=iOSTXSQl3sEsa-9kx_6w5zbEB
88
88
  simo/core/__pycache__/models.cpython-38.pyc,sha256=Nw2Fb11EwBdMVTHCpzkY6x0hRNCqRo0RtLNlRxS1VZE,18534
89
89
  simo/core/__pycache__/permissions.cpython-38.pyc,sha256=fH4iyqd9DdzRLEu2b621-FeM-napR0M7hzBUTHo9Q3g,2972
90
90
  simo/core/__pycache__/routing.cpython-38.pyc,sha256=3T3FPJ8Cn99xZCGvMyg2xjl7al-Shm9CelbSpkJtNP8,599
91
- simo/core/__pycache__/serializers.cpython-38.pyc,sha256=S4eNvJkMZO98FQXgNGbeKBJihG5LXdnhl0tm2tjjXTE,19266
91
+ simo/core/__pycache__/serializers.cpython-38.pyc,sha256=fN3kkfxFbQczNkAoghp_mjuXEuFhpiecd87MB3cXW6k,19483
92
92
  simo/core/__pycache__/signal_receivers.cpython-38.pyc,sha256=lBVca6zNPVn3Ev98ekjPGzBR1MJk4xI19CyMcm4lf6A,7056
93
93
  simo/core/__pycache__/socket_consumers.cpython-38.pyc,sha256=KqbO1cOewodVPcy0-htVefyUjCuELKV0o7fOfYqfgPc,8490
94
94
  simo/core/__pycache__/storage.cpython-38.pyc,sha256=9R1Xu0FJDflfRXUPsqEgt0SpwiP7FGk7HaR8s8XRyI8,721
@@ -10337,7 +10337,7 @@ simo/generic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10337
10337
  simo/generic/app_widgets.py,sha256=vwYYVRKzKZ9XTvWTfEbaH4zpoHiDIHP6qFTNgZI-xvY,979
10338
10338
  simo/generic/base_types.py,sha256=Bvf3lv6PXx_SwtwBH7qpkwysWuloNcKNRh3LiuZf-Dc,359
10339
10339
  simo/generic/controllers.py,sha256=kGYdcuU7kpbhb6QeuOo4l-W82Zldh8vpdMnJRMKCkgU,49378
10340
- simo/generic/forms.py,sha256=oAvWeYzLyWiNLRnXGa2124ICRD7GpLwwsF6i6L56HCI,29044
10340
+ simo/generic/forms.py,sha256=vXQ7bQV4SmYx5hbCIZFvCYZ3rJJfx4SpDJgNy8sCioE,29069
10341
10341
  simo/generic/gateways.py,sha256=dUzRBxVDdsx70mrCvxSQwhJr0ydQ5NtoLHoYeVLJmtA,15224
10342
10342
  simo/generic/models.py,sha256=Adq7ipWK-renxJlNW-SZnAq2oGEOwKx8EdUWaKnfcVQ,7597
10343
10343
  simo/generic/routing.py,sha256=elQVZmgnPiieEuti4sJ7zITk1hlRxpgbotcutJJgC60,228
@@ -10551,9 +10551,9 @@ simo/users/templates/invitations/expired_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCe
10551
10551
  simo/users/templates/invitations/expired_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10552
10552
  simo/users/templates/invitations/taken_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10553
10553
  simo/users/templates/invitations/taken_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10554
- simo-2.5.9.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
10555
- simo-2.5.9.dist-info/METADATA,sha256=seKSLClAKBnMi8ejXmRi6A8gouqbRobDzkzLi4yiFvc,1923
10556
- simo-2.5.9.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
10557
- simo-2.5.9.dist-info/entry_points.txt,sha256=S9PwnUYmTSW7681GKDCxUbL0leRJIaRk6fDQIKgbZBA,135
10558
- simo-2.5.9.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
10559
- simo-2.5.9.dist-info/RECORD,,
10554
+ simo-2.5.11.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
10555
+ simo-2.5.11.dist-info/METADATA,sha256=EA87aQ2mip3VAeGWmYPF2WzEPLqpjFR_cu7NSzd2XtE,1924
10556
+ simo-2.5.11.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
10557
+ simo-2.5.11.dist-info/entry_points.txt,sha256=S9PwnUYmTSW7681GKDCxUbL0leRJIaRk6fDQIKgbZBA,135
10558
+ simo-2.5.11.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
10559
+ simo-2.5.11.dist-info/RECORD,,
File without changes