simo 2.1.5__py3-none-any.whl → 2.1.7__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.

Files changed (35) hide show
  1. simo/core/__pycache__/api.cpython-38.pyc +0 -0
  2. simo/core/__pycache__/api_meta.cpython-38.pyc +0 -0
  3. simo/core/__pycache__/apps.cpython-38.pyc +0 -0
  4. simo/core/__pycache__/managers.cpython-38.pyc +0 -0
  5. simo/core/__pycache__/models.cpython-38.pyc +0 -0
  6. simo/core/__pycache__/permissions.cpython-38.pyc +0 -0
  7. simo/core/__pycache__/serializers.cpython-38.pyc +0 -0
  8. simo/core/__pycache__/signal_receivers.cpython-38.pyc +0 -0
  9. simo/core/__pycache__/tasks.cpython-38.pyc +0 -0
  10. simo/core/api.py +62 -7
  11. simo/core/api_meta.py +29 -6
  12. simo/core/apps.py +3 -0
  13. simo/core/managers.py +6 -0
  14. simo/core/migrations/0039_instance_is_active_alter_instance_timezone.py +23 -0
  15. simo/core/migrations/0040_alter_instance_name.py +18 -0
  16. simo/core/migrations/0041_alter_instance_slug.py +18 -0
  17. simo/core/migrations/__pycache__/0039_instance_is_active_alter_instance_timezone.cpython-38.pyc +0 -0
  18. simo/core/migrations/__pycache__/0040_alter_instance_name.cpython-38.pyc +0 -0
  19. simo/core/migrations/__pycache__/0041_alter_instance_slug.cpython-38.pyc +0 -0
  20. simo/core/models.py +11 -3
  21. simo/core/permissions.py +5 -1
  22. simo/core/serializers.py +18 -10
  23. simo/core/signal_receivers.py +2 -2
  24. simo/core/tasks.py +53 -43
  25. simo/management/install.py +1 -1
  26. simo/users/__pycache__/models.cpython-38.pyc +0 -0
  27. simo/users/migrations/0029_alter_instanceuser_instance.py +20 -0
  28. simo/users/migrations/__pycache__/0029_alter_instanceuser_instance.cpython-38.pyc +0 -0
  29. simo/users/models.py +2 -1
  30. {simo-2.1.5.dist-info → simo-2.1.7.dist-info}/METADATA +2 -1
  31. {simo-2.1.5.dist-info → simo-2.1.7.dist-info}/RECORD +35 -27
  32. {simo-2.1.5.dist-info → simo-2.1.7.dist-info}/WHEEL +1 -1
  33. {simo-2.1.5.dist-info → simo-2.1.7.dist-info}/LICENSE.md +0 -0
  34. {simo-2.1.5.dist-info → simo-2.1.7.dist-info}/entry_points.txt +0 -0
  35. {simo-2.1.5.dist-info → simo-2.1.7.dist-info}/top_level.txt +0 -0
Binary file
Binary file
Binary file
Binary file
simo/core/api.py CHANGED
@@ -35,11 +35,11 @@ from .permissions import (
35
35
  class InstanceMixin:
36
36
 
37
37
  def dispatch(self, request, *args, **kwargs):
38
- try:
39
- self.instance = Instance.objects.get(
40
- slug=self.request.resolver_match.kwargs.get('instance_slug')
41
- )
42
- except Instance.DoesNotExist:
38
+ self.instance = Instance.objects.filter(
39
+ slug=self.request.resolver_match.kwargs.get('instance_slug'),
40
+ is_active=True
41
+ ).last()
42
+ if not self.instance:
43
43
  raise Http404()
44
44
  return super().dispatch(request, *args, **kwargs)
45
45
 
@@ -515,6 +515,8 @@ class ActionsViewset(InstanceMixin, viewsets.ReadOnlyModelViewSet):
515
515
  class SettingsViewSet(InstanceMixin, viewsets.GenericViewSet):
516
516
  url = 'core/settings'
517
517
  basename = 'settings'
518
+ #http_method_names = ['get', 'head', 'options', 'patch']
519
+
518
520
 
519
521
  def list(self, request, format=None, *args, **kwargs):
520
522
  from simo.conf import dynamic_settings
@@ -551,14 +553,67 @@ class SettingsViewSet(InstanceMixin, viewsets.GenericViewSet):
551
553
  'timezone': self.instance.timezone,
552
554
  'location': self.instance.location,
553
555
  'last_event': last_event,
554
- 'indoor_climate_sensor': self.instance.indoor_climate_sensor_id,
555
556
  'weather_forecast': wf_comp_id,
556
557
  'main_alarm_group': main_alarm_group_id,
558
+ # TODO: Remove these two when the app is updated for everybody.
557
559
  'remote_http': dynamic_settings['core__remote_http'],
558
560
  'local_http': 'https://%s' % get_self_ip(),
559
- 'units_of_measure': self.instance.units_of_measure
561
+ 'units_of_measure': self.instance.units_of_measure,
562
+ # editable fields
563
+ 'history_days': self.instance.history_days,
564
+ 'device_report_history_days': self.instance.device_report_history_days,
565
+ 'indoor_climate_sensor': self.instance.indoor_climate_sensor_id,
560
566
  })
561
567
 
568
+ def update(self, request, *args, **kwargs):
569
+ data = request.data
570
+ if not isinstance(request.data, dict):
571
+ data = data.dict()
572
+ request_data = restore_json(data)
573
+ if 'history_days' in request_data:
574
+ try:
575
+ history_days = int(request_data['history_days'])
576
+ except:
577
+ raise APIValidationError(
578
+ _('Bad value for history days!'), code=400
579
+ )
580
+ if history_days < 0 or history_days > 365:
581
+ raise APIValidationError(
582
+ _('History days must be 0 - 365!'), code=400
583
+ )
584
+ self.instance.history_days = history_days
585
+ if 'device_report_history_days' in request_data:
586
+ try:
587
+ device_report_history_days = int(
588
+ request_data['device_report_history_days']
589
+ )
590
+ except:
591
+ raise APIValidationError(
592
+ _('Bad value for device_report_history_days days!'),
593
+ code=400
594
+ )
595
+ if device_report_history_days < 0 \
596
+ or device_report_history_days > 365:
597
+ raise APIValidationError(
598
+ _('History days must be 0 - 365!'), code=400
599
+ )
600
+ self.instance.device_report_history_days = device_report_history_days
601
+
602
+ self.instance.indoor_climate_sensor = Component.objects.filter(
603
+ id=request_data.get('indoor_climate_sensor', 0)
604
+ ).first()
605
+
606
+ self.instance.save()
607
+
608
+ return self.list(request)
609
+
610
+ def get_serializer_class(self):
611
+ from rest_framework.serializers import Serializer
612
+ return Serializer
613
+
614
+ def patch(self, request, *args, **kwargs):
615
+ return self.update(request, *args, **kwargs)
616
+
562
617
 
563
618
  class InfoViewSet(InstanceMixin, viewsets.GenericViewSet):
564
619
  url = 'core/info'
simo/core/api_meta.py CHANGED
@@ -4,10 +4,11 @@ from django.utils.encoding import force_str
4
4
  from rest_framework.metadata import SimpleMetadata
5
5
  from rest_framework import serializers
6
6
  from rest_framework.utils.field_mapping import ClassLookupDict
7
- from simo.core.models import Icon
7
+ from simo.core.models import Icon, Instance, Category, Zone
8
+ from simo.core.middleware import introduce_instance
8
9
  from .serializers import (
9
10
  HiddenSerializerField, ComponentManyToManyRelatedField,
10
- TextAreaSerializerField
11
+ TextAreaSerializerField, Component
11
12
  )
12
13
 
13
14
 
@@ -42,6 +43,16 @@ class SIMOAPIMetadata(SimpleMetadata):
42
43
  TextAreaSerializerField: 'textarea',
43
44
  })
44
45
 
46
+ def determine_metadata(self, request, view):
47
+ self.instance = getattr(view, 'instance', None)
48
+ if not self.instance:
49
+ self.instance = Instance.objects.filter(
50
+ slug=request.resolver_match.kwargs.get('instance_slug')
51
+ ).first()
52
+ if self.instance:
53
+ introduce_instance(self.instance)
54
+ return super().determine_metadata(request, view)
55
+
45
56
 
46
57
  def get_field_info(self, field):
47
58
 
@@ -85,12 +96,24 @@ class SIMOAPIMetadata(SimpleMetadata):
85
96
  elif getattr(field, 'fields', None):
86
97
  field_info['children'] = self.get_serializer_info(field)
87
98
 
88
- if form_field and hasattr(form_field, 'queryset') \
89
- and form_field.queryset.model == Icon:
90
- return field_info
99
+ if form_field and hasattr(form_field, 'queryset'):
100
+ if form_field.queryset.model == Icon:
101
+ return field_info
102
+ elif self.instance:
103
+ if hasattr(form_field.queryset.model, 'instance'):
104
+ form_field.queryset = form_field.queryset.filter(
105
+ instance=self.instance
106
+ )
107
+ elif hasattr(form_field.queryset.model, 'instances'):
108
+ form_field.queryset = form_field.queryset.filter(
109
+ instances=self.instance
110
+ )
111
+ if form_field.queryset.model == Component:
112
+ form_field.queryset = form_field.queryset.filter(
113
+ zone__instance=self.instance
114
+ )
91
115
 
92
116
  if not field_info.get('read_only') and hasattr(field, 'choices'):
