simo 1.6.2__py3-none-any.whl → 1.6.4__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 +0 -1
- simo/core/apps.py +1 -1
- simo/core/autocomplete_views.py +4 -5
- simo/core/events.py +56 -0
- simo/core/middleware.py +1 -7
- simo/core/migrations/0022_auto_20231221_0735.py +23 -0
- simo/core/models.py +3 -49
- simo/core/socket_consumers.py +1 -1
- simo/core/widgets.py +9 -0
- simo/generic/controllers.py +1 -0
- simo/users/admin.py +6 -6
- simo/users/api.py +13 -17
- simo/users/auth_backends.py +2 -2
- simo/users/migrations/0017_auto_20231221_0735.py +22 -0
- simo/users/models.py +23 -4
- simo/users/serializers.py +2 -2
- {simo-1.6.2.dist-info → simo-1.6.4.dist-info}/METADATA +1 -1
- {simo-1.6.2.dist-info → simo-1.6.4.dist-info}/RECORD +21 -19
- {simo-1.6.2.dist-info → simo-1.6.4.dist-info}/LICENSE.md +0 -0
- {simo-1.6.2.dist-info → simo-1.6.4.dist-info}/WHEEL +0 -0
- {simo-1.6.2.dist-info → simo-1.6.4.dist-info}/top_level.txt +0 -0
simo/core/api.py
CHANGED
|
@@ -3,7 +3,6 @@ from calendar import monthrange
|
|
|
3
3
|
import pytz
|
|
4
4
|
import logging
|
|
5
5
|
from django.db.models import Q, Prefetch
|
|
6
|
-
from django.urls import get_script_prefix
|
|
7
6
|
from django.utils.translation import gettext_lazy as _
|
|
8
7
|
from django.utils import timezone
|
|
9
8
|
from django.shortcuts import get_object_or_404
|
simo/core/apps.py
CHANGED
|
@@ -19,6 +19,6 @@ class CoreAppConfig(AppConfig):
|
|
|
19
19
|
# We are running as root and there is no symbolic link yet made
|
|
20
20
|
# for auto updates.
|
|
21
21
|
os.symlink(auto_update_file_path, executable_path)
|
|
22
|
-
auto_update_cron = f'
|
|
22
|
+
auto_update_cron = f'0 * * * * {executable_path} \n'
|
|
23
23
|
cron_out = subprocess.Popen(['crontab', '-'], stdin=subprocess.PIPE)
|
|
24
24
|
cron_out.communicate(input=str.encode(auto_update_cron))
|
simo/core/autocomplete_views.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from dal import autocomplete
|
|
2
|
-
from django.urls import get_script_prefix
|
|
3
2
|
from django.db.models import Q
|
|
4
3
|
from django.template.loader import render_to_string
|
|
5
4
|
from simo.core.utils.helpers import search_queryset
|
|
@@ -24,7 +23,7 @@ class IconModelAutocomplete(autocomplete.Select2QuerySetView):
|
|
|
24
23
|
def get_result_label(self, item):
|
|
25
24
|
return render_to_string(
|
|
26
25
|
'core/icon_acutocomplete_select_item.html', {
|
|
27
|
-
'icon': item,
|
|
26
|
+
'icon': item,
|
|
28
27
|
}
|
|
29
28
|
)
|
|
30
29
|
|
|
@@ -70,7 +69,7 @@ class CategoryAutocomplete(autocomplete.Select2QuerySetView):
|
|
|
70
69
|
def get_result_label(self, item):
|
|
71
70
|
return render_to_string(
|
|
72
71
|
'core/object_acutocomplete_select_item.html', {
|
|
73
|
-
'object': item
|
|
72
|
+
'object': item
|
|
74
73
|
}
|
|
75
74
|
)
|
|
76
75
|
|
|
@@ -96,7 +95,7 @@ class ZoneAutocomplete(autocomplete.Select2QuerySetView):
|
|
|
96
95
|
def get_result_label(self, item):
|
|
97
96
|
return render_to_string(
|
|
98
97
|
'core/object_acutocomplete_select_item.html', {
|
|
99
|
-
'object': item
|
|
98
|
+
'object': item
|
|
100
99
|
}
|
|
101
100
|
)
|
|
102
101
|
|
|
@@ -133,7 +132,7 @@ class ComponentAutocomplete(autocomplete.Select2QuerySetView):
|
|
|
133
132
|
def get_result_label(self, item):
|
|
134
133
|
return render_to_string(
|
|
135
134
|
'core/object_acutocomplete_select_item.html', {
|
|
136
|
-
'object': item
|
|
135
|
+
'object': item
|
|
137
136
|
}
|
|
138
137
|
)
|
|
139
138
|
|
simo/core/events.py
CHANGED
|
@@ -2,9 +2,14 @@ import json
|
|
|
2
2
|
import time
|
|
3
3
|
import logging
|
|
4
4
|
import threading
|
|
5
|
+
import sys
|
|
6
|
+
import json
|
|
7
|
+
import traceback
|
|
8
|
+
import pytz
|
|
5
9
|
from django.contrib.contenttypes.models import ContentType
|
|
6
10
|
from django.conf import settings
|
|
7
11
|
import paho.mqtt.client as mqtt
|
|
12
|
+
from django.utils import timezone
|
|
8
13
|
from django.utils.translation import gettext_lazy as _
|
|
9
14
|
import paho.mqtt.publish as mqtt_publish
|
|
10
15
|
|
|
@@ -130,3 +135,54 @@ class EventsStream:
|
|
|
130
135
|
def on_tick(self):
|
|
131
136
|
"""Override me to do something every second"""
|
|
132
137
|
pass
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class OnChangeMixin:
|
|
141
|
+
|
|
142
|
+
on_change_fields = ('value', )
|
|
143
|
+
|
|
144
|
+
def get_instance(self):
|
|
145
|
+
# default for component
|
|
146
|
+
return self.zone.instance.timezone
|
|
147
|
+
|
|
148
|
+
def on_mqtt_connect(self, mqtt_client, userdata, flags, rc):
|
|
149
|
+
mqtt_client.subscribe(ObjectManagementEvent.TOPIC)
|
|
150
|
+
|
|
151
|
+
def on_mqtt_message(self, client, userdata, msg):
|
|
152
|
+
payload = json.loads(msg.payload)
|
|
153
|
+
if not self._on_change_function:
|
|
154
|
+
return
|
|
155
|
+
if payload['obj_pk'] != self.id:
|
|
156
|
+
return
|
|
157
|
+
if payload['obj_ct_pk'] != self._obj_ct_id:
|
|
158
|
+
return
|
|
159
|
+
if payload['event'] != 'changed':
|
|
160
|
+
return
|
|
161
|
+
if 'value' not in payload.get('dirty_fields', {}):
|
|
162
|
+
return
|
|
163
|
+
|
|
164
|
+
tz = pytz.timezone(self.gget_instance().timezone)
|
|
165
|
+
timezone.activate(tz)
|
|
166
|
+
|
|
167
|
+
self.refresh_from_db()
|
|
168
|
+
|
|
169
|
+
try:
|
|
170
|
+
self._on_change_function(self)
|
|
171
|
+
except Exception:
|
|
172
|
+
print(traceback.format_exc(), file=sys.stderr)
|
|
173
|
+
|
|
174
|
+
def on_change(self, function):
|
|
175
|
+
if function:
|
|
176
|
+
self._mqtt_client = mqtt.Client()
|
|
177
|
+
self._mqtt_client.on_connect = self.on_mqtt_connect
|
|
178
|
+
self._mqtt_client.on_message = self.on_mqtt_message
|
|
179
|
+
self._mqtt_client.connect(host=settings.MQTT_HOST,
|
|
180
|
+
port=settings.MQTT_PORT)
|
|
181
|
+
self._mqtt_client.loop_start()
|
|
182
|
+
self._on_change_function = function
|
|
183
|
+
self._obj_ct_id = ContentType.objects.get_for_model(self).pk
|
|
184
|
+
elif self._mqtt_client:
|
|
185
|
+
self._mqtt_client.disconnect()
|
|
186
|
+
self._mqtt_client.loop_stop()
|
|
187
|
+
self._mqtt_client = None
|
|
188
|
+
self._on_change_function = None
|
simo/core/middleware.py
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import pytz
|
|
2
2
|
import threading
|
|
3
|
-
from django.urls import set_script_prefix
|
|
4
|
-
from django.shortcuts import redirect, render
|
|
3
|
+
from django.urls import set_script_prefix
|
|
5
4
|
from django.utils import timezone
|
|
6
|
-
from django.conf import settings
|
|
7
|
-
from simo.users.models import User
|
|
8
5
|
from simo.conf import dynamic_settings
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
|
|
12
7
|
_thread_locals = threading.local()
|
|
13
8
|
|
|
14
9
|
|
|
@@ -25,7 +20,6 @@ def simo_router_middleware(get_response):
|
|
|
25
20
|
_thread_locals.request = request
|
|
26
21
|
|
|
27
22
|
request.relay = None
|
|
28
|
-
router_prefix = '/'
|
|
29
23
|
|
|
30
24
|
if request.META.get('HTTP_HOST', '').endswith('.simo.io'):
|
|
31
25
|
router_prefix = dynamic_settings['core__remote_http']
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Generated by Django 3.2.9 on 2023-12-21 07:35
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
('core', '0021_auto_20231020_1041'),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AlterField(
|
|
14
|
+
model_name='gateway',
|
|
15
|
+
name='type',
|
|
16
|
+
field=models.CharField(choices=[('simo.generic.gateways.DummyGatewayHandler', 'Dummy'), ('simo_esphome.gateways.ESPHomeGatewayHandler', 'ESPHome'), ('simo.generic.gateways.GenericGatewayHandler', 'Generic'), ('NukiDevices', 'Nuki'), ('simo_fleet.gateways.FleetGatewayHandler', 'SIMO.io Fleet'), ('simo_sonos.gateways.SONOSGatewayHandler', 'SONOS'), ('simo_zwave.gateways.ZwaveGatewayHandler', 'Zwave')], db_index=True, max_length=200, unique=True),
|
|
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/Ciudad_Juarez', 'America/Ciudad_Juarez'), ('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/Kyiv', 'Europe/Kyiv'), ('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
|
+
]
|
simo/core/models.py
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import sys
|
|
3
3
|
import inspect
|
|
4
|
-
|
|
5
|
-
import traceback
|
|
6
|
-
import pytz
|
|
4
|
+
|
|
7
5
|
from django.utils.text import slugify
|
|
8
6
|
from django.core.cache import cache
|
|
9
7
|
from django.urls import reverse_lazy
|
|
@@ -25,10 +23,7 @@ from django.contrib.contenttypes.models import ContentType
|
|
|
25
23
|
from simo.core.utils.mixins import SimoAdminMixin
|
|
26
24
|
from simo.core.storage import OverwriteStorage
|
|
27
25
|
from simo.core.utils.validators import validate_svg
|
|
28
|
-
from .events import ObjectCommand, ObjectManagementEvent
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
from .events import ObjectCommand, ObjectManagementEvent, OnChangeMixin
|
|
32
27
|
|
|
33
28
|
|
|
34
29
|
User = get_user_model()
|
|
@@ -239,7 +234,7 @@ class Gateway(DirtyFieldsMixin, models.Model, SimoAdminMixin):
|
|
|
239
234
|
)
|
|
240
235
|
|
|
241
236
|
|
|
242
|
-
class Component(DirtyFieldsMixin, models.Model, SimoAdminMixin):
|
|
237
|
+
class Component(DirtyFieldsMixin, models.Model, SimoAdminMixin, OnChangeMixin):
|
|
243
238
|
name = models.CharField(
|
|
244
239
|
_('name'), max_length=100, db_index=True
|
|
245
240
|
)
|
|
@@ -403,47 +398,6 @@ def translate_before_set(self, value):
|
|
|
403
398
|
return '%s | %s' % (self.zone.name, self.name)
|
|
404
399
|
return self.name
|
|
405
400
|
|
|
406
|
-
def on_mqtt_connect(self, mqtt_client, userdata, flags, rc):
|
|
407
|
-
mqtt_client.subscribe(ObjectManagementEvent.TOPIC)
|
|
408
|
-
|
|
409
|
-
def on_mqtt_message(self, client, userdata, msg):
|
|
410
|
-
payload = json.loads(msg.payload)
|
|
411
|
-
if not self._on_change_function:
|
|
412
|
-
return
|
|
413
|
-
if payload['obj_pk'] != self.id:
|
|
414
|
-
return
|
|
415
|
-
if payload['obj_ct_pk'] != self._obj_ct_id:
|
|
416
|
-
return
|
|
417
|
-
if payload['event'] != 'changed':
|
|
418
|
-
return
|
|
419
|
-
if 'value' not in payload.get('dirty_fields', {}):
|
|
420
|
-
return
|
|
421
|
-
|
|
422
|
-
tz = pytz.timezone(self.zone.instance.timezone)
|
|
423
|
-
timezone.activate(tz)
|
|
424
|
-
|
|
425
|
-
self.refresh_from_db()
|
|
426
|
-
|
|
427
|
-
try:
|
|
428
|
-
self._on_change_function(self)
|
|
429
|
-
except Exception:
|
|
430
|
-
print(traceback.format_exc(), file=sys.stderr)
|
|
431
|
-
|
|
432
|
-
def on_change(self, function):
|
|
433
|
-
if function:
|
|
434
|
-
self._mqtt_client = mqtt.Client()
|
|
435
|
-
self._mqtt_client.on_connect = self.on_mqtt_connect
|
|
436
|
-
self._mqtt_client.on_message = self.on_mqtt_message
|
|
437
|
-
self._mqtt_client.connect(host=settings.MQTT_HOST,
|
|
438
|
-
port=settings.MQTT_PORT)
|
|
439
|
-
self._mqtt_client.loop_start()
|
|
440
|
-
self._on_change_function = function
|
|
441
|
-
self._obj_ct_id = ContentType.objects.get_for_model(self).pk
|
|
442
|
-
elif self._mqtt_client:
|
|
443
|
-
self._mqtt_client.disconnect()
|
|
444
|
-
self._mqtt_client.loop_stop()
|
|
445
|
-
self._mqtt_client = None
|
|
446
|
-
self._on_change_function = None
|
|
447
401
|
|
|
448
402
|
def get_socket_url(self):
|
|
449
403
|
return reverse_lazy(
|
simo/core/socket_consumers.py
CHANGED
|
@@ -6,7 +6,7 @@ import os
|
|
|
6
6
|
import logging
|
|
7
7
|
from ansi2html import Ansi2HTMLConverter
|
|
8
8
|
from asgiref.sync import sync_to_async
|
|
9
|
-
from django.urls import set_script_prefix
|
|
9
|
+
from django.urls import set_script_prefix
|
|
10
10
|
from django.core.exceptions import ValidationError
|
|
11
11
|
from django.template.loader import render_to_string
|
|
12
12
|
from django.conf import settings
|
simo/core/widgets.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from django import forms
|
|
2
2
|
from django.conf import settings
|
|
3
|
+
from django.templatetags.static import static
|
|
3
4
|
from django.utils.safestring import mark_safe
|
|
4
5
|
from location_field.widgets import LocationWidget as OrgLocationWidget
|
|
5
6
|
|
|
@@ -12,6 +13,14 @@ class LocationWidget(OrgLocationWidget):
|
|
|
12
13
|
if zoom:
|
|
13
14
|
self.options['map.zoom'] = zoom
|
|
14
15
|
|
|
16
|
+
@property
|
|
17
|
+
def media(self):
|
|
18
|
+
return forms.Media({
|
|
19
|
+
'js': [
|
|
20
|
+
static('location_field') + '/js/form.js',
|
|
21
|
+
],
|
|
22
|
+
})
|
|
23
|
+
|
|
15
24
|
|
|
16
25
|
class SVGFileWidget(forms.ClearableFileInput):
|
|
17
26
|
template_name = 'admin/svg_file_widget.html'
|
simo/generic/controllers.py
CHANGED
|
@@ -1123,6 +1123,7 @@ class AlarmClock(ControllerBase):
|
|
|
1123
1123
|
week_days.sort()
|
|
1124
1124
|
week_days = week_days + [d + 7 for d in week_days]
|
|
1125
1125
|
for wd in week_days:
|
|
1126
|
+
alarm = json.loads(json.dumps(alarm))
|
|
1126
1127
|
if wd < weekday:
|
|
1127
1128
|
continue
|
|
1128
1129
|
days_diff = wd - weekday
|
simo/users/admin.py
CHANGED
|
@@ -6,7 +6,7 @@ from django.contrib.auth.admin import UserAdmin as OrgUserAdmin
|
|
|
6
6
|
from django.contrib import admin
|
|
7
7
|
from .models import (
|
|
8
8
|
PermissionsRole, ComponentPermission, User, UserDevice, UserDeviceReportLog,
|
|
9
|
-
InstanceInvitation,
|
|
9
|
+
InstanceInvitation, InstanceUser
|
|
10
10
|
)
|
|
11
11
|
|
|
12
12
|
|
|
@@ -67,8 +67,8 @@ class UserDeviceInline(admin.TabularInline):
|
|
|
67
67
|
return mark_safe('<a href="%s">more >></a>' % obj.get_admin_url())
|
|
68
68
|
|
|
69
69
|
|
|
70
|
-
class
|
|
71
|
-
model =
|
|
70
|
+
class InstanceUserInline(admin.TabularInline):
|
|
71
|
+
model = InstanceUser
|
|
72
72
|
extra = 0
|
|
73
73
|
readonly_fields = 'instance', 'at_home'
|
|
74
74
|
|
|
@@ -90,7 +90,7 @@ class UserAdmin(OrgUserAdmin):
|
|
|
90
90
|
'name', 'email', 'avatar',
|
|
91
91
|
'last_action', 'ssh_key',
|
|
92
92
|
)
|
|
93
|
-
inlines = UserDeviceInline,
|
|
93
|
+
inlines = UserDeviceInline, InstanceUserInline
|
|
94
94
|
|
|
95
95
|
def name_display(self, obj=None):
|
|
96
96
|
if not obj:
|
|
@@ -132,8 +132,8 @@ admin.site.unregister(Group)
|
|
|
132
132
|
@admin.register(UserDeviceReportLog)
|
|
133
133
|
class UserDeviceLogInline(admin.ModelAdmin):
|
|
134
134
|
model = UserDeviceReportLog
|
|
135
|
-
readonly_fields = 'datetime', 'app_open', 'location', 'relay'
|
|
136
|
-
list_display = 'datetime', 'app_open', 'location', 'relay'
|
|
135
|
+
readonly_fields = 'datetime', 'app_open', 'location', 'relay'
|
|
136
|
+
list_display = 'datetime', 'app_open', 'location', 'relay'
|
|
137
137
|
fields = readonly_fields
|
|
138
138
|
list_filter = 'user_device__user',
|
|
139
139
|
|
simo/users/api.py
CHANGED
|
@@ -11,7 +11,7 @@ from simo.core.api import InstanceMixin
|
|
|
11
11
|
from simo.core.models import Instance
|
|
12
12
|
from .models import (
|
|
13
13
|
User, UserDevice, UserDeviceReportLog, PermissionsRole, InstanceInvitation,
|
|
14
|
-
|
|
14
|
+
InstanceUser
|
|
15
15
|
)
|
|
16
16
|
from .serializers import (
|
|
17
17
|
UserSerializer, PermissionsRoleSerializer, InstanceInvitationSerializer
|
|
@@ -169,12 +169,6 @@ class UserDeviceReport(viewsets.GenericViewSet):
|
|
|
169
169
|
if request.META.get('HTTP_HOST', '').endswith('.simo.io'):
|
|
170
170
|
relay = request.META.get('HTTP_HOST')
|
|
171
171
|
|
|
172
|
-
at_home = False
|
|
173
|
-
if not relay:
|
|
174
|
-
at_home = True
|
|
175
|
-
elif location:
|
|
176
|
-
pass
|
|
177
|
-
|
|
178
172
|
|
|
179
173
|
# TODO: fire at home event:
|
|
180
174
|
# from simo.core.events import Event
|
|
@@ -185,9 +179,9 @@ class UserDeviceReport(viewsets.GenericViewSet):
|
|
|
185
179
|
# ).publish()
|
|
186
180
|
|
|
187
181
|
if not relay:
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
182
|
+
for item in InstanceUser.objects.filter(user=request.user):
|
|
183
|
+
item.at_home = True
|
|
184
|
+
item.save()
|
|
191
185
|
elif location:
|
|
192
186
|
for instance in Instance.objects.all():
|
|
193
187
|
cords = instance.location
|
|
@@ -201,19 +195,21 @@ class UserDeviceReport(viewsets.GenericViewSet):
|
|
|
201
195
|
else:
|
|
202
196
|
if distance(instance_location, location).meters < \
|
|
203
197
|
dynamic_settings['users__at_home_radius']:
|
|
204
|
-
|
|
205
|
-
user=request.user, instance=instance
|
|
206
|
-
).update(at_home=True)
|
|
198
|
+
at_home = True
|
|
207
199
|
else:
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
200
|
+
at_home = False
|
|
201
|
+
|
|
202
|
+
for item in InstanceUser.objects.filter(
|
|
203
|
+
user=request.user, instance=instance
|
|
204
|
+
):
|
|
205
|
+
item.at_home = at_home
|
|
206
|
+
item.save()
|
|
211
207
|
|
|
212
208
|
log_entry = UserDeviceReportLog.objects.create(
|
|
213
209
|
user_device=user_device,
|
|
214
210
|
app_open=request.data.get('app_open', False),
|
|
215
211
|
location=','.join([str(i) for i in location]) if location else None,
|
|
216
|
-
relay=relay
|
|
212
|
+
relay=relay
|
|
217
213
|
)
|
|
218
214
|
# Do not keep more than 1000 entries for every device.
|
|
219
215
|
for log in UserDeviceReportLog.objects.filter(
|
simo/users/auth_backends.py
CHANGED
|
@@ -4,7 +4,7 @@ import requests
|
|
|
4
4
|
from django.core.files import File
|
|
5
5
|
from django.contrib.auth.backends import ModelBackend
|
|
6
6
|
from django.utils import timezone
|
|
7
|
-
from .models import User, InstanceInvitation,
|
|
7
|
+
from .models import User, InstanceInvitation, InstanceUser
|
|
8
8
|
from .utils import get_superuser_role
|
|
9
9
|
|
|
10
10
|
|
|
@@ -52,7 +52,7 @@ class SSOBackend(ModelBackend):
|
|
|
52
52
|
if invitation:
|
|
53
53
|
invitation.taken_by = user
|
|
54
54
|
invitation.save()
|
|
55
|
-
|
|
55
|
+
InstanceUser.objects.create(
|
|
56
56
|
user=user, role=invitation.role,
|
|
57
57
|
instance=invitation.instance
|
|
58
58
|
)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Generated by Django 3.2.9 on 2023-12-21 07:35
|
|
2
|
+
|
|
3
|
+
from django.db import migrations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
('core', '0022_auto_20231221_0735'),
|
|
10
|
+
('users', '0016_auto_20231005_1050'),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.RenameModel(
|
|
15
|
+
old_name='UserInstanceRole',
|
|
16
|
+
new_name='InstanceUser',
|
|
17
|
+
),
|
|
18
|
+
migrations.RemoveField(
|
|
19
|
+
model_name='userdevicereportlog',
|
|
20
|
+
name='at_home',
|
|
21
|
+
),
|
|
22
|
+
]
|
simo/users/models.py
CHANGED
|
@@ -7,6 +7,8 @@ from django.db.models import Q
|
|
|
7
7
|
from django.db import transaction
|
|
8
8
|
from django.db.models.signals import post_save, post_delete, m2m_changed
|
|
9
9
|
from django.dispatch import receiver
|
|
10
|
+
from model_utils import FieldTracker
|
|
11
|
+
from dirtyfields import DirtyFieldsMixin
|
|
10
12
|
from django.core.exceptions import ValidationError
|
|
11
13
|
from django.contrib.auth.models import (
|
|
12
14
|
AbstractBaseUser, PermissionsMixin, UserManager as DefaultUserManager
|
|
@@ -17,6 +19,7 @@ from location_field.models.plain import PlainLocationField
|
|
|
17
19
|
from simo.conf import dynamic_settings
|
|
18
20
|
from simo.core.utils.mixins import SimoAdminMixin
|
|
19
21
|
from simo.core.utils.helpers import get_random_string
|
|
22
|
+
from simo.core.events import OnChangeMixin
|
|
20
23
|
from .middleware import get_current_user
|
|
21
24
|
from .utils import rebuild_authorized_keys
|
|
22
25
|
|
|
@@ -69,7 +72,7 @@ class UserManager(DefaultUserManager):
|
|
|
69
72
|
return user
|
|
70
73
|
|
|
71
74
|
|
|
72
|
-
class
|
|
75
|
+
class InstanceUser(DirtyFieldsMixin, models.Model, OnChangeMixin):
|
|
73
76
|
user = models.ForeignKey(
|
|
74
77
|
'User', on_delete=models.CASCADE, related_name='instance_roles'
|
|
75
78
|
)
|
|
@@ -91,6 +94,23 @@ class UserInstanceRole(models.Model):
|
|
|
91
94
|
self.instance = self.role.instance
|
|
92
95
|
return super().save(*args, **kwargs)
|
|
93
96
|
|
|
97
|
+
def get_instance(self):
|
|
98
|
+
return self.instance
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@receiver(post_save, sender=InstanceUser)
|
|
102
|
+
def post_instance_user_save(sender, instance, created, **kwargs):
|
|
103
|
+
if created:
|
|
104
|
+
return
|
|
105
|
+
from simo.core.events import ObjectManagementEvent
|
|
106
|
+
dirty_fields = instance.get_dirty_fields()
|
|
107
|
+
if 'at_home' in dirty_fields:
|
|
108
|
+
def post_update():
|
|
109
|
+
ObjectManagementEvent(
|
|
110
|
+
instance, 'changed', dirty_fields=dirty_fields
|
|
111
|
+
).publish()
|
|
112
|
+
transaction.on_commit(post_update)
|
|
113
|
+
|
|
94
114
|
|
|
95
115
|
class User(AbstractBaseUser, SimoAdminMixin):
|
|
96
116
|
name = models.CharField(_('name'), max_length=150)
|
|
@@ -101,7 +121,7 @@ class User(AbstractBaseUser, SimoAdminMixin):
|
|
|
101
121
|
)
|
|
102
122
|
avatar_url = models.URLField(null=True, blank=True)
|
|
103
123
|
avatar_last_change = models.DateTimeField(auto_now_add=True)
|
|
104
|
-
roles = models.ManyToManyField(PermissionsRole, through=
|
|
124
|
+
roles = models.ManyToManyField(PermissionsRole, through=InstanceUser)
|
|
105
125
|
is_active = models.BooleanField(
|
|
106
126
|
_('active'),
|
|
107
127
|
default=True,
|
|
@@ -205,7 +225,7 @@ class User(AbstractBaseUser, SimoAdminMixin):
|
|
|
205
225
|
if not role:
|
|
206
226
|
raise ValueError("There is no such a role on this instance")
|
|
207
227
|
|
|
208
|
-
|
|
228
|
+
InstanceUser.objects.update_or_create(
|
|
209
229
|
user=self, instance=self._instance, defaults={
|
|
210
230
|
'role': role
|
|
211
231
|
}
|
|
@@ -324,7 +344,6 @@ class UserDeviceReportLog(models.Model):
|
|
|
324
344
|
help_text="Sent via remote relay if specified, otherwise it's from LAN."
|
|
325
345
|
)
|
|
326
346
|
location = PlainLocationField(zoom=7, null=True, blank=True)
|
|
327
|
-
at_home = models.BooleanField(default=False)
|
|
328
347
|
|
|
329
348
|
class Meta:
|
|
330
349
|
ordering = '-datetime',
|
simo/users/serializers.py
CHANGED
|
@@ -3,7 +3,7 @@ from collections.abc import Iterable
|
|
|
3
3
|
from simo.core.middleware import get_current_request
|
|
4
4
|
from simo.core.serializers import TimestampField
|
|
5
5
|
from easy_thumbnails.files import get_thumbnailer
|
|
6
|
-
from .models import User, PermissionsRole, InstanceInvitation,
|
|
6
|
+
from .models import User, PermissionsRole, InstanceInvitation, InstanceUser
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class UserSerializer(serializers.ModelSerializer):
|
|
@@ -42,7 +42,7 @@ class UserSerializer(serializers.ModelSerializer):
|
|
|
42
42
|
return None
|
|
43
43
|
|
|
44
44
|
def get_at_home(self, obj):
|
|
45
|
-
return
|
|
45
|
+
return InstanceUser.objects.filter(
|
|
46
46
|
user=obj
|
|
47
47
|
).first().at_home
|
|
48
48
|
|
|
@@ -14,34 +14,34 @@ simo/_hub_template/hub/settings.py,sha256=4QhvhbtLRxHvAntwqG_qeAAtpDUqKvN4jzw9u3
|
|
|
14
14
|
simo/_hub_template/hub/urls.py,sha256=Ydm-1BkYAzWeEF-MKSDIFf-7aE4qNLPm48-SA51XgJQ,25
|
|
15
15
|
simo/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
16
|
simo/core/admin.py,sha256=4l2XFoI9yUoOuQkyYdpwxt-PGj-VTVcMb-BiA_NHYok,16588
|
|
17
|
-
simo/core/api.py,sha256=
|
|
17
|
+
simo/core/api.py,sha256=AZBNVfi75XeoRU-VctlhHr25uIymuAn_cec4fNzUpAU,19177
|
|
18
18
|
simo/core/api_auth.py,sha256=8Pp6Rcn3aL5hpQpW2Ph5XZ1rWnN1MIFvium8zlbzSwQ,1108
|
|
19
19
|
simo/core/app_widgets.py,sha256=SP1txwI8_robAapIjalciS1cnJGoPH6udi6-k3fGC-g,1928
|
|
20
|
-
simo/core/apps.py,sha256=
|
|
20
|
+
simo/core/apps.py,sha256=T41TluDrtjzZ8T5LcvA5OnImmn08HB9tXk1SkZ52k3I,899
|
|
21
21
|
simo/core/auto_urls.py,sha256=YZcvHqmAs4_azA_F_yz3CBsxrHAGijOPHib3SJCAoR0,1089
|
|
22
|
-
simo/core/autocomplete_views.py,sha256=
|
|
22
|
+
simo/core/autocomplete_views.py,sha256=ygbVEOfyygWNy2BanB46Ov0NfWxBFAwwKp5CqAkrGMc,3849
|
|
23
23
|
simo/core/base_types.py,sha256=OkRoAHp8P3r79k3IlUzkhycqlHDkeq7AAhOgsz7qGz8,552
|
|
24
24
|
simo/core/context.py,sha256=xmGQ5h6HXw9-_XTuJSXyNiWDRHAVauqGCxmSJo0mxjE,1261
|
|
25
25
|
simo/core/controllers.py,sha256=pP93QRFdCDRdo-yOqZTHD_LBRkbM-LWeGwWpDanS6os,22836
|
|
26
26
|
simo/core/dynamic_settings.py,sha256=gLAL4IiZ55T-zXPsfwpaIYpw-QPfxkEJVbt-wNIlyrY,2214
|
|
27
|
-
simo/core/events.py,sha256=
|
|
27
|
+
simo/core/events.py,sha256=0q5Rez-C92JSJLo5PW1B8-lgWWRfF2OBH8XSPbHtN5c,5539
|
|
28
28
|
simo/core/filters.py,sha256=ghtOZcrwNAkIyF5_G9Sn73NkiI71mXv0NhwCk4IyMIM,411
|
|
29
29
|
simo/core/forms.py,sha256=s-Cjw--vibCmxk6IQ_4M5IQOMuE3Z8re75NFPPmi4O4,19735
|
|
30
30
|
simo/core/gateways.py,sha256=pFTOAfiglyGZ-6NCAHZZs1Lhnp0rVb3IhNc1vX7cZmY,2563
|
|
31
31
|
simo/core/loggers.py,sha256=EBdq23gTQScVfQVH-xeP90-wII2DQFDjoROAW6ggUP4,1645
|
|
32
|
-
simo/core/middleware.py,sha256=
|
|
33
|
-
simo/core/models.py,sha256=
|
|
32
|
+
simo/core/middleware.py,sha256=2EELD2mMWpPl3ispu2Yl7zeXUZp7s-PAJm-W-3BRsF0,1565
|
|
33
|
+
simo/core/models.py,sha256=m912O5z4fLYRGY58e5t4ZGZvKL06QPG_K5j4OWwLRYc,17862
|
|
34
34
|
simo/core/permissions.py,sha256=1GI59JZxl_sL9qzSt2uhoOnYnORDmcOJ8Fb37LbrhJE,576
|
|
35
35
|
simo/core/routing.py,sha256=X1_IHxyA-_Q7hw1udDoviVP4_FSBDl8GYETTC2zWTbY,499
|
|
36
36
|
simo/core/serializers.py,sha256=IX5Lnhq6v8tYVFysz7w5K7QelK3fVXOjTUMjuomzbBs,4200
|
|
37
37
|
simo/core/signal_receivers.py,sha256=sTHwSnCnBaZKFwTSEspkkH490GF7Paxar6KxyoWlh1I,3361
|
|
38
|
-
simo/core/socket_consumers.py,sha256=
|
|
38
|
+
simo/core/socket_consumers.py,sha256=gF6QVVr1T60IFSwx4dS8jlkUifRPlFqVrQq2AL4e5UY,9639
|
|
39
39
|
simo/core/storage.py,sha256=46x-20HXGa-_gHUBFZYYL72FoR3jjOaYt-i7QDHezzM,981
|
|
40
40
|
simo/core/tasks.py,sha256=jZKctxcEiO3sqVlkWRuDzeYrA77H_9hAc48mfTmOz_w,10225
|
|
41
41
|
simo/core/todos.py,sha256=eYVXfLGiapkxKK57XuviSNe3WsUYyIWZ0hgQJk7ThKo,665
|
|
42
42
|
simo/core/types.py,sha256=WJEq48mIbFi_5Alt4wxWMGXxNxUTXqfQU5koH7wqHHI,1108
|
|
43
43
|
simo/core/views.py,sha256=Vr4eyLLIbxyPld-mOWH-hn0iqFfAbrK2jCHo_7nhvYE,5420
|
|
44
|
-
simo/core/widgets.py,sha256=
|
|
44
|
+
simo/core/widgets.py,sha256=J9e06C6I22F6xKic3VMgG7WeX07glAcl-4bF2Mg180A,2827
|
|
45
45
|
simo/core/db_backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
46
46
|
simo/core/db_backend/base.py,sha256=IiE1r74oa6z05QhFMDUnn2ET0dYpye_fMaw_ksYHnrA,1303
|
|
47
47
|
simo/core/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -70,6 +70,7 @@ simo/core/migrations/0018_auto_20231005_0622.py,sha256=NCITPVoBK_QC-oarTvjzvw-0I
|
|
|
70
70
|
simo/core/migrations/0019_alter_gateway_type.py,sha256=qy4vwa4Rm2iE1Kez3X-EMrOGyTMfoQum8Qb45KtUaKQ,738
|
|
71
71
|
simo/core/migrations/0020_component_meta.py,sha256=aO3qKCRZoAkdKIbRBDlN3H0YaOJmAnvFBScRqDSRy3I,397
|
|
72
72
|
simo/core/migrations/0021_auto_20231020_1041.py,sha256=OmXoVeWfb8HPvGlP0iC1ZYqByj7pI4T6L2-lEsmbfSQ,998
|
|
73
|
+
simo/core/migrations/0022_auto_20231221_0735.py,sha256=vn8eIRzqWetG_6z3m9dOXqaWtUKeNS3oTkv3EbtwWbY,23894
|
|
73
74
|
simo/core/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
74
75
|
simo/core/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
75
76
|
simo/core/templatetags/components_list.py,sha256=dcwXEgVrP2xuRpGpv1yQ_DHvmitsuF93PhDa9y69F2M,18540
|
|
@@ -90,7 +91,7 @@ simo/core/utils/validators.py,sha256=PGqW9E8tA6I68RiZg_38DS_MsZs1ew_6vQY4YRKhBdU
|
|
|
90
91
|
simo/generic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
91
92
|
simo/generic/app_widgets.py,sha256=E_pnpA1hxMIhenRCrHoQ5cik06jm2BAHCkl_eo-OudU,1264
|
|
92
93
|
simo/generic/base_types.py,sha256=djymox_boXTHX1BTTCLXrCH7ED-uAsV_idhaDOc3OLI,409
|
|
93
|
-
simo/generic/controllers.py,sha256=
|
|
94
|
+
simo/generic/controllers.py,sha256=J8lfRwgfRIS9BS901lKZZO4tuRus7XKXVIG8VRTBQgQ,51144
|
|
94
95
|
simo/generic/forms.py,sha256=zF-QYfu6C0TZ7sJ5_-VkhUweV0_J8gg0CC07At6RIK8,19829
|
|
95
96
|
simo/generic/gateways.py,sha256=Pp29L_2AoZ_4nW6rLHmDCbDoac-yK9evJ1ZTcfMOItc,14807
|
|
96
97
|
simo/generic/models.py,sha256=XG8VnLSpMSiBnbKwvMknF9J9kdbmBolXvJ9L3Giz8pQ,3330
|
|
@@ -121,15 +122,15 @@ simo/notifications/migrations/0001_initial.py,sha256=Zh69AQ-EKlQKfqfnMDVRcxvo1Mx
|
|
|
121
122
|
simo/notifications/migrations/0002_notification_instance.py,sha256=B3msbMeKvsuq-V7gvRADRjj5PFLayhi3pQvHZjqzO5g,563
|
|
122
123
|
simo/notifications/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
123
124
|
simo/users/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
124
|
-
simo/users/admin.py,sha256=
|
|
125
|
-
simo/users/api.py,sha256=
|
|
126
|
-
simo/users/auth_backends.py,sha256=
|
|
125
|
+
simo/users/admin.py,sha256=NJe9t3fh3ETKPTz0RRhmAsAND-lODEv937fOgnf4gcc,6293
|
|
126
|
+
simo/users/api.py,sha256=9DDVAJ-cpWdkcQCKzQK-E_zV1LFP_K_HGwVRD-FM_Ko,9060
|
|
127
|
+
simo/users/auth_backends.py,sha256=RWoDgfFA32mrS-b0DbbW7_Ve8ZMKp-NqX7Ywg5uaLFI,2487
|
|
127
128
|
simo/users/auto_urls.py,sha256=ee0d6fWABkJY5mQOTC8KhrqDI6d8xZkYZ4ja-gZJ-rw,269
|
|
128
129
|
simo/users/dynamic_settings.py,sha256=sEIsi4yJw3kH46Jq_aOkSuK7QTfQACGUE-lkyBogCaM,570
|
|
129
130
|
simo/users/middleware.py,sha256=lwZQ1koxOEWcRI2PD_EXo3AX8exO-z4R5jOFwfTHRw8,739
|
|
130
|
-
simo/users/models.py,sha256=
|
|
131
|
+
simo/users/models.py,sha256=bqdY8BXHhFjaElXgSoRFN7vHXmwMY9JcPzoZU1GNoXg,14948
|
|
131
132
|
simo/users/permissions.py,sha256=IwtYS8yQdupWbYKR9VimSRDV3qCJ2jXP57Lyjpb2EQM,242
|
|
132
|
-
simo/users/serializers.py,sha256=
|
|
133
|
+
simo/users/serializers.py,sha256=K0b5snRTn1ZSbG0wWu9P_0GE8MYYxmNxfAzJlwl00HI,2001
|
|
133
134
|
simo/users/sso_urls.py,sha256=pcb_GhYHRtmairxJhMXE1bdcTma0BcYfKU3nCRtHQMQ,244
|
|
134
135
|
simo/users/sso_views.py,sha256=-XI67TvQ7SN3goU4OuAHyn84u_1vtusvpn7Pu0K97zo,4648
|
|
135
136
|
simo/users/tasks.py,sha256=tZPr4w0kgElHImbKuDZn0ixXR3xf_uU-RNpGbdpA5-c,796
|
|
@@ -151,9 +152,10 @@ simo/users/migrations/0013_remove_user_roles.py,sha256=UIau3WxXLM8EpFy16s3rO_Qt6
|
|
|
151
152
|
simo/users/migrations/0014_user_roles.py,sha256=rxbSd655IEQ6IvXqOUTpJL6XsvrKEqjpL7XmewhrEwI,431
|
|
152
153
|
simo/users/migrations/0015_remove_user_at_home.py,sha256=rEpLyrmKLL24Mzm2icrdi0A9DzaNENPBmNsZZeMpGw4,317
|
|
153
154
|
simo/users/migrations/0016_auto_20231005_1050.py,sha256=PlvqGjJFk0oyd7zd1ZL4urbRj0cMBPICkcQtU04O64Y,719
|
|
155
|
+
simo/users/migrations/0017_auto_20231221_0735.py,sha256=u7o6-f4WB_MiMVNayl4ERBo3oQxgGvMMIMtClo7vPQQ,506
|
|
154
156
|
simo/users/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
155
|
-
simo-1.6.
|
|
156
|
-
simo-1.6.
|
|
157
|
-
simo-1.6.
|
|
158
|
-
simo-1.6.
|
|
159
|
-
simo-1.6.
|
|
157
|
+
simo-1.6.4.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
|
|
158
|
+
simo-1.6.4.dist-info/METADATA,sha256=YnV8O01KrQ47L3AkjpXVvddzEVkMaBAfaq7tRwyboh4,1748
|
|
159
|
+
simo-1.6.4.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
160
|
+
simo-1.6.4.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
|
|
161
|
+
simo-1.6.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|