simo 2.1.0__py3-none-any.whl → 2.1.2__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 (53) hide show
  1. simo/__pycache__/asgi.cpython-38.pyc +0 -0
  2. simo/asgi.py +1 -1
  3. simo/core/__pycache__/admin.cpython-38.pyc +0 -0
  4. simo/core/__pycache__/api.cpython-38.pyc +0 -0
  5. simo/core/__pycache__/apps.cpython-38.pyc +0 -0
  6. simo/core/__pycache__/auto_urls.cpython-38.pyc +0 -0
  7. simo/core/__pycache__/dynamic_settings.cpython-38.pyc +0 -0
  8. simo/core/__pycache__/forms.cpython-38.pyc +0 -0
  9. simo/core/__pycache__/models.cpython-38.pyc +0 -0
  10. simo/core/__pycache__/tasks.cpython-38.pyc +0 -0
  11. simo/core/__pycache__/views.cpython-38.pyc +0 -0
  12. simo/core/admin.py +0 -18
  13. simo/core/api.py +1 -0
  14. simo/core/apps.py +4 -1
  15. simo/core/auto_urls.py +2 -3
  16. simo/core/dynamic_settings.py +0 -8
  17. simo/core/forms.py +1 -98
  18. simo/core/migrations/0038_remove_instance_cover_image_and_more.py +30 -0
  19. simo/core/migrations/__pycache__/0038_remove_instance_cover_image_and_more.cpython-38.pyc +0 -0
  20. simo/core/models.py +2 -7
  21. simo/core/tasks.py +82 -49
  22. simo/core/templates/admin/user_tools.html +0 -3
  23. simo/core/views.py +2 -85
  24. simo/fleet/__pycache__/controllers.cpython-38.pyc +0 -0
  25. simo/fleet/controllers.py +1 -1
  26. simo/fleet/migrations/0037_alter_colonelpin_options_alter_colonelpin_no_and_more.py +27 -0
  27. simo/fleet/migrations/__pycache__/0037_alter_colonelpin_options_alter_colonelpin_no_and_more.cpython-38.pyc +0 -0
  28. simo/generic/__pycache__/controllers.cpython-38.pyc +0 -0
  29. simo/generic/__pycache__/forms.cpython-38.pyc +0 -0
  30. simo/generic/controllers.py +2 -2
  31. simo/generic/forms.py +0 -3
  32. simo/generic/templates/admin/controller_widgets/weather_forecast.html +1 -1
  33. simo/management/__init__.py +0 -0
  34. simo/management/__pycache__/__init__.cpython-38.pyc +0 -0
  35. simo/management/__pycache__/on_http_start.cpython-38.pyc +0 -0
  36. simo/{_hub_template → management/_hub_template}/hub/nginx.conf +2 -2
  37. simo/{auto_update.py → management/auto_update.py} +3 -0
  38. simo/{cli.py → management/copy_template.py} +3 -16
  39. simo/management/install.py +258 -0
  40. simo/{on_http_start.py → management/on_http_start.py} +22 -2
  41. {simo-2.1.0.dist-info → simo-2.1.2.dist-info}/METADATA +1 -1
  42. {simo-2.1.0.dist-info → simo-2.1.2.dist-info}/RECORD +52 -44
  43. simo-2.1.2.dist-info/entry_points.txt +2 -0
  44. simo/__pycache__/on_http_start.cpython-38.pyc +0 -0
  45. /simo/{_hub_template → management/_hub_template}/hub/asgi.py +0 -0
  46. /simo/{_hub_template → management/_hub_template}/hub/celeryc.py +0 -0
  47. /simo/{_hub_template → management/_hub_template}/hub/manage.py +0 -0
  48. /simo/{_hub_template → management/_hub_template}/hub/settings.py +0 -0
  49. /simo/{_hub_template → management/_hub_template}/hub/supervisor.conf +0 -0
  50. /simo/{_hub_template → management/_hub_template}/hub/urls.py +0 -0
  51. {simo-2.1.0.dist-info → simo-2.1.2.dist-info}/LICENSE.md +0 -0
  52. {simo-2.1.0.dist-info → simo-2.1.2.dist-info}/WHEEL +0 -0
  53. {simo-2.1.0.dist-info → simo-2.1.2.dist-info}/top_level.txt +0 -0