93
- print(f"DO choices for: {field.label}")
94
117
  field_info['choices'] = [
95
118
  {
96
119
  'value': choice_value,
simo/core/apps.py CHANGED
@@ -9,5 +9,8 @@ class SIMOCoreAppConfig(AppConfig):
9
9
  from actstream import registry
10
10
  registry.register(self.get_model('Component'))
11
11
  registry.register(self.get_model('Gateway'))
12
+ registry.register(self.get_model('Instance'))
13
+ registry.register(self.get_model('Zone'))
14
+ registry.register(self.get_model('Category'))
12
15
 
13
16
 
simo/core/managers.py CHANGED
@@ -16,6 +16,12 @@ class ActionManager(OrgActionManager):
16
16
  return qs
17
17
 
18
18
 
19
+ class InstanceManager(models.Manager):
20
+
21
+ def get_queryset(self):
22
+ return super().get_queryset().filter(is_active=True)
23
+
24
+
19
25
  class ZonesManager(models.Manager):
20
26
 
21
27
  def get_queryset(self):
@@ -0,0 +1,23 @@
1
+ # Generated by Django 4.2.10 on 2024-06-25 12:40
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('core', '0038_remove_instance_cover_image_and_more'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AddField(
14
+ model_name='instance',
15
+ name='is_active',
16
+ field=models.BooleanField(db_index=True, default=True, help_text="Get's deactivated instead of delete."),
17
+ ),
18
+ migrations.AlterField(
19
+ model_name='instance',
20
+ name='timezone',
21
+ field=models.CharField(choices=[('Africa/Abidjan', 'Africa/Abidjan'), ('Africa/Accra', 'Africa/Accra'), ('Africa/Addis_Ababa', 'Africa/Addis_Ababa'), ('Africa/Algiers', 'Africa/Algiers'), ('Africa/Asmara', 'Africa/Asmara'), ('Africa/Asmera', 'Africa/Asmera'), ('Africa/Bamako', 'Africa/Bamako'), ('Africa/Bangui', 'Africa/Bangui'), ('Africa/Banjul', 'Africa/Banjul'), ('Africa/Bissau', 'Africa/Bissau'), ('Africa/Blantyre', 'Africa/Blantyre'), ('Africa/Brazzaville', 'Africa/Brazzaville'), ('Africa/Bujumbura', 'Africa/Bujumbura'), ('Africa/Cairo', 'Africa/Cairo'), ('Africa/Casablanca', 'Africa/Casablanca'), ('Africa/Ceuta', 'Africa/Ceuta'), ('Africa/Conakry', 'Africa/Conakry'), ('Africa/Dakar', 'Africa/Dakar'), ('Africa/Dar_es_Salaam', 'Africa/Dar_es_Salaam'), ('Africa/Djibouti', 'Africa/Djibouti'), ('Africa/Douala', 'Africa/Douala'), ('Africa/El_Aaiun', 'Africa/El_Aaiun'), ('Africa/Freetown', 'Africa/Freetown'), ('Africa/Gaborone', 'Africa/Gaborone'), ('Africa/Harare', 'Africa/Harare'), ('Africa/Johannesburg', 'Africa/Johannesburg'), ('Africa/Juba', 'Africa/Juba'), ('Africa/Kampala', 'Africa/Kampala'), ('Africa/Khartoum', 'Africa/Khartoum'), ('Africa/Kigali', 'Africa/Kigali'), ('Africa/Kinshasa', 'Africa/Kinshasa'), ('Africa/Lagos', 'Africa/Lagos'), ('Africa/Libreville', 'Africa/Libreville'), ('Africa/Lome', 'Africa/Lome'), ('Africa/Luanda', 'Africa/Luanda'), ('Africa/Lubumbashi', 'Africa/Lubumbashi'), ('Africa/Lusaka', 'Africa/Lusaka'), ('Africa/Malabo', 'Africa/Malabo'), ('Africa/Maputo', 'Africa/Maputo'), ('Africa/Maseru', 'Africa/Maseru'), ('Africa/Mbabane', 'Africa/Mbabane'), ('Africa/Mogadishu', 'Africa/Mogadishu'), ('Africa/Monrovia', 'Africa/Monrovia'), ('Africa/Nairobi', 'Africa/Nairobi'), ('Africa/Ndjamena', 'Africa/Ndjamena'), ('Africa/Niamey', 'Africa/Niamey'), ('Africa/Nouakchott', 'Africa/Nouakchott'), ('Africa/Ouagadougou', 'Africa/Ouagadougou'), ('Africa/Porto-Novo', 'Africa/Porto-Novo'), ('Africa/Sao_Tome', 'Africa/Sao_Tome'), ('Africa/Timbuktu', 'Africa/Timbuktu'), ('Africa/Tripoli', 'Africa/Tripoli'), ('Africa/Tunis', 'Africa/Tunis'), ('Africa/Windhoek', 'Africa/Windhoek'), ('America/Adak', 'America/Adak'), ('America/Anchorage', 'America/Anchorage'), ('America/Anguilla', 'America/Anguilla'), ('America/Antigua', 'America/Antigua'), ('America/Araguaina', 'America/Araguaina'), ('America/Argentina/Buenos_Aires', 'America/Argentina/Buenos_Aires'), ('America/Argentina/Catamarca', 'America/Argentina/Catamarca'), ('America/Argentina/ComodRivadavia', 'America/Argentina/ComodRivadavia'), ('America/Argentina/Cordoba', 'America/Argentina/Cordoba'), ('America/Argentina/Jujuy', 'America/Argentina/Jujuy'), ('America/Argentina/La_Rioja', 'America/Argentina/La_Rioja'), ('America/Argentina/Mendoza', 'America/Argentina/Mendoza'), ('America/Argentina/Rio_Gallegos', 'America/Argentina/Rio_Gallegos'), ('America/Argentina/Salta', 'America/Argentina/Salta'), ('America/Argentina/San_Juan', 'America/Argentina/San_Juan'), ('America/Argentina/San_Luis', 'America/Argentina/San_Luis'), ('America/Argentina/Tucuman', 'America/Argentina/Tucuman'), ('America/Argentina/Ushuaia', 'America/Argentina/Ushuaia'), ('America/Aruba', 'America/Aruba'), ('America/Asuncion', 'America/Asuncion'), ('America/Atikokan', 'America/Atikokan'), ('America/Atka', 'America/Atka'), ('America/Bahia', 'America/Bahia'), ('America/Bahia_Banderas', 'America/Bahia_Banderas'), ('America/Barbados', 'America/Barbados'), ('America/Belem', 'America/Belem'), ('America/Belize', 'America/Belize'), ('America/Blanc-Sablon', 'America/Blanc-Sablon'), ('America/Boa_Vista', 'America/Boa_Vista'), ('America/Bogota', 'America/Bogota'), ('America/Boise', 'America/Boise'), ('America/Buenos_Aires', 'America/Buenos_Aires'), ('America/Cambridge_Bay', 'America/Cambridge_Bay'), ('America/Campo_Grande', 'America/Campo_Grande'), ('America/Cancun', 'America/Cancun'), ('America/Caracas', 'America/Caracas'), ('America/Catamarca', 'America/Catamarca'), ('America/Cayenne', 'America/Cayenne'), ('America/Cayman', 'America/Cayman'), ('America/Chicago', 'America/Chicago'), ('America/Chihuahua', 'America/Chihuahua'), ('America/Coral_Harbour', 'America/Coral_Harbour'), ('America/Cordoba', 'America/Cordoba'), ('America/Costa_Rica', 'America/Costa_Rica'), ('America/Creston', 'America/Creston'), ('America/Cuiaba', 'America/Cuiaba'), ('America/Curacao', 'America/Curacao'), ('America/Danmarkshavn', 'America/Danmarkshavn'), ('America/Dawson', 'America/Dawson'), ('America/Dawson_Creek', 'America/Dawson_Creek'), ('America/Denver', 'America/Denver'), ('America/Detroit', 'America/Detroit'), ('America/Dominica', 'America/Dominica'), ('America/Edmonton', 'America/Edmonton'), ('America/Eirunepe', 'America/Eirunepe'), ('America/El_Salvador', 'America/El_Salvador'), ('America/Ensenada', 'America/Ensenada'), ('America/Fort_Nelson', 'America/Fort_Nelson'), ('America/Fort_Wayne', 'America/Fort_Wayne'), ('America/Fortaleza', 'America/Fortaleza'), ('America/Glace_Bay', 'America/Glace_Bay'), ('America/Godthab', 'America/Godthab'), ('America/Goose_Bay', 'America/Goose_Bay'), ('America/Grand_Turk', 'America/Grand_Turk'), ('America/Grenada', 'America/Grenada'), ('America/Guadeloupe', 'America/Guadeloupe'), ('America/Guatemala', 'America/Guatemala'), ('America/Guayaquil', 'America/Guayaquil'), ('America/Guyana', 'America/Guyana'), ('America/Halifax', 'America/Halifax'), ('America/Havana', 'America/Havana'), ('America/Hermosillo', 'America/Hermosillo'), ('America/Indiana/Indianapolis', 'America/Indiana/Indianapolis'), ('America/Indiana/Knox', 'America/Indiana/Knox'), ('America/Indiana/Marengo', 'America/Indiana/Marengo'), ('America/Indiana/Petersburg', 'America/Indiana/Petersburg'), ('America/Indiana/Tell_City', 'America/Indiana/Tell_City'), ('America/Indiana/Vevay', 'America/Indiana/Vevay'), ('America/Indiana/Vincennes', 'America/Indiana/Vincennes'), ('America/Indiana/Winamac', 'America/Indiana/Winamac'), ('America/Indianapolis', 'America/Indianapolis'), ('America/Inuvik', 'America/Inuvik'), ('America/Iqaluit', 'America/Iqaluit'), ('America/Jamaica', 'America/Jamaica'), ('America/Jujuy', 'America/Jujuy'), ('America/Juneau', 'America/Juneau'), ('America/Kentucky/Louisville', 'America/Kentucky/Louisville'), ('America/Kentucky/Monticello', 'America/Kentucky/Monticello'), ('America/Knox_IN', 'America/Knox_IN'), ('America/Kralendijk', 'America/Kralendijk'), ('America/La_Paz', 'America/La_Paz'), ('America/Lima', 'America/Lima'), ('America/Los_Angeles', 'America/Los_Angeles'), ('America/Louisville', 'America/Louisville'), ('America/Lower_Princes', 'America/Lower_Princes'), ('America/Maceio', 'America/Maceio'), ('America/Managua', 'America/Managua'), ('America/Manaus', 'America/Manaus'), ('America/Marigot', 'America/Marigot'), ('America/Martinique', 'America/Martinique'), ('America/Matamoros', 'America/Matamoros'), ('America/Mazatlan', 'America/Mazatlan'), ('America/Mendoza', 'America/Mendoza'), ('America/Menominee', 'America/Menominee'), ('America/Merida', 'America/Merida'), ('America/Metlakatla', 'America/Metlakatla'), ('America/Mexico_City', 'America/Mexico_City'), ('America/Miquelon', 'America/Miquelon'), ('America/Moncton', 'America/Moncton'), ('America/Monterrey', 'America/Monterrey'), ('America/Montevideo', 'America/Montevideo'), ('America/Montreal', 'America/Montreal'), ('America/Montserrat', 'America/Montserrat'), ('America/Nassau', 'America/Nassau'), ('America/New_York', 'America/New_York'), ('America/Nipigon', 'America/Nipigon'), ('America/Nome', 'America/Nome'), ('America/Noronha', 'America/Noronha'), ('America/North_Dakota/Beulah', 'America/North_Dakota/Beulah'), ('America/North_Dakota/Center', 'America/North_Dakota/Center'), ('America/North_Dakota/New_Salem', 'America/North_Dakota/New_Salem'), ('America/Nuuk', 'America/Nuuk'), ('America/Ojinaga', 'America/Ojinaga'), ('America/Panama', 'America/Panama'), ('America/Pangnirtung', 'America/Pangnirtung'), ('America/Paramaribo', 'America/Paramaribo'), ('America/Phoenix', 'America/Phoenix'), ('America/Port-au-Prince', 'America/Port-au-Prince'), ('America/Port_of_Spain', 'America/Port_of_Spain'), ('America/Porto_Acre', 'America/Porto_Acre'), ('America/Porto_Velho', 'America/Porto_Velho'), ('America/Puerto_Rico', 'America/Puerto_Rico'), ('America/Punta_Arenas', 'America/Punta_Arenas'), ('America/Rainy_River', 'America/Rainy_River'), ('America/Rankin_Inlet', 'America/Rankin_Inlet'), ('America/Recife', 'America/Recife'), ('America/Regina', 'America/Regina'), ('America/Resolute', 'America/Resolute'), ('America/Rio_Branco', 'America/Rio_Branco'), ('America/Rosario', 'America/Rosario'), ('America/Santa_Isabel', 'America/Santa_Isabel'), ('America/Santarem', 'America/Santarem'), ('America/Santiago', 'America/Santiago'), ('America/Santo_Domingo', 'America/Santo_Domingo'), ('America/Sao_Paulo', 'America/Sao_Paulo'), ('America/Scoresbysund', 'America/Scoresbysund'), ('America/Shiprock', 'America/Shiprock'), ('America/Sitka', 'America/Sitka'), ('America/St_Barthelemy', 'America/St_Barthelemy'), ('America/St_Johns', 'America/St_Johns'), ('America/St_Kitts', 'America/St_Kitts'), ('America/St_Lucia', 'America/St_Lucia'), ('America/St_Thomas', 'America/St_Thomas'), ('America/St_Vincent', 'America/St_Vincent'), ('America/Swift_Current', 'America/Swift_Current'), ('America/Tegucigalpa', 'America/Tegucigalpa'), ('America/Thule', 'America/Thule'), ('America/Thunder_Bay', 'America/Thunder_Bay'), ('America/Tijuana', 'America/Tijuana'), ('America/Toronto', 'America/Toronto'), ('America/Tortola', 'America/Tortola'), ('America/Vancouver', 'America/Vancouver'), ('America/Virgin', 'America/Virgin'), ('America/Whitehorse', 'America/Whitehorse'), ('America/Winnipeg', 'America/Winnipeg'), ('America/Yakutat', 'America/Yakutat'), ('America/Yellowknife', 'America/Yellowknife'), ('Antarctica/Casey', 'Antarctica/Casey'), ('Antarctica/Davis', 'Antarctica/Davis'), ('Antarctica/DumontDUrville', 'Antarctica/DumontDUrville'), ('Antarctica/Macquarie', 'Antarctica/Macquarie'), ('Antarctica/Mawson', 'Antarctica/Mawson'), ('Antarctica/McMurdo', 'Antarctica/McMurdo'), ('Antarctica/Palmer', 'Antarctica/Palmer'), ('Antarctica/Rothera', 'Antarctica/Rothera'), ('Antarctica/South_Pole', 'Antarctica/South_Pole'), ('Antarctica/Syowa', 'Antarctica/Syowa'), ('Antarctica/Troll', 'Antarctica/Troll'), ('Antarctica/Vostok', 'Antarctica/Vostok'), ('Arctic/Longyearbyen', 'Arctic/Longyearbyen'), ('Asia/Aden', 'Asia/Aden'), ('Asia/Almaty', 'Asia/Almaty'), ('Asia/Amman', 'Asia/Amman'), ('Asia/Anadyr', 'Asia/Anadyr'), ('Asia/Aqtau', 'Asia/Aqtau'), ('Asia/Aqtobe', 'Asia/Aqtobe'), ('Asia/Ashgabat', 'Asia/Ashgabat'), ('Asia/Ashkhabad', 'Asia/Ashkhabad'), ('Asia/Atyrau', 'Asia/Atyrau'), ('Asia/Baghdad', 'Asia/Baghdad'), ('Asia/Bahrain', 'Asia/Bahrain'), ('Asia/Baku', 'Asia/Baku'), ('Asia/Bangkok', 'Asia/Bangkok'), ('Asia/Barnaul', 'Asia/Barnaul'), ('Asia/Beirut', 'Asia/Beirut'), ('Asia/Bishkek', 'Asia/Bishkek'), ('Asia/Brunei', 'Asia/Brunei'), ('Asia/Calcutta', 'Asia/Calcutta'), ('Asia/Chita', 'Asia/Chita'), ('Asia/Choibalsan', 'Asia/Choibalsan'), ('Asia/Chongqing', 'Asia/Chongqing'), ('Asia/Chungking', 'Asia/Chungking'), ('Asia/Colombo', 'Asia/Colombo'), ('Asia/Dacca', 'Asia/Dacca'), ('Asia/Damascus', 'Asia/Damascus'), ('Asia/Dhaka', 'Asia/Dhaka'), ('Asia/Dili', 'Asia/Dili'), ('Asia/Dubai', 'Asia/Dubai'), ('Asia/Dushanbe', 'Asia/Dushanbe'), ('Asia/Famagusta', 'Asia/Famagusta'), ('Asia/Gaza', 'Asia/Gaza'), ('Asia/Harbin', 'Asia/Harbin'), ('Asia/Hebron', 'Asia/Hebron'), ('Asia/Ho_Chi_Minh', 'Asia/Ho_Chi_Minh'), ('Asia/Hong_Kong', 'Asia/Hong_Kong'), ('Asia/Hovd', 'Asia/Hovd'), ('Asia/Irkutsk', 'Asia/Irkutsk'), ('Asia/Istanbul', 'Asia/Istanbul'), ('Asia/Jakarta', 'Asia/Jakarta'), ('Asia/Jayapura', 'Asia/Jayapura'), ('Asia/Jerusalem', 'Asia/Jerusalem'), ('Asia/Kabul', 'Asia/Kabul'), ('Asia/Kamchatka', 'Asia/Kamchatka'), ('Asia/Karachi', 'Asia/Karachi'), ('Asia/Kashgar', 'Asia/Kashgar'), ('Asia/Kathmandu', 'Asia/Kathmandu'), ('Asia/Katmandu', 'Asia/Katmandu'), ('Asia/Khandyga', 'Asia/Khandyga'), ('Asia/Kolkata', 'Asia/Kolkata'), ('Asia/Krasnoyarsk', 'Asia/Krasnoyarsk'), ('Asia/Kuala_Lumpur', 'Asia/Kuala_Lumpur'), ('Asia/Kuching', 'Asia/Kuching'), ('Asia/Kuwait', 'Asia/Kuwait'), ('Asia/Macao', 'Asia/Macao'), ('Asia/Macau', 'Asia/Macau'), ('Asia/Magadan', 'Asia/Magadan'), ('Asia/Makassar', 'Asia/Makassar'), ('Asia/Manila', 'Asia/Manila'), ('Asia/Muscat', 'Asia/Muscat'), ('Asia/Nicosia', 'Asia/Nicosia'), ('Asia/Novokuznetsk', 'Asia/Novokuznetsk'), ('Asia/Novosibirsk', 'Asia/Novosibirsk'), ('Asia/Omsk', 'Asia/Omsk'), ('Asia/Oral', 'Asia/Oral'), ('Asia/Phnom_Penh', 'Asia/Phnom_Penh'), ('Asia/Pontianak', 'Asia/Pontianak'), ('Asia/Pyongyang', 'Asia/Pyongyang'), ('Asia/Qatar', 'Asia/Qatar'), ('Asia/Qostanay', 'Asia/Qostanay'), ('Asia/Qyzylorda', 'Asia/Qyzylorda'), ('Asia/Rangoon', 'Asia/Rangoon'), ('Asia/Riyadh', 'Asia/Riyadh'), ('Asia/Saigon', 'Asia/Saigon'), ('Asia/Sakhalin', 'Asia/Sakhalin'), ('Asia/Samarkand', 'Asia/Samarkand'), ('Asia/Seoul', 'Asia/Seoul'), ('Asia/Shanghai', 'Asia/Shanghai'), ('Asia/Singapore', 'Asia/Singapore'), ('Asia/Srednekolymsk', 'Asia/Srednekolymsk'), ('Asia/Taipei', 'Asia/Taipei'), ('Asia/Tashkent', 'Asia/Tashkent'), ('Asia/Tbilisi', 'Asia/Tbilisi'), ('Asia/Tehran', 'Asia/Tehran'), ('Asia/Tel_Aviv', 'Asia/Tel_Aviv'), ('Asia/Thimbu', 'Asia/Thimbu'), ('Asia/Thimphu', 'Asia/Thimphu'), ('Asia/Tokyo', 'Asia/Tokyo'), ('Asia/Tomsk', 'Asia/Tomsk'), ('Asia/Ujung_Pandang', 'Asia/Ujung_Pandang'), ('Asia/Ulaanbaatar', 'Asia/Ulaanbaatar'), ('Asia/Ulan_Bator', 'Asia/Ulan_Bator'), ('Asia/Urumqi', 'Asia/Urumqi'), ('Asia/Ust-Nera', 'Asia/Ust-Nera'), ('Asia/Vientiane', 'Asia/Vientiane'), ('Asia/Vladivostok', 'Asia/Vladivostok'), ('Asia/Yakutsk', 'Asia/Yakutsk'), ('Asia/Yangon', 'Asia/Yangon'), ('Asia/Yekaterinburg', 'Asia/Yekaterinburg'), ('Asia/Yerevan', 'Asia/Yerevan'), ('Atlantic/Azores', 'Atlantic/Azores'), ('Atlantic/Bermuda', 'Atlantic/Bermuda'), ('Atlantic/Canary', 'Atlantic/Canary'), ('Atlantic/Cape_Verde', 'Atlantic/Cape_Verde'), ('Atlantic/Faeroe', 'Atlantic/Faeroe'), ('Atlantic/Faroe', 'Atlantic/Faroe'), ('Atlantic/Jan_Mayen', 'Atlantic/Jan_Mayen'), ('Atlantic/Madeira', 'Atlantic/Madeira'), ('Atlantic/Reykjavik', 'Atlantic/Reykjavik'), ('Atlantic/South_Georgia', 'Atlantic/South_Georgia'), ('Atlantic/St_Helena', 'Atlantic/St_Helena'), ('Atlantic/Stanley', 'Atlantic/Stanley'), ('Australia/ACT', 'Australia/ACT'), ('Australia/Adelaide', 'Australia/Adelaide'), ('Australia/Brisbane', 'Australia/Brisbane'), ('Australia/Broken_Hill', 'Australia/Broken_Hill'), ('Australia/Canberra', 'Australia/Canberra'), ('Australia/Currie', 'Australia/Currie'), ('Australia/Darwin', 'Australia/Darwin'), ('Australia/Eucla', 'Australia/Eucla'), ('Australia/Hobart', 'Australia/Hobart'), ('Australia/LHI', 'Australia/LHI'), ('Australia/Lindeman', 'Australia/Lindeman'), ('Australia/Lord_Howe', 'Australia/Lord_Howe'), ('Australia/Melbourne', 'Australia/Melbourne'), ('Australia/NSW', 'Australia/NSW'), ('Australia/North', 'Australia/North'), ('Australia/Perth', 'Australia/Perth'), ('Australia/Queensland', 'Australia/Queensland'), ('Australia/South', 'Australia/South'), ('Australia/Sydney', 'Australia/Sydney'), ('Australia/Tasmania', 'Australia/Tasmania'), ('Australia/Victoria', 'Australia/Victoria'), ('Australia/West', 'Australia/West'), ('Australia/Yancowinna', 'Australia/Yancowinna'), ('Brazil/Acre', 'Brazil/Acre'), ('Brazil/DeNoronha', 'Brazil/DeNoronha'), ('Brazil/East', 'Brazil/East'), ('Brazil/West', 'Brazil/West'), ('CET', 'CET'), ('CST6CDT', 'CST6CDT'), ('Canada/Atlantic', 'Canada/Atlantic'), ('Canada/Central', 'Canada/Central'), ('Canada/Eastern', 'Canada/Eastern'), ('Canada/Mountain', 'Canada/Mountain'), ('Canada/Newfoundland', 'Canada/Newfoundland'), ('Canada/Pacific', 'Canada/Pacific'), ('Canada/Saskatchewan', 'Canada/Saskatchewan'), ('Canada/Yukon', 'Canada/Yukon'), ('Chile/Continental', 'Chile/Continental'), ('Chile/EasterIsland', 'Chile/EasterIsland'), ('Cuba', 'Cuba'), ('EET', 'EET'), ('EST', 'EST'), ('EST5EDT', 'EST5EDT'), ('Egypt', 'Egypt'), ('Eire', 'Eire'), ('Etc/GMT', 'Etc/GMT'), ('Etc/GMT+0', 'Etc/GMT+0'), ('Etc/GMT+1', 'Etc/GMT+1'), ('Etc/GMT+10', 'Etc/GMT+10'), ('Etc/GMT+11', 'Etc/GMT+11'), ('Etc/GMT+12', 'Etc/GMT+12'), ('Etc/GMT+2', 'Etc/GMT+2'), ('Etc/GMT+3', 'Etc/GMT+3'), ('Etc/GMT+4', 'Etc/GMT+4'), ('Etc/GMT+5', 'Etc/GMT+5'), ('Etc/GMT+6', 'Etc/GMT+6'), ('Etc/GMT+7', 'Etc/GMT+7'), ('Etc/GMT+8', 'Etc/GMT+8'), ('Etc/GMT+9', 'Etc/GMT+9'), ('Etc/GMT-0', 'Etc/GMT-0'), ('Etc/GMT-1', 'Etc/GMT-1'), ('Etc/GMT-10', 'Etc/GMT-10'), ('Etc/GMT-11', 'Etc/GMT-11'), ('Etc/GMT-12', 'Etc/GMT-12'), ('Etc/GMT-13', 'Etc/GMT-13'), ('Etc/GMT-14', 'Etc/GMT-14'), ('Etc/GMT-2', 'Etc/GMT-2'), ('Etc/GMT-3', 'Etc/GMT-3'), ('Etc/GMT-4', 'Etc/GMT-4'), ('Etc/GMT-5', 'Etc/GMT-5'), ('Etc/GMT-6', 'Etc/GMT-6'), ('Etc/GMT-7', 'Etc/GMT-7'), ('Etc/GMT-8', 'Etc/GMT-8'), ('Etc/GMT-9', 'Etc/GMT-9'), ('Etc/GMT0', 'Etc/GMT0'), ('Etc/Greenwich', 'Etc/Greenwich'), ('Etc/UCT', 'Etc/UCT'), ('Etc/UTC', 'Etc/UTC'), ('Etc/Universal', 'Etc/Universal'), ('Etc/Zulu', 'Etc/Zulu'), ('Europe/Amsterdam', 'Europe/Amsterdam'), ('Europe/Andorra', 'Europe/Andorra'), ('Europe/Astrakhan', 'Europe/Astrakhan'), ('Europe/Athens', 'Europe/Athens'), ('Europe/Belfast', 'Europe/Belfast'), ('Europe/Belgrade', 'Europe/Belgrade'), ('Europe/Berlin', 'Europe/Berlin'), ('Europe/Bratislava', 'Europe/Bratislava'), ('Europe/Brussels', 'Europe/Brussels'), ('Europe/Bucharest', 'Europe/Bucharest'), ('Europe/Budapest', 'Europe/Budapest'), ('Europe/Busingen', 'Europe/Busingen'), ('Europe/Chisinau', 'Europe/Chisinau'), ('Europe/Copenhagen', 'Europe/Copenhagen'), ('Europe/Dublin', 'Europe/Dublin'), ('Europe/Gibraltar', 'Europe/Gibraltar'), ('Europe/Guernsey', 'Europe/Guernsey'), ('Europe/Helsinki', 'Europe/Helsinki'), ('Europe/Isle_of_Man', 'Europe/Isle_of_Man'), ('Europe/Istanbul', 'Europe/Istanbul'), ('Europe/Jersey', 'Europe/Jersey'), ('Europe/Kaliningrad', 'Europe/Kaliningrad'), ('Europe/Kiev', 'Europe/Kiev'), ('Europe/Kirov', 'Europe/Kirov'), ('Europe/Lisbon', 'Europe/Lisbon'), ('Europe/Ljubljana', 'Europe/Ljubljana'), ('Europe/London', 'Europe/London'), ('Europe/Luxembourg', 'Europe/Luxembourg'), ('Europe/Madrid', 'Europe/Madrid'), ('Europe/Malta', 'Europe/Malta'), ('Europe/Mariehamn', 'Europe/Mariehamn'), ('Europe/Minsk', 'Europe/Minsk'), ('Europe/Monaco', 'Europe/Monaco'), ('Europe/Moscow', 'Europe/Moscow'), ('Europe/Nicosia', 'Europe/Nicosia'), ('Europe/Oslo', 'Europe/Oslo'), ('Europe/Paris', 'Europe/Paris'), ('Europe/Podgorica', 'Europe/Podgorica'), ('Europe/Prague', 'Europe/Prague'), ('Europe/Riga', 'Europe/Riga'), ('Europe/Rome', 'Europe/Rome'), ('Europe/Samara', 'Europe/Samara'), ('Europe/San_Marino', 'Europe/San_Marino'), ('Europe/Sarajevo', 'Europe/Sarajevo'), ('Europe/Saratov', 'Europe/Saratov'), ('Europe/Simferopol', 'Europe/Simferopol'), ('Europe/Skopje', 'Europe/Skopje'), ('Europe/Sofia', 'Europe/Sofia'), ('Europe/Stockholm', 'Europe/Stockholm'), ('Europe/Tallinn', 'Europe/Tallinn'), ('Europe/Tirane', 'Europe/Tirane'), ('Europe/Tiraspol', 'Europe/Tiraspol'), ('Europe/Ulyanovsk', 'Europe/Ulyanovsk'), ('Europe/Uzhgorod', 'Europe/Uzhgorod'), ('Europe/Vaduz', 'Europe/Vaduz'), ('Europe/Vatican', 'Europe/Vatican'), ('Europe/Vienna', 'Europe/Vienna'), ('Europe/Vilnius', 'Europe/Vilnius'), ('Europe/Volgograd', 'Europe/Volgograd'), ('Europe/Warsaw', 'Europe/Warsaw'), ('Europe/Zagreb', 'Europe/Zagreb'), ('Europe/Zaporozhye', 'Europe/Zaporozhye'), ('Europe/Zurich', 'Europe/Zurich'), ('GB', 'GB'), ('GB-Eire', 'GB-Eire'), ('GMT', 'GMT'), ('GMT+0', 'GMT+0'), ('GMT-0', 'GMT-0'), ('GMT0', 'GMT0'), ('Greenwich', 'Greenwich'), ('HST', 'HST'), ('Hongkong', 'Hongkong'), ('Iceland', 'Iceland'), ('Indian/Antananarivo', 'Indian/Antananarivo'), ('Indian/Chagos', 'Indian/Chagos'), ('Indian/Christmas', 'Indian/Christmas'), ('Indian/Cocos', 'Indian/Cocos'), ('Indian/Comoro', 'Indian/Comoro'), ('Indian/Kerguelen', 'Indian/Kerguelen'), ('Indian/Mahe', 'Indian/Mahe'), ('Indian/Maldives', 'Indian/Maldives'), ('Indian/Mauritius', 'Indian/Mauritius'), ('Indian/Mayotte', 'Indian/Mayotte'), ('Indian/Reunion', 'Indian/Reunion'), ('Iran', 'Iran'), ('Israel', 'Israel'), ('Jamaica', 'Jamaica'), ('Japan', 'Japan'), ('Kwajalein', 'Kwajalein'), ('Libya', 'Libya'), ('MET', 'MET'), ('MST', 'MST'), ('MST7MDT', 'MST7MDT'), ('Mexico/BajaNorte', 'Mexico/BajaNorte'), ('Mexico/BajaSur', 'Mexico/BajaSur'), ('Mexico/General', 'Mexico/General'), ('NZ', 'NZ'), ('NZ-CHAT', 'NZ-CHAT'), ('Navajo', 'Navajo'), ('PRC', 'PRC'), ('PST8PDT', 'PST8PDT'), ('Pacific/Apia', 'Pacific/Apia'), ('Pacific/Auckland', 'Pacific/Auckland'), ('Pacific/Bougainville', 'Pacific/Bougainville'), ('Pacific/Chatham', 'Pacific/Chatham'), ('Pacific/Chuuk', 'Pacific/Chuuk'), ('Pacific/Easter', 'Pacific/Easter'), ('Pacific/Efate', 'Pacific/Efate'), ('Pacific/Enderbury', 'Pacific/Enderbury'), ('Pacific/Fakaofo', 'Pacific/Fakaofo'), ('Pacific/Fiji', 'Pacific/Fiji'), ('Pacific/Funafuti', 'Pacific/Funafuti'), ('Pacific/Galapagos', 'Pacific/Galapagos'), ('Pacific/Gambier', 'Pacific/Gambier'), ('Pacific/Guadalcanal', 'Pacific/Guadalcanal'), ('Pacific/Guam', 'Pacific/Guam'), ('Pacific/Honolulu', 'Pacific/Honolulu'), ('Pacific/Johnston', 'Pacific/Johnston'), ('Pacific/Kanton', 'Pacific/Kanton'), ('Pacific/Kiritimati', 'Pacific/Kiritimati'), ('Pacific/Kosrae', 'Pacific/Kosrae'), ('Pacific/Kwajalein', 'Pacific/Kwajalein'), ('Pacific/Majuro', 'Pacific/Majuro'), ('Pacific/Marquesas', 'Pacific/Marquesas'), ('Pacific/Midway', 'Pacific/Midway'), ('Pacific/Nauru', 'Pacific/Nauru'), ('Pacific/Niue', 'Pacific/Niue'), ('Pacific/Norfolk', 'Pacific/Norfolk'), ('Pacific/Noumea', 'Pacific/Noumea'), ('Pacific/Pago_Pago', 'Pacific/Pago_Pago'), ('Pacific/Palau', 'Pacific/Palau'), ('Pacific/Pitcairn', 'Pacific/Pitcairn'), ('Pacific/Pohnpei', 'Pacific/Pohnpei'), ('Pacific/Ponape', 'Pacific/Ponape'), ('Pacific/Port_Moresby', 'Pacific/Port_Moresby'), ('Pacific/Rarotonga', 'Pacific/Rarotonga'), ('Pacific/Saipan', 'Pacific/Saipan'), ('Pacific/Samoa', 'Pacific/Samoa'), ('Pacific/Tahiti', 'Pacific/Tahiti'), ('Pacific/Tarawa', 'Pacific/Tarawa'), ('Pacific/Tongatapu', 'Pacific/Tongatapu'), ('Pacific/Truk', 'Pacific/Truk'), ('Pacific/Wake', 'Pacific/Wake'), ('Pacific/Wallis', 'Pacific/Wallis'), ('Pacific/Yap', 'Pacific/Yap'), ('Poland', 'Poland'), ('Portugal', 'Portugal'), ('ROC', 'ROC'), ('ROK', 'ROK'), ('Singapore', 'Singapore'), ('Turkey', 'Turkey'), ('UCT', 'UCT'), ('US/Alaska', 'US/Alaska'), ('US/Aleutian', 'US/Aleutian'), ('US/Arizona', 'US/Arizona'), ('US/Central', 'US/Central'), ('US/East-Indiana', 'US/East-Indiana'), ('US/Eastern', 'US/Eastern'), ('US/Hawaii', 'US/Hawaii'), ('US/Indiana-Starke', 'US/Indiana-Starke'), ('US/Michigan', 'US/Michigan'), ('US/Mountain', 'US/Mountain'), ('US/Pacific', 'US/Pacific'), ('US/Samoa', 'US/Samoa'), ('UTC', 'UTC'), ('Universal', 'Universal'), ('W-SU', 'W-SU'), ('WET', 'WET'), ('Zulu', 'Zulu')], db_index=True, max_length=50),
22
+ ),
23
+ ]
@@ -0,0 +1,18 @@
1
+ # Generated by Django 4.2.10 on 2024-06-26 12:23
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('core', '0039_instance_is_active_alter_instance_timezone'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name='instance',
15
+ name='name',
16
+ field=models.CharField(db_index=True, max_length=100),
17
+ ),
18
+ ]
@@ -0,0 +1,18 @@
1
+ # Generated by Django 4.2.10 on 2024-06-26 12:38
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('core', '0040_alter_instance_name'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name='instance',
15
+ name='slug',
16
+ field=models.CharField(db_index=True, max_length=100),
17
+ ),
18
+ ]
simo/core/models.py CHANGED
@@ -18,7 +18,9 @@ from simo.core.storage import OverwriteStorage
18
18
  from simo.core.utils.validators import validate_svg
19
19
  from simo.core.utils.helpers import get_random_string
20
20
  from simo.users.models import User
21
- from .managers import ZonesManager, CategoriesManager, ComponentsManager
21
+ from .managers import (
22
+ InstanceManager, ZonesManager, CategoriesManager, ComponentsManager
23
+ )
22
24
  from .events import GatewayObjectCommand, OnChangeMixin
23
25
 
24
26
 
@@ -68,9 +70,13 @@ class Instance(models.Model, SimoAdminMixin):
68
70
  uid = models.CharField(
69
71
  max_length=50, unique=True, help_text="Issued by SIMO.io"
70
72
  )
71
- name = models.CharField(max_length=100, db_index=True, unique=True)
72
- slug = models.CharField(max_length=100, db_index=True, unique=True)
73
+ name = models.CharField(max_length=100, db_index=True)
74
+ slug = models.CharField(max_length=100, db_index=True)
73
75
  date_created = models.DateTimeField(auto_now_add=True)
76
+ is_active = models.BooleanField(
77
+ default=True, db_index=True,
78
+ help_text="Get's deactivated instead of delete."
79
+ )
74
80
  location = PlainLocationField(null=True, blank=True, zoom=7)
75
81
  timezone = models.CharField(
76
82
  max_length=50, db_index=True, choices=ALL_TIMEZONES_CHOICES
@@ -96,6 +102,8 @@ class Instance(models.Model, SimoAdminMixin):
96
102
  User, null=True, blank=True, on_delete=models.SET_NULL
97
103
  )