Binary file
simo/asgi.py CHANGED
@@ -21,7 +21,7 @@ for name, app in apps.app_configs.items():
21
21
  if isinstance(item, list) and var_name == 'urlpatterns':
22
22
  urlpatterns.extend(item)
23
23
 
24
- from .on_http_start import *
24
+ from .management.on_http_start import *
25
25
 
26
26
  application = ProtocolTypeRouter({
27
27
  "http": get_asgi_application(),
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
simo/core/admin.py CHANGED
@@ -60,24 +60,6 @@ class IconAdmin(EasyObjectsDeleteMixin, admin.ModelAdmin):
60
60
 
61
61
 
62
62
 
63
-
64
- @admin.register(Instance)
65
- class InstanceAdmin(EasyObjectsDeleteMixin, admin.ModelAdmin):
66
- list_display = 'name', 'timezone', 'uid'
67
- exclude = 'learn_fingerprints_start', 'learn_fingerprints'
68
-
69
-
70
- def has_module_permission(self, request):
71
- return request.user.is_master
72
-
73
- def has_view_permission(self, request, obj=None):
74
- return self.has_module_permission(request)
75
-
76
- def has_change_permission(self, request, obj=None):
77
- return self.has_module_permission(request)
78
-
79
-
80
-
81
63
  @admin.register(Zone)
82
64
  class ZoneAdmin(EasyObjectsDeleteMixin, SortableAdminMixin, admin.ModelAdmin):
83
65
  list_display = 'name', 'instance'
simo/core/api.py CHANGED
@@ -545,6 +545,7 @@ class SettingsViewSet(InstanceMixin, viewsets.GenericViewSet):
545
545
  main_alarm_group_id = main_alarm_group.id
546
546
 
547
547
  return RESTResponse({
548
+ 'hub_uid': dynamic_settings['core__hub_uid'],
548
549
  'instance_name': self.instance.name,
549
550
  'instance_uid': self.instance.uid,
550
551
  'timezone': self.instance.timezone,
simo/core/apps.py CHANGED
@@ -1,10 +1,13 @@
1
1
  from django.apps import AppConfig
2
2
 
3
3
 
4
+
4
5
  class SIMOCoreAppConfig(AppConfig):
5
6
  name = 'simo.core'
6
7
 
7
8
  def ready(self):
8
9
  from actstream import registry
9
10
  registry.register(self.get_model('Component'))
10
- registry.register(self.get_model('Gateway'))
11
+ registry.register(self.get_model('Gateway'))
12
+
13
+
simo/core/auto_urls.py CHANGED
@@ -1,9 +1,9 @@
1
1
  from django.urls import path
2
2
  from .views import (
3
- get_timestamp, setup_wizard, update, restart, reboot, set_instance
3
+ get_timestamp, update, restart, reboot, set_instance
4
4
  )
5
5
  from .autocomplete_views import (
6
- IconModelAutocomplete, #IconSlugAutocomplete,
6
+ IconModelAutocomplete,
7
7
  CategoryAutocomplete, ZoneAutocomplete,
8
8
  ComponentAutocomplete,
9
9
  )
@@ -31,7 +31,6 @@ urlpatterns = [
31
31
  ComponentAutocomplete.as_view(), name='autocomplete-component'
32
32
  ),
33
33
  path('set-instance/<slug:instance_slug>/', set_instance, name='set-instance'),
34
- path('setup/', setup_wizard, name='setup-wizard'),
35
34
  path('update/', update, name='update'),
36
35
  path('restart/', restart, name='restart'),
37
36
  path('reboot/', reboot, name='reboot')
@@ -43,14 +43,6 @@ class RemoteConnectionVersion(IntegerPreference):
43
43
  "when hub get's synced up to the simo.io."
44
44
 
45
45
 
46
- @global_preferences_registry.register
47
- class UnitsOfMeasure(ChoicePreference):
48
- section = core
49
- name = 'units_of_measure'
50
- choices = (('metric', "Metric"), ('imperial', "Imperial"))
51
- default = 'metric'
52
- required = True
53
-
54
46
 
55
47
  @global_preferences_registry.register
56
48
  class LatestHubOSVersionAvailable(StringPreference):
simo/core/forms.py CHANGED
@@ -1,28 +1,19 @@
1
- import os
2
1
  import traceback
3
- import requests
4
2
  from dal import forward
5
- from django import forms
6
3
  from django.contrib.admin.forms import AdminAuthenticationForm as OrgAdminAuthenticationForm
7
4
  from django.db import models
8
5
  from django import forms
9
6
  from django.forms import formset_factory
10
- from django.conf import settings
11
7
  from django.urls.base import get_script_prefix
12
8
  from django.utils.safestring import mark_safe
13
9
  from django.utils.translation import gettext_lazy as _
14
10
  from django.contrib.contenttypes.models import ContentType
15
11
  from actstream import action
16
- from timezone_utils.choices import ALL_TIMEZONES_CHOICES
17
12
  from dal import autocomplete
18
13
  from .models import (
19
14
  Icon, Category, Gateway, Component
20
15
  )
21
- from .widgets import LocationWidget
22
- from simo.conf import dynamic_settings
23
- from .widgets import SVGFileWidget, PythonCode, LogOutputWidget
24
- from .widgets import ImageWidget
25
- from .utils.helpers import get_random_string
16
+ from .widgets import SVGFileWidget, LogOutputWidget
26
17
  from .utils.formsets import FormsetField
27
18
  from .utils.validators import validate_slaves
28
19
 
@@ -35,94 +26,6 @@ class HiddenField(forms.CharField):
35
26
  super().__init__(widget=forms.HiddenInput())
36
27
 
37
28
 
38
- class HubConfigForm(forms.Form):
39
- name = forms.CharField(
40
- label=_("Hub Name"), required=True,
41
- widget=forms.TextInput(attrs={'placeholder': "Home Sweet Home"})
42
- )
43
- uid = forms.CharField(
44
- label=_('Unique Identifier (UID)'), required=False,
45
- widget=forms.TextInput(attrs={'placeholder': "Df5Hd8v1"}),
46
- help_text="Leave blank if this is a new instance."
47
- )
48
- time_zone = forms.ChoiceField(
49
- label=_("Time zone"), required=True,
50
- choices=ALL_TIMEZONES_CHOICES
51
- )
52
- units_of_measure = forms.ChoiceField(
53
- label=_("Units of Measure"), required=True,
54
- choices=(('metric', 'Metric'), ('imperial', 'Imperial'))
55
- )
56
- cover_image = forms.FileField(
57
- label=_("Cover image"), required=True, widget=ImageWidget
58
- )
59
-
60
- def __init__(self, *args, **kwargs):
61
- self.user = kwargs.pop('user')
62
- super().__init__(*args, **kwargs)
63
-
64
- def clean(self):
65
- cleaned_data = super().clean()
66
- post_data = cleaned_data.copy()
67
- post_data.pop('cover_image')
68
- if not dynamic_settings['core__hub_secret']:
69
- dynamic_settings['core__hub_secret'] = get_random_string(20)
70
- post_data['secret'] = dynamic_settings['core__hub_secret']
71
- post_data['email'] = self.user.email
72
- try:
73
- resp = requests.post(
74
- 'https://simo.io/hubs/sync-initial-config/', json=post_data,
75
- )
76
- except Exception as e:
77
- raise forms.ValidationError(
78
- "Connection error. "
79
- "Make sure your hub can reach https://simo.io and try again."
80
- )
81
-
82
- if resp.status_code == 400:
83
- resp_json = resp.json()
84
- resp_json.pop('status', None)
85
- for field_name, msg in resp_json.items():
86
- self.add_error(field_name, msg)
87
- elif resp.status_code == 200:
88
- cleaned_data['uid'] = resp.json()['uid']
89
- else:
90
- raise forms.ValidationError(
91
- "Bad response from https://simo.io. Please try again. "
92
- )
93
- return cleaned_data
94
-
95
-
96
- class CoordinatesForm(forms.Form):
97
- location = forms.CharField(
98
- label=_("Where is your hub located?"),
99
- widget=LocationWidget(based_fields=[])
100
- )
101
- share_location = forms.BooleanField(
102
- label="Share exact location with SIMO.io for "
103
- "better accuracy of location related services.",
104
- required=False
105
- )
106
-
107
- def __init__(self, *args, **kwargs):
108
- super().__init__(*args, **kwargs)
109
- if not self.initial['location']:
110
- self.fields['location'].widget = LocationWidget(
111
- based_fields=[], zoom=2
112
- )
113
-
114
-
115
-
116
-
117
- class TermsAndConditionsForm(forms.Form):
118
- accept = forms.BooleanField(required=False)
119
-
120
- def clean_accept(self):
121
- if not self.cleaned_data['accept']:
122
- raise forms.ValidationError(_("You must accept SIMO.io Terms & Conditions if you want to continue."))
123
- return self.cleaned_data['accept']
124
-
125
-
126
29
  class AdminAuthenticationForm(OrgAdminAuthenticationForm):
127
30
 
128
31
  def confirm_login_allowed(self, user):
@@ -0,0 +1,30 @@
1
+ # Generated by Django 4.2.10 on 2024-06-12 08:14
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('core', '0037_auto_20240606_1057'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.RemoveField(
14
+ model_name='instance',
15
+ name='cover_image',
16
+ ),
17
+ migrations.RemoveField(
18
+ model_name='instance',
19
+ name='cover_image_synced',
20
+ ),
21
+ migrations.RemoveField(
22
+ model_name='instance',
23
+ name='secret_key',
24
+ ),
25
+ migrations.AlterField(
26
+ model_name='instance',
27
+ name='timezone',
28
+ 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),
29
+ ),
30
+ ]
simo/core/models.py CHANGED
@@ -16,6 +16,7 @@ from actstream import action
16
16
  from simo.core.utils.mixins import SimoAdminMixin
17
17
  from simo.core.storage import OverwriteStorage
18
18
  from simo.core.utils.validators import validate_svg
19
+ from simo.core.utils.helpers import get_random_string
19
20
  from simo.users.models import User
20
21
  from .managers import ZonesManager, CategoriesManager, ComponentsManager
21
22
  from .events import GatewayObjectCommand, OnChangeMixin
@@ -65,16 +66,10 @@ class Instance(models.Model, SimoAdminMixin):
65
66
  # or something of that kind.
66
67
  # Usually, there will be only one.
67
68
  uid = models.CharField(
68
- max_length=50, unique=True,
69
- help_text="Issued by SIMO.io"
69
+ max_length=50, unique=True, help_text="Issued by SIMO.io"
70
70
  )
71
71
  name = models.CharField(max_length=100, db_index=True, unique=True)
72
72
  slug = models.CharField(max_length=100, db_index=True, unique=True)
73
- cover_image = models.ImageField(
74
- name='cover_image', upload_to='hub_covers', null=True, blank=True
75
- )
76
- cover_image_synced = models.BooleanField(default=False)
77
- secret_key = models.CharField(max_length=100, blank=True)
78
73
  date_created = models.DateTimeField(auto_now_add=True)
79
74
  location = PlainLocationField(null=True, blank=True, zoom=7)
80
75
  timezone = models.CharField(
simo/core/tasks.py CHANGED
@@ -2,20 +2,23 @@ import time
2
2
  import os
3
3
  import io
4
4
  import json
5
- import base64
6
5
  import datetime
7
6
  import requests
8
7
  import subprocess
9
8
  import threading
10
9
  import pkg_resources
10
+ import sys
11
+ import traceback
11
12
  from django.db.models import Q
12
- from django.db import connection
13
+ from django.db import connection, transaction
13
14
  from django.template.loader import render_to_string
14
15
  from celeryc import celery_app
15
16
  from django.utils import timezone
17
+ from actstream.models import Action
16
18
  from easy_thumbnails.files import get_thumbnailer
17
19
  from simo.conf import dynamic_settings
18
20
  from simo.core.utils.helpers import get_self_ip
21
+ from simo.users.models import PermissionsRole, InstanceUser
19
22
  from .models import Instance, Component, ComponentHistory, HistoryAggregate
20
23
 
21
24
 
@@ -99,19 +102,15 @@ def save_config(data):
99
102
  def sync_with_remote():
100
103
  from simo.users.models import User
101
104
 
102
- instances = Instance.objects.all()
103
- if not instances:
104
- # No initial configuration yet
105
- return
106
-
107
105
  report_data = {
108
106
  'simo_version': pkg_resources.get_distribution('simo').version,
109
107
  'local_http': 'https://%s' % get_self_ip(),
110
108
  'hub_uid': dynamic_settings['core__hub_uid'],
111
109
  'hub_secret': dynamic_settings['core__hub_secret'],
110
+ 'remote_conn_version': dynamic_settings['core__remote_conn_version'],
112
111
  'instances': []
113
112
  }
114
- for instance in instances:
113
+ for instance in Instance.objects.all():
115
114
  instance_data = {
116
115
  'uid': instance.uid,
117
116
  'name': instance.name,
@@ -131,10 +130,14 @@ def sync_with_remote():
131
130
  user_role = user.get_role(instance)
132
131
  if user_role and user_role.is_superuser:
133
132
  is_superuser = True
133
+ is_owner = False
134
+ if user_role and user_role.is_owner:
135
+ is_owner = True
134
136
  instance_data['users'].append({
135
137
  'email': user.email,
136
138
  'is_hub_master': user.is_master,
137
139
  'is_superuser': is_superuser,
140
+ 'is_owner': is_owner,
138
141
  'device_token': user.primary_device_token
139
142
  })
140
143
 
@@ -144,15 +147,6 @@ def sync_with_remote():
144
147
  if last_event:
145
148
  instance_data['last_event'] = last_event.date.timestamp()
146
149
 
147
- if instance.cover_image and not instance.cover_image_synced:
148
- thumbnailer = get_thumbnailer(instance.cover_image.path)
149
- cover_imb_path = thumbnailer.get_thumbnail(
150
- {'size': (880, 490), 'crop': True}
151
- ).path
152
- with open(cover_imb_path, 'rb') as img:
153
- instance_data['cover_image'] = base64.b64encode(
154
- img.read()
155
- ).decode()
156
150
  report_data['instances'].append(instance_data)
157
151
 
158
152
  print("Sync UP with remote: ", json.dumps(report_data))
@@ -169,11 +163,7 @@ def sync_with_remote():
169
163
  if 'hub_uid' in r_json:
170
164
  dynamic_settings['core__hub_uid'] = r_json['hub_uid']
171
165
 
172
- for instance in instances:
173
- instance.cover_image_synced = True
174
- instance.save()
175
-
176
- dynamic_settings['core__remote_http'] = r_json.get('hub_remote_http')
166
+ dynamic_settings['core__remote_http'] = r_json.get('hub_remote_http', '')
177
167
  if 'new_secret' in r_json:
178
168
  dynamic_settings['core__hub_secret'] = r_json['new_secret']
179
169
 
@@ -182,9 +172,14 @@ def sync_with_remote():
182
172
  dynamic_settings['core__remote_conn_version'] = r_json['remote_conn_version']
183
173
 
184
174
  for data in r_json['instances']:
185
- instance = Instance.objects.get(uid=data['uid'])
175
+ users_data = data.pop('users', {})
176
+ instance_uid = data.pop('uid')
177
+ weather_forecast = data.pop('weather_forecast', None)
178
+ instance, new_instance = Instance.objects.update_or_create(
179
+ uid=instance_uid, defaults=data
180
+ )
186
181
 
187
- if 'weather_forecast' in data:
182
+ if weather_forecast:
188
183
  from simo.generic.controllers import WeatherForecast
189
184
  weather_component = Component.objects.filter(
190
185
  zone__instance=instance,
@@ -192,27 +187,55 @@ def sync_with_remote():
192
187
  ).first()
193
188
  if weather_component:
194
189
  weather_component.track_history = False
195
- weather_component.controller.set(data['weather_forecast'])
196
-
197
- instance.save()
198
-
199
- for user_data in r_json['users']:
200
- try:
201
- user = User.objects.get(email=user_data['email'])
202
- except User.DoesNotExist:
203
- continue
204
- user.name = user_data['name']
205
- if user_data.get('avatar_url') \
206
- and user.avatar_url != user_data.get('avatar_url'):
207
- user.avatar_url = user_data.get('avatar_url')
208
- resp = requests.get(user.avatar_url)
209
- user.avatar.save(
210
- os.path.basename(user.avatar_url), io.BytesIO(resp.content)
211
- )
212
- user.avatar_url = user_data.get('avatar_url')
213
- user.avatar_last_change = timezone.now()
214
- user.ssh_key = user_data.get('ssh_key')
215
- user.save()
190
+ weather_component.controller.set(weather_forecast)
191
+
192
+
193
+ for email, options in users_data.items():
194
+ with transaction.atomic():
195
+ if new_instance:
196
+ # Create users for new instance!
197
+ user, new_user = User.objects.update_or_create(
198
+ email=email, defaults={
199
+ 'name': options.get('name'),
200
+ 'is_master': options.get('is_hub_master', False),
201
+ 'ssh_key': options.get('ssh_key')
202
+ })
203
+ role = None
204
+ if options.get('is_superuser'):
205
+ role = PermissionsRole.objects.filter(
206
+ instance=new_instance, is_superuser=True
207
+ ).first()
208
+ elif options.get('is_owner'):
209
+ role = PermissionsRole.objects.filter(
210
+ instance=new_instance, is_owner=True
211
+ ).first()
212
+ InstanceUser.objects.update_or_create(
213
+ user=user, instance=new_instance, defaults={
214
+ 'is_active': True, 'role': role
215
+ }
216
+ )
217
+ else:
218
+ user = User.objects.filter(email=email).first()
219
+
220
+ if not user:
221
+ continue
222
+
223
+ if user.name != options.get('name'):
224
+ user.name = options['name']
225
+ user.save()
226
+ if user.ssh_key != options.get('ssh_key'):
227
+ user.ssh_key = options['ssh_key']
228
+ user.save()
229
+
230
+ avatar_url = options.get('avatar_url')
231
+ if avatar_url and user.avatar_url != avatar_url:
232
+ resp = requests.get(avatar_url)
233
+ user.avatar.save(
234
+ os.path.basename(avatar_url), io.BytesIO(resp.content)
235
+ )
236
+ user.avatar_url = avatar_url
237
+ user.avatar_last_change = timezone.now()
238
+ user.save()
216
239
 
217
240
 
218
241
  @celery_app.task
@@ -223,7 +246,10 @@ def watch_timers():
223
246
  component.meta['timer_to'] = 0
224
247
  component.meta['timer_start'] = 0
225
248
  component.save()
226
- component.controller._on_timer_end()
249
+ try:
250
+ component.controller._on_timer_end()
251
+ except Exception as e:
252
+ print(traceback.format_exc(), file=sys.stderr)
227
253
 
228
254
 
229
255
  @celery_app.task
@@ -232,8 +258,15 @@ def clear_history():
232
258
  old_times = timezone.now() - datetime.timedelta(
233
259
  days=instance.history_days
234
260
  )
235
- ComponentHistory.objects.filter(date__lt=old_times).delete()
236
- HistoryAggregate.objects.filter(start__lt=old_times).delete()
261
+ ComponentHistory.objects.filter(
262
+ component__zone__instance=instance, date__lt=old_times
263
+ ).delete()
264
+ HistoryAggregate.objects.filter(
265
+ component__zone__instance=instance, start__lt=old_times
266
+ ).delete()
267
+ Action.objects.filter(
268
+ data__instance_id=instance.id, timestamp__lt=old_times
269
+ )
237
270
 
238
271
 
239
272
  @celery_app.task
@@ -300,6 +333,7 @@ def update_latest_version_available():
300
333
  return
301
334
  latest = list(resp.json()['releases'].keys())[-1]
302
335
  dynamic_settings['core__latest_version_available'] = latest
336
+ print("Got the latest version available!")
303
337
 
304
338
 
305
339
  @celery_app.task
@@ -358,7 +392,6 @@ def low_battery_notifications():
358
392
  )
359
393
 
360
394
 
361
-
362
395
  @celery_app.on_after_finalize.connect
363
396
  def setup_periodic_tasks(sender, **kwargs):
364
397
  sender.add_periodic_task(1, watch_timers.s())
@@ -16,9 +16,6 @@
16
16
  <i class="fas fa-sort-down"></i>
17
17
  </div>
18
18
  <div class="dropdown-content" style="right: 110px">
19
- <a href="{% url 'setup-wizard' %}">
20
- <i class="fas fa-magic"></i> Core Setup Wizard
21
- </a>
22
19
  <a href="{% url 'update' %}" title="Update hub" class="update_link">
23
20
  <i class="fas fa-angle-double-up"></i> Update
24
21
  </a>