98
104
 
105
+ objects = InstanceManager()
106
+
99
107
 
100
108
  def __str__(self):
101
109
  return self.name
simo/core/permissions.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from rest_framework.permissions import BasePermission, SAFE_METHODS, IsAuthenticated
2
2
  from django.http import Http404
3
+ from .middleware import introduce_instance
3
4
  from .models import Instance, Category, Zone
4
5
 
5
6
 
@@ -13,7 +14,8 @@ class InstancePermission(BasePermission):
13
14
  instance = getattr(view, 'instance', None)
14
15
  if not instance:
15
16
  instance = Instance.objects.filter(
16
- slug=request.resolver_match.kwargs.get('instance_slug')
17
+ slug=request.resolver_match.kwargs.get('instance_slug'),
18
+ is_active=True
17
19
  ).first()
18
20
 
19
21
  if not instance:
@@ -22,6 +24,8 @@ class InstancePermission(BasePermission):
22
24
  if instance not in request.user.instances:
23
25
  return False
24
26
 
27
+ introduce_instance(instance)
28
+
25
29
  return True
26
30
 
27
31
 
simo/core/serializers.py CHANGED
@@ -227,6 +227,7 @@ class ComponentManyToManyRelatedField(serializers.Field):
227
227
  self.allow_blank = kwargs.pop('allow_blank', False)
228
228
  super().__init__(*args, **kwargs)
229
229
 
230
+
230
231
  def to_representation(self, value):
231
232
  return [obj.pk for obj in value.all()]
232
233
 
@@ -257,8 +258,6 @@ class ComponentSerializer(FormSerializer):
257
258
  controller_methods = serializers.SerializerMethodField()
258
259
  info = serializers.SerializerMethodField()
259
260
 
260
- _forms = {}
261
-
262
261
  class Meta:
263
262
  form = ComponentAdminForm
264
263
  field_mapping = {
@@ -353,10 +352,18 @@ class ComponentSerializer(FormSerializer):
353
352
  def _get_field_kwargs(self, form_field, serializer_field_class):
354
353
  kwargs = super()._get_field_kwargs(form_field, serializer_field_class)
355
354
  kwargs['style'] = {'form_field': form_field}
356
- if serializer_field_class == ComponentPrimaryKeyRelatedField:
357
- kwargs['queryset'] = form_field.queryset
358
- elif serializer_field_class == ComponentManyToManyRelatedField:
359
- kwargs['queryset'] = form_field.queryset
355
+ if serializer_field_class in (
356
+ ComponentPrimaryKeyRelatedField, ComponentManyToManyRelatedField
357
+ ):
358
+ qs = form_field.queryset
359
+ if hasattr(qs.model, 'instance'):
360
+ qs = qs.filter(instance=self.context['instance'])
361
+ elif hasattr(qs.model, 'instances'):
362
+ qs = qs.filter(instances=self.context['instance'])
363
+ elif qs.model == Component:
364
+ qs = qs.filter(zone__instance=self.context['instance'])
365
+ kwargs['queryset'] = qs
366
+
360
367
  elif serializer_field_class == ComponentFormsetField:
361
368
  kwargs['formset_field'] = form_field
362
369
  kwargs['many'] = True
@@ -386,13 +393,15 @@ class ComponentSerializer(FormSerializer):
386
393
  self.Meta.form = controller.config_form
387
394
 
388
395
  def get_form(self, data=None, instance=None, **kwargs):
396
+ if 'forms' not in self.context:
397
+ self.context['forms'] = {}
389
398
  form_key = None
390
399
  if not data:
391
400
  form_key = 0
392
401
  if instance:
393
402
  form_key = instance.id
394
- if form_key in self._forms:
395
- return self._forms[form_key]
403
+ if form_key in self.context['forms']:
404
+ return self.context['forms'][form_key]
396
405
 
397
406
  self.set_form_cls()
398
407
  if not self.instance or isinstance(self.instance, Iterable):
@@ -412,11 +421,10 @@ class ComponentSerializer(FormSerializer):
412
421
  if not user_role.is_superuser and user_role.is_owner:
413
422
  for field_name in list(form.fields.keys()):
414
423
  if field_name not in form.basic_fields:
415
- print("DELETE FIELD: ", field_name)
416
424
  del form.fields[field_name]
417
425
 
418
426
  if form_key is not None:
419
- self._forms[form_key] = form
427
+ self.context['forms'][form_key] = form
420
428
 
421
429
  return form
422
430
 
@@ -71,8 +71,8 @@ def create_instance_defaults(sender, instance, created, **kwargs):
71
71
  )
72
72
  dummy.start()
73
73
  weather_icon = Icon.objects.get(slug='cloud-bolt-sun')
74
- other_zone = Zone.objects.get(name='Other')
75
- climate_category = Category.objects.get(name='Climate')
74
+ other_zone = Zone.objects.get(name='Other', instance=instance)
75
+ climate_category = Category.objects.get(name='Climate', instance=instance)
76
76
  Component.objects.create(
77
77
  name='Weather', icon=weather_icon,
78
78
  zone=other_zone,
simo/core/tasks.py CHANGED
@@ -117,7 +117,7 @@ def sync_with_remote():
117
117
  'remote_conn_version': dynamic_settings['core__remote_conn_version'],
118
118
  'instances': []
119
119
  }
120
- for instance in Instance.objects.all():
120
+ for instance in Instance.objects.filter(is_active=True):
121
121
  instance_data = {
122
122
  'uid': instance.uid,
123
123
  'name': instance.name,
@@ -167,40 +167,45 @@ def sync_with_remote():
167
167
 
168
168
  print("Responded with: ", json.dumps(r_json))
169
169
 
170
- if 'hub_uid' in r_json:
171
- dynamic_settings['core__hub_uid'] = r_json['hub_uid']
172
-
173
- dynamic_settings['core__remote_http'] = r_json.get('hub_remote_http', '')
174
- if 'new_secret' in r_json:
175
- dynamic_settings['core__hub_secret'] = r_json['new_secret']
176
-
177
- if dynamic_settings['core__remote_conn_version'] < r_json['remote_conn_version']:
178
- save_config(r_json)
179
- dynamic_settings['core__remote_conn_version'] = r_json['remote_conn_version']
180
-
181
- for data in r_json['instances']:
182
- users_data = data.pop('users', {})
183
- instance_uid = data.pop('uid')
184
- weather_forecast = data.pop('weather_forecast', None)
185
- instance, new_instance = Instance.objects.update_or_create(
186
- uid=instance_uid, defaults=data
187
- )
188
-
189
- if weather_forecast:
190
- from simo.generic.controllers import WeatherForecast
191
- weather_component = Component.objects.filter(
192
- zone__instance=instance,
193
- controller_uid=WeatherForecast.uid
194
- ).first()
195
- if weather_component:
196
- weather_component.track_history = False
197
- weather_component.controller.set(weather_forecast)
198
-
199
-
200
- for email, options in users_data.items():
201
- with transaction.atomic():
202
- if new_instance:
203
- # Create users for new instance!
170
+ with transaction.atomic():
171
+ if 'hub_uid' in r_json:
172
+ dynamic_settings['core__hub_uid'] = r_json['hub_uid']
173
+
174
+ dynamic_settings['core__remote_http'] = r_json.get('hub_remote_http', '')
175
+ if 'new_secret' in r_json:
176
+ dynamic_settings['core__hub_secret'] = r_json['new_secret']
177
+
178
+ if dynamic_settings['core__remote_conn_version'] < r_json['remote_conn_version']:
179
+ save_config(r_json)
180
+ dynamic_settings['core__remote_conn_version'] = r_json['remote_conn_version']
181
+
182
+ instance_uids = []
183
+ for data in r_json['instances']:
184
+ users_data = data.pop('users', {})
185
+ instance_uid = data.pop('uid')
186
+ instance_uids.append(instance_uid)
187
+ weather_forecast = data.pop('weather_forecast', None)
188
+ instance, new_instance = Instance.objects.update_or_create(
189
+ uid=instance_uid, defaults=data
190
+ )
191
+ if not instance.is_active:
192
+ instance.is_active = True
193
+ instance.save()
194
+
195
+ if weather_forecast:
196
+ from simo.generic.controllers import WeatherForecast
197
+ weather_component = Component.objects.filter(
198
+ zone__instance=instance,
199
+ controller_uid=WeatherForecast.uid
200
+ ).first()
201
+ if weather_component:
202
+ weather_component.track_history = False
203
+ weather_component.controller.set(weather_forecast)
204
+
205
+ for email, options in users_data.items():
206
+
207
+ if new_instance or not instance.instance_users.count():
208
+ # Create user for new instance!
204
209
  user, new_user = User.objects.update_or_create(
205
210
  email=email, defaults={
206
211
  'name': options.get('name'),
@@ -208,19 +213,20 @@ def sync_with_remote():
208
213
  'ssh_key': options.get('ssh_key')
209
214
  })
210
215
  role = None
211
- if options.get('is_superuser'):
216
+ if options.get('is_hub_master') or options.get('is_superuser'):
212
217
  role = PermissionsRole.objects.filter(
213
- instance=new_instance, is_superuser=True
218
+ instance=instance, is_superuser=True
214
219
  ).first()
215
220
  elif options.get('is_owner'):
216
221
  role = PermissionsRole.objects.filter(
217
- instance=new_instance, is_owner=True
222
+ instance=instance, is_owner=True
218
223
  ).first()
219
- InstanceUser.objects.update_or_create(
220
- user=user, instance=new_instance, defaults={
221
- 'is_active': True, 'role': role
222
- }
223
- )
224
+ if role:
225
+ InstanceUser.objects.update_or_create(
226
+ user=user, instance=instance, defaults={
227
+ 'is_active': True, 'role': role
228
+ }
229
+ )
224
230
  else:
225
231
  user = User.objects.filter(email=email).first()
226
232
 
@@ -244,6 +250,10 @@ def sync_with_remote():
244
250
  user.avatar_last_change = timezone.now()
245
251
  user.save()
246
252
 
253
+ Instance.objects.all().exclude(
254
+ uid__in=instance_uids
255
+ ).update(is_active=False)
256
+
247
257
 
248
258
  @celery_app.task
249
259
  def watch_timers():
@@ -222,7 +222,7 @@ def install():
222
222
  with open('/etc/ssh/sshd_config', 'r') as ssh_conf:
223
223
  line = ssh_conf.readline()
224
224
  while line:
225
- if line.startswitn('PasswordAuthentication'):
225
+ if line.startswith('PasswordAuthentication'):
226
226
  line.replace(' yes', ' no')
227
227
  new_ssh_conf += line
228
228
 
@@ -0,0 +1,20 @@
1
+ # Generated by Django 4.2.10 on 2024-06-25 12:40
2
+
3
+ from django.db import migrations, models
4
+ import django.db.models.deletion
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+
9
+ dependencies = [
10
+ ('core', '0039_instance_is_active_alter_instance_timezone'),
11
+ ('users', '0028_auto_20240506_1146'),
12
+ ]
13
+
14
+ operations = [
15
+ migrations.AlterField(
16
+ model_name='instanceuser',
17
+ name='instance',
18
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='instance_users', to='core.instance'),
19
+ ),
20
+ ]
simo/users/models.py CHANGED
@@ -90,7 +90,8 @@ class InstanceUser(DirtyFieldsMixin, models.Model, OnChangeMixin):
90
90
  'User', on_delete=models.CASCADE, related_name='instance_roles'
91
91
  )
92
92
  instance = models.ForeignKey(
93
- 'core.Instance', on_delete=models.CASCADE, null=True
93
+ 'core.Instance', on_delete=models.CASCADE, null=True,
94
+ related_name='instance_users',
94
95
  )
95
96
  role = models.ForeignKey(PermissionsRole, on_delete=models.CASCADE)
96
97
  at_home = models.BooleanField(default=False, db_index=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: simo
3
- Version: 2.1.5
3
+ Version: 2.1.7
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,6 +33,7 @@ Requires-Dist: itsdangerous ==2.0.1
33
33
  Requires-Dist: redis ==3.5.3
34
34
  Requires-Dist: django-redis ==4.12.1
35
35
  Requires-Dist: webservices ==0.7
36
+ Requires-Dist: numpy ==1.24.4
36
37
  Requires-Dist: opencv-python ==4.5.4.60
37
38
  Requires-Dist: geopy ==2.2.0
38
39
  Requires-Dist: requests ==2.26.0
@@ -14,11 +14,11 @@ simo/__pycache__/urls.cpython-38.pyc,sha256=sqfstQthcjXtv31Tad0RAlWWI2A0HH6HN0fW
14
14
  simo/__pycache__/wsgi.cpython-38.pyc,sha256=TpRxO7VM_ql31hbKphVdanydC5RI1nHB4l0QA2pdWxo,322
15
15
  simo/core/__init__.py,sha256=_s2TjJfQImsMrTIxqLAx9AZie1Ojmm6sCHASdl3WLGU,50
16
16
  simo/core/admin.py,sha256=Gb1lSyvFtYj2oC5lA7j3VqU6zlqlncx5R-_XJbb8Wdk,17927
17
- simo/core/api.py,sha256=HSokv9CZCCr0WHSzo5TBXe2BF5-EnTZHPnShlzN86ms,25706
17
+ simo/core/api.py,sha256=_f0J9wmuB1ydN5qxZ487u-pKz4XiuENlTIhHfzBXvUY,27856
18
18
  simo/core/api_auth.py,sha256=vCxvczA8aWNcW0VyKs5WlC_ytlqeGP_H_hkKUNVkCwM,1247
19
- simo/core/api_meta.py,sha256=0leq4qdAELwACL7-9V_LCkuzu1VSEexys1b3iz0bsYM,3848
19
+ simo/core/api_meta.py,sha256=EaiY-dCADP__9MvLpoHvhjytFT92IrxPZDv95xgqasU,4955
20
20
  simo/core/app_widgets.py,sha256=4Lh9FDzdkfh_mccJMe09dyRTT3Uqf9VXwbkurJ9E9oQ,2115
21
- simo/core/apps.py,sha256=CL4-BX6lYYGwq6hcXL-ozT7RTvy9hyfuiPCC_RfGIY0,267
21
+ simo/core/apps.py,sha256=CsqpiQerhmrMsH-wGiG-gQgXd9qEkIi-LUaA9cXpKSw,425
22
22
  simo/core/auto_urls.py,sha256=nNXEgLAAAQAhRWQDA9AbDtw-zcPKmu_pufJaSa8g818,1102
23
23
  simo/core/autocomplete_views.py,sha256=JT5LA2_Wtr60XYSAIqaXFKFYPjrmkEf6yunXD9y2zco,4022
24
24
  simo/core/base_types.py,sha256=qVh6MrXZEfN7bFOyFftC7u0yyz0PkvpsjllLBc6SCp4,616
@@ -31,27 +31,27 @@ simo/core/form_fields.py,sha256=9tIjiEN3IE55GPyB4tOlfkd51JDne3-h8pKhpL3tLFE,2220
31
31
  simo/core/forms.py,sha256=QTPEe7nxzhg8NNCQFsVJpoO1LQW6MNNTHkEhBs7keYw,21386
32
32
  simo/core/gateways.py,sha256=m0eS3XjVe34Dge6xtoCq16kFWCKJcdQrT0JW0REqoq8,3715
33
33
  simo/core/loggers.py,sha256=EBdq23gTQScVfQVH-xeP90-wII2DQFDjoROAW6ggUP4,1645
34
- simo/core/managers.py,sha256=_BO-fiO4SYqLi7yUt7cW-ZFMD9wu-Ew8pA7cN1gnmcY,2783
34
+ simo/core/managers.py,sha256=sCo9R7ctGepYK-uspl7cR-KFBrJxSy3TZkbWbOP0YHs,2914
35
35
  simo/core/middleware.py,sha256=pO52hQOJV_JRmNyUe7zfufSnJFlRITOWX6jwkoPWJhk,2052
36
- simo/core/models.py,sha256=MaE6BUIJdXwrrlsGZRkrPSaOLY1OTWRCyjEoYArdAl8,20739
37
- simo/core/permissions.py,sha256=u89OubeV_NPMX87Mcireg6FhCs-XTuyYLIiL2HDaxg4,2815
36
+ simo/core/models.py,sha256=y5IG6hcVen6tDjzPJM8GxVeuop3XsVZElLqgoAiLVDE,20908
37
+ simo/core/permissions.py,sha256=D8JA3gdsbSfA1Lz6-AIP5ILsYYZ59_Rw4csLqVpuKuE,2928
38
38
  simo/core/routing.py,sha256=X1_IHxyA-_Q7hw1udDoviVP4_FSBDl8GYETTC2zWTbY,499
39
- simo/core/serializers.py,sha256=M3r2P1-Eb5eObOqcI9dttedh4UxgPwWwGYmOfXe3BDk,20303
40
- simo/core/signal_receivers.py,sha256=ZhHg1mLn_Yhin-23Af1WNPfE5hnGYhhVDZDTEjRtO-A,6190
39
+ simo/core/serializers.py,sha256=K13SDW-FIcNiRYmJufSDS2EkRAW3cuoiHRByof2DYXQ,20629
40
+ simo/core/signal_receivers.py,sha256=9-qFCCeSLcMFEMg6QUtKOVgUsoNoqhzGoI98nuNSTEo,6228
41
41
  simo/core/socket_consumers.py,sha256=n7VE2Fvqt4iEAYLTRbTPOcI-7tszMAADu7gimBxB-Fg,9635
42
42
  simo/core/storage.py,sha256=YlxmdRs-zhShWtFKgpJ0qp2NDBuIkJGYC1OJzqkbttQ,572
43
- simo/core/tasks.py,sha256=VTr83_8avke6UwFZ9VQ8c2qROpVOqAWqc0RbMxNPd08,14005
43
+ simo/core/tasks.py,sha256=kTqetlu8oqzTsxqgMKI3nmWhdERag3vjLCCbZuXDfEA,14517
44
44
  simo/core/todos.py,sha256=eYVXfLGiapkxKK57XuviSNe3WsUYyIWZ0hgQJk7ThKo,665
45
45
  simo/core/types.py,sha256=WJEq48mIbFi_5Alt4wxWMGXxNxUTXqfQU5koH7wqHHI,1108
46
46
  simo/core/views.py,sha256=ze8yX0PBLN-DH8B8jol6NKj0hLOAE4WA1rTXf07G-MU,2129
47
47
  simo/core/widgets.py,sha256=J9e06C6I22F6xKic3VMgG7WeX07glAcl-4bF2Mg180A,2827
48
48
  simo/core/__pycache__/__init__.cpython-38.pyc,sha256=ZJFM_XN0RmJMULQulgA_wFiOnEtsMoedcOWnXjH-Y8o,208
49
49
  simo/core/__pycache__/admin.cpython-38.pyc,sha256=Lqs-wHz-vxGEo7ApOk6nkpNwfxselcFHqAUozotdZU4,13231
50
- simo/core/__pycache__/api.cpython-38.pyc,sha256=hoCs0HvJFULzhDG4mwhTMMJt3hSDnMXJU_05FPK6dB4,20516
50
+ simo/core/__pycache__/api.cpython-38.pyc,sha256=8deqsTEUmnRJxarLWVOzmgHJqPdemM_qvy-1g_RUXG0,21721
51
51
  simo/core/__pycache__/api_auth.cpython-38.pyc,sha256=6M9Cl_ha4y_Vf8Rv4GMYL8dcBCmp0KzYi6jn3SQTgys,1712
52
- simo/core/__pycache__/api_meta.cpython-38.pyc,sha256=Y59fGaKkyo_DJhhcDeRUUguy2OUb6f7_F6RbQRRp0vY,3023
52
+ simo/core/__pycache__/api_meta.cpython-38.pyc,sha256=VYx5ZeDyNBI4B_CBEIhV5B3GnLsMOx9s3rNZTSMODco,3703
53
53
  simo/core/__pycache__/app_widgets.cpython-38.pyc,sha256=vUCEAYqppjgRZYMs6pTuSxWWuZxreLygPuPBGw044dQ,3643
54
- simo/core/__pycache__/apps.cpython-38.pyc,sha256=S12d7zdc2m_93FeQ4gE6I3l_lh3GAe2Icf1Ra869Kzs,633
54
+ simo/core/__pycache__/apps.cpython-38.pyc,sha256=JL0BEqgXcSQvMlcK48PBpPfyDEkPMdO1Y0teqMRGirs,713
55
55
  simo/core/__pycache__/auto_urls.cpython-38.pyc,sha256=Tyf8PYHq5YqSwTp25Joy-eura_Fm86fpX9zKLSklhvo,872
56
56
  simo/core/__pycache__/autocomplete_views.cpython-38.pyc,sha256=hJ6JILI1LqrAtpQMvxnLvljGdW1v1gpvBsD79vFkZ58,3972
57
57
  simo/core/__pycache__/base_types.cpython-38.pyc,sha256=hmq22vvGyCmhbYyuV6bFAOOSIupspgW5yq_VzqWd-vY,759
@@ -64,16 +64,16 @@ simo/core/__pycache__/form_fields.cpython-38.pyc,sha256=u0voKXkA64xbH6LY_-jMBHQS
64
64
  simo/core/__pycache__/forms.cpython-38.pyc,sha256=gDYKULuBTMLxrKfzWXaLDbxuCJvhi2rwR5rIMC_IIVI,17672
65
65
  simo/core/__pycache__/gateways.cpython-38.pyc,sha256=D1ooHL-iSpQrxnD8uAl4xWFJmm-QWZfbkLiLlFOMtdU,4553
66
66
  simo/core/__pycache__/loggers.cpython-38.pyc,sha256=Z-cdQnC6XlIonPV4Sl4E52tP4NMEdPAiHK0cFaIL7I8,1623
67
- simo/core/__pycache__/managers.cpython-38.pyc,sha256=lyqp5S11V5qinruI5druyxy-znldpjD69EmfYnF0ZLk,2994
67
+ simo/core/__pycache__/managers.cpython-38.pyc,sha256=wuZuRuyf_mZwM0DJeA83mewOLunfz4-miA2YEQphE60,3292
68
68
  simo/core/__pycache__/middleware.cpython-38.pyc,sha256=ESR5JPtITo9flczO0672sfzYUxrc_cQU0e0w5DFL-60,2038
69
- simo/core/__pycache__/models.cpython-38.pyc,sha256=_GXEFYXfQm-RP2TOgSLgfdSsCL3teu2YZ8dyAQu_0bo,17628
70
- simo/core/__pycache__/permissions.cpython-38.pyc,sha256=EBFzHG-9G5V0DlQf7CkwSGoAK0zn4Qyh69P5QuFT2yg,2853
69
+ simo/core/__pycache__/models.cpython-38.pyc,sha256=q-rGNkbO2wtAhoe1TRIOapHTuCoogpF9y7iBxZnuIKo,17753
70
+ simo/core/__pycache__/permissions.cpython-38.pyc,sha256=pg11ulzmKh4IeWGPIDJ-KYG-S0dKyY5lHh-S3iljb0E,2930
71
71
  simo/core/__pycache__/routing.cpython-38.pyc,sha256=3T3FPJ8Cn99xZCGvMyg2xjl7al-Shm9CelbSpkJtNP8,599
72
- simo/core/__pycache__/serializers.cpython-38.pyc,sha256=ibatzlaahJ0keKpml7JWuPsrzlTQcRyKNVHh_raktyo,19093
73
- simo/core/__pycache__/signal_receivers.cpython-38.pyc,sha256=gKwUVUf1vtIo1Ecvm6xGmBSwpEUALHrXai5pkMmjr9I,4895
72
+ simo/core/__pycache__/serializers.cpython-38.pyc,sha256=DhfGacxAy35un3edthOzgOWeVFbD93bvBWCJ4cAMPN4,19280
73
+ simo/core/__pycache__/signal_receivers.cpython-38.pyc,sha256=3Bt9S47DR_ZFS3O-crElFgLLXPIYyDgPIc2ibwEkaic,4904
74
74
  simo/core/__pycache__/socket_consumers.cpython-38.pyc,sha256=NJUr7nRyHFvmAumxxWpsod5wzVVZM99rCEuJs1utHA4,8432
75
75
  simo/core/__pycache__/storage.cpython-38.pyc,sha256=BTkYH8QQyjqI0WOtJC8fHNtgu0YA1vjqZclXjC2vCVI,1116
76
- simo/core/__pycache__/tasks.cpython-38.pyc,sha256=maImi7pqoVNvKNESi4xY_WdTOJdjDgP11knfXKKuVcI,9902
76
+ simo/core/__pycache__/tasks.cpython-38.pyc,sha256=HAYNyqMYRWdObXs72e_svZrq2QMSC8HBi_4CGLxGTNU,10076
77
77
  simo/core/__pycache__/todos.cpython-38.pyc,sha256=lOqGZ58siHM3isoJV4r7sg8igrfE9fFd-jSfeBa0AQI,253
78
78
  simo/core/__pycache__/views.cpython-38.pyc,sha256=ULyoiWRiU_auXTuxzi2RyqYIea9VfaiMuTzkMAWaWOA,2343
79
79
  simo/core/__pycache__/widgets.cpython-38.pyc,sha256=sR0ZeHCHrhnNDBJuRrxp3zUsfBp0xrtF0xrK2TkQv1o,3520
@@ -172,6 +172,9 @@ simo/core/migrations/0035_remove_instance_share_location.py,sha256=PeofRnw_INwN1
172
172
  simo/core/migrations/0036_auto_20240521_0823.py,sha256=dDgrcSGjONisbEGTfGYS-AaycI8XbHLf5aL2cbFHAwk,529
173
173
  simo/core/migrations/0037_auto_20240606_1057.py,sha256=nkjdiyP1M32p9VSfSgsYufvufywNXWAK6XoK4_1zDQA,783
174
174
  simo/core/migrations/0038_remove_instance_cover_image_and_more.py,sha256=cmTNDcRa3m2dBERWKXOjWv4maGIPDNocgdFamBE6drc,23669
175
+ simo/core/migrations/0039_instance_is_active_alter_instance_timezone.py,sha256=8VobRMIQDxa22gBsERRXn0akiVvD2L_qchPY2Sd5a7k,23490
176
+ simo/core/migrations/0040_alter_instance_name.py,sha256=FqUq-NnO_eqMy3lg5Yl0uG3C-NgC_Qff7bcoBipTZSc,424
177
+ simo/core/migrations/0041_alter_instance_slug.py,sha256=MmuW0n5CCpF7NyKYINDcqChOU1DynSqQu_3wAYQypCo,401
175
178
  simo/core/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
176
179
  simo/core/migrations/__pycache__/0001_initial.cpython-38.pyc,sha256=w6GiBXVxWj30Bg4Sn_pFVeA041d-pCrkaq8mR3KuF70,5381
177
180
  simo/core/migrations/__pycache__/0002_load_icons.cpython-38.pyc,sha256=Nb9RrPjVYo_RpZ5PmzoaEIWGCeVt4kicpmGiKlBrpIw,2123
@@ -211,6 +214,9 @@ simo/core/migrations/__pycache__/0035_remove_instance_share_location.cpython-38.
211
214
  simo/core/migrations/__pycache__/0036_auto_20240521_0823.cpython-38.pyc,sha256=iIdvU2s5UBI0guWpQWOSx7QynQ99myuK6Dqopeg7V0I,693
212
215
  simo/core/migrations/__pycache__/0037_auto_20240606_1057.cpython-38.pyc,sha256=tFwNfVe5Xat1300vhHKSL0tLAvt0jbVSENQD_5U85Og,1062
213
216
  simo/core/migrations/__pycache__/0038_remove_instance_cover_image_and_more.cpython-38.pyc,sha256=fl4w4fy8hT6rGf_MB1pcRosJwaEvnxT9rqLEi1JpPgA,16542
217
+ simo/core/migrations/__pycache__/0039_instance_is_active_alter_instance_timezone.cpython-38.pyc,sha256=E3gQfskgqsPm5JgAVGa5WsVSO4GKO_puDhQL_s1zo2s,16512
218
+ simo/core/migrations/__pycache__/0040_alter_instance_name.cpython-38.pyc,sha256=PPZHAHRMnFS0PsPHxovAkkM3cPEQnLOyJz8q25ZshWs,642
219
+ simo/core/migrations/__pycache__/0041_alter_instance_slug.cpython-38.pyc,sha256=tVBd5-92gJPHR-I2yjUhsbtxwcykBMzxA6W3mvs8giE,620
214
220
  simo/core/migrations/__pycache__/__init__.cpython-38.pyc,sha256=VZmDQ57BTcebuM0KMhjiTOabgWZCBxQmSJzWZos9SO8,169
215
221
  simo/core/static/ansi_styles.css,sha256=4ieJGrjZPKyPSago9FdB_gflHoGE1vxCHi8qVn5tY-Y,37352
216
222
  simo/core/static/admin/Img/plus.svg,sha256=2NpSFPWqGIjpAQGFI7LDQHPKagEhYkJiJX95ufCoZaI,741
@@ -10337,7 +10343,7 @@ simo/generic/templates/generic/controllers_info/stateselect.md,sha256=T0w3vJg02W
10337
10343
  simo/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10338
10344
  simo/management/auto_update.py,sha256=4MDrJHdtC5LxEJM258Y0kc5yI4yloeKhDjh-S2BN-ZQ,2115
10339
10345
  simo/management/copy_template.py,sha256=Iehq57FYMzdHNp3LU4ue6rr6AkRiGeOthG7PoGWd88Q,2002
10340
- simo/management/install.py,sha256=s9GqIRwLpli8g_utu2pZ0QGVSXSHFXbkY12S_R3MnVc,10127
10346
+ simo/management/install.py,sha256=hy2LB0sPNpaFHv2Wvp6CeiItvKJb3sFVU0lJuz02VDM,10127
10341
10347
  simo/management/on_http_start.py,sha256=ZDotfMQaCjksD5FFf3eZYgJS-gd_-7eZhYTHLaD-448,3312
10342
10348
  simo/management/__pycache__/__init__.cpython-38.pyc,sha256=ey9k5mPsmvAHRVf5Du6QUqy40LgBCAPN_B5EaR6h9Eg,164
10343
10349
  simo/management/__pycache__/on_http_start.cpython-38.pyc,sha256=ERfcMNz3QnqDJTJ4PwbmDfLgPCh5hrEcaedejARFkUQ,2864
@@ -10402,7 +10408,7 @@ simo/users/auth_backends.py,sha256=I5pnaTa20-Lxfw_dFG8471xDITb0_fQl1PVhJalp5vU,3
10402
10408
  simo/users/auto_urls.py,sha256=lcJvteBsbHQMJieZpDz-63tDYejLApqsW3CUnDakd7k,272
10403
10409
  simo/users/dynamic_settings.py,sha256=sEIsi4yJw3kH46Jq_aOkSuK7QTfQACGUE-lkyBogCaM,570
10404
10410
  simo/users/middleware.py,sha256=GMCrnWSc_2qCleyQIkfQGdL-pU-UTEcSg1wPvIKZ9uk,1210
10405
- simo/users/models.py,sha256=uelvMDt-sq07wvXONPiikwzWuIbDc3I3eG6HLza1f2g,19691
10411
+ simo/users/models.py,sha256=SnYBP-d7Z6eXCqb-aBayocpdbJSQfKw5qUaPgsxzqfY,19731
10406
10412
  simo/users/permissions.py,sha256=IwtYS8yQdupWbYKR9VimSRDV3qCJ2jXP57Lyjpb2EQM,242
10407
10413
  simo/users/serializers.py,sha256=DwbFGi4WeTYXOSnfrBfd5rC5OGtevYurn27EaTVa1EU,2553
10408
10414
  simo/users/sso_urls.py,sha256=gQOaPvGMYFD0NCVSwyoWO-mTEHe5j9sbzV_RK7kdvp0,251
@@ -10418,7 +10424,7 @@ simo/users/__pycache__/auth_backends.cpython-38.pyc,sha256=MuOieBIXt6lrDx83-UQtd
10418
10424
  simo/users/__pycache__/auto_urls.cpython-38.pyc,sha256=K-3sz2h-cEitoflSmZk1t0eUg5mQMMGLNZFREVwG7_o,430
10419
10425
  simo/users/__pycache__/dynamic_settings.cpython-38.pyc,sha256=6F8JBjZkHykySnmZjNEzjS0ijbmPdcp9yUAZ5kqq_Fo,864
10420
10426
  simo/users/__pycache__/middleware.cpython-38.pyc,sha256=Tj4nVEAvxEW3xA63fBRiJWRJpz_M848ZOqbHioc_IPE,1149
10421
- simo/users/__pycache__/models.cpython-38.pyc,sha256=K1EUMaEQThJ0xNj863Q-_-cbMKFh1SR8syElVdv96yg,18294
10427
+ simo/users/__pycache__/models.cpython-38.pyc,sha256=mGTfDKyCDfLc4_KDzi8446eCJnL7lqj-NKkrMVv00zk,18319
10422
10428
  simo/users/__pycache__/permissions.cpython-38.pyc,sha256=ez5NxoL_JUeeH6GsKhvFreuA3FCBgGf9floSypdXUtM,633
10423
10429
  simo/users/__pycache__/serializers.cpython-38.pyc,sha256=tZzdmCdSnqekAgRl0kyq-msm7QfUA0J_IipfrysAMRM,3477
10424
10430
  simo/users/__pycache__/sso_urls.cpython-38.pyc,sha256=uAwDozpOmrhUald-8tOHANILXkH7-TI8fNYXOtPkSY8,402
@@ -10454,6 +10460,7 @@ simo/users/migrations/0025_rename_name_fingerprint_type_and_more.py,sha256=Azw_a
10454
10460
  simo/users/migrations/0026_fingerprint_name.py,sha256=DPmfi1brbaPymdNiPgc7dINSKy97yVHdKpKp-ZfnS3I,428
10455
10461
  simo/users/migrations/0027_permissionsrole_can_manage_components.py,sha256=VcGZE6u-q6UkGo7D01K_T1XBtIvIGe8SCk5ZPRrPpGo,485
10456
10462
  simo/users/migrations/0028_auto_20240506_1146.py,sha256=7RUFF2rJH-bnPeHwc77p8Q4kEAc3owyG4qp9Kc4aKhU,716
10463
+ simo/users/migrations/0029_alter_instanceuser_instance.py,sha256=5ebO0vX9lCnTXBMkWg8633sBCBLNtMLfbocVY-uyQhE,588
10457
10464
  simo/users/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10458
10465
  simo/users/migrations/__pycache__/0001_initial.cpython-38.pyc,sha256=ngXA1QR-Qc2VS-BTTZWybVXiEfifIgKaVS6bADiN8nU,4269
10459
10466
  simo/users/migrations/__pycache__/0002_componentpermission.cpython-38.pyc,sha256=pknJnpic8p6Vdx9DX41FfODXNnvexDswJtUCmC5w1tg,995
@@ -10483,6 +10490,7 @@ simo/users/migrations/__pycache__/0025_rename_name_fingerprint_type_and_more.cpy
10483
10490
  simo/users/migrations/__pycache__/0026_fingerprint_name.cpython-38.pyc,sha256=Ti0NLIKb0Wffn33LCBQQ-cumFCX6JFxSi1FYoV8C0ZE,642
10484
10491
  simo/users/migrations/__pycache__/0027_permissionsrole_can_manage_components.cpython-38.pyc,sha256=Ju4FLSKUNoJ419bAp_Np_MKrSyxzlJnYGfeNYg7HC5M,721
10485
10492
  simo/users/migrations/__pycache__/0028_auto_20240506_1146.cpython-38.pyc,sha256=e8J_lTYJMixdqV37OgonG9ndd9gjn1E9hVj-jh4bxGw,874
10493
+ simo/users/migrations/__pycache__/0029_alter_instanceuser_instance.cpython-38.pyc,sha256=2EsX6ksqPomNHiPCORDYENqn2yI7dQUK_4hMSpMVxDE,823
10486
10494
  simo/users/migrations/__pycache__/0029_alter_instanceuser_options_instanceuser_order.cpython-38.pyc,sha256=aqC63NS8xpFKzLuvL00_axUAvjTzqmvlgfkD03bzakg,721
10487
10495
  simo/users/migrations/__pycache__/0030_alter_instanceuser_options_remove_instanceuser_order.cpython-38.pyc,sha256=uC2t0g2AGdQ53Z621ZcS4-n6UGxjRUM6AFUAMrGIMnY,658
10488
10496
  simo/users/migrations/__pycache__/__init__.cpython-38.pyc,sha256=NKq7WLgktK8WV1oOqCPbAbdkrPV5GRGhYx4VxxI4dcs,170
@@ -10494,9 +10502,9 @@ simo/users/templates/invitations/expired_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCe
10494
10502
  simo/users/templates/invitations/expired_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10495
10503
  simo/users/templates/invitations/taken_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10496
10504
  simo/users/templates/invitations/taken_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10497
- simo-2.1.5.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
10498
- simo-2.1.5.dist-info/METADATA,sha256=sV13UwrNRCCV4LImcqM__PHth4pKToD1KXgItU6eMoY,1817
10499
- simo-2.1.5.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
10500
- simo-2.1.5.dist-info/entry_points.txt,sha256=SJBxiDpH7noO0STxVI_eRIsGR-nLgdXXeqCDe8cXlbM,65
10501
- simo-2.1.5.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
10502
- simo-2.1.5.dist-info/RECORD,,
10505
+ simo-2.1.7.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
10506
+ simo-2.1.7.dist-info/METADATA,sha256=GmYnqsbm6poKGIYXr6sl5CHQHn-5b7BVWLpiZpI0OgM,1847
10507
+ simo-2.1.7.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
10508
+ simo-2.1.7.dist-info/entry_points.txt,sha256=SJBxiDpH7noO0STxVI_eRIsGR-nLgdXXeqCDe8cXlbM,65
10509
+ simo-2.1.7.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
10510
+ simo-2.1.7.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (70.1.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5