simo 2.0.42__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 (124) hide show
  1. simo/__pycache__/asgi.cpython-38.pyc +0 -0
  2. simo/__pycache__/settings.cpython-38.pyc +0 -0
  3. simo/__pycache__/wsgi.cpython-38.pyc +0 -0
  4. simo/asgi.py +1 -1
  5. simo/core/__init__.py +1 -0
  6. simo/core/__pycache__/__init__.cpython-38.pyc +0 -0
  7. simo/core/__pycache__/admin.cpython-38.pyc +0 -0
  8. simo/core/__pycache__/api.cpython-38.pyc +0 -0
  9. simo/core/__pycache__/api_meta.cpython-38.pyc +0 -0
  10. simo/core/__pycache__/app_widgets.cpython-38.pyc +0 -0
  11. simo/core/__pycache__/apps.cpython-38.pyc +0 -0
  12. simo/core/__pycache__/auto_urls.cpython-38.pyc +0 -0
  13. simo/core/__pycache__/base_types.cpython-38.pyc +0 -0
  14. simo/core/__pycache__/controllers.cpython-38.pyc +0 -0
  15. simo/core/__pycache__/dynamic_settings.cpython-38.pyc +0 -0
  16. simo/core/__pycache__/form_fields.cpython-38.pyc +0 -0
  17. simo/core/__pycache__/forms.cpython-38.pyc +0 -0
  18. simo/core/__pycache__/gateways.cpython-38.pyc +0 -0
  19. simo/core/__pycache__/managers.cpython-38.pyc +0 -0
  20. simo/core/__pycache__/models.cpython-38.pyc +0 -0
  21. simo/core/__pycache__/permissions.cpython-38.pyc +0 -0
  22. simo/core/__pycache__/serializers.cpython-38.pyc +0 -0
  23. simo/core/__pycache__/signal_receivers.cpython-38.pyc +0 -0
  24. simo/core/__pycache__/tasks.cpython-38.pyc +0 -0
  25. simo/core/__pycache__/views.cpython-38.pyc +0 -0
  26. simo/core/admin.py +26 -26
  27. simo/core/api.py +22 -2
  28. simo/core/api_meta.py +23 -13
  29. simo/core/app_widgets.py +6 -0
  30. simo/core/apps.py +13 -0
  31. simo/core/auto_urls.py +2 -3
  32. simo/core/base_types.py +1 -0
  33. simo/core/controllers.py +57 -0
  34. simo/core/dynamic_settings.py +0 -8
  35. simo/core/form_fields.py +93 -0
  36. simo/core/forms.py +16 -101
  37. simo/core/gateways.py +1 -1
  38. simo/core/managers.py +14 -1
  39. simo/core/migrations/0037_auto_20240606_1057.py +33 -0
  40. simo/core/migrations/0038_remove_instance_cover_image_and_more.py +30 -0
  41. simo/core/migrations/__pycache__/0037_auto_20240606_1057.cpython-38.pyc +0 -0
  42. simo/core/migrations/__pycache__/0038_remove_instance_cover_image_and_more.cpython-38.pyc +0 -0
  43. simo/core/models.py +30 -16
  44. simo/core/permissions.py +6 -3
  45. simo/core/serializers.py +77 -5
  46. simo/core/signal_receivers.py +25 -0
  47. simo/core/static/admin/css/simo.css +14 -0
  48. simo/core/tasks.py +82 -49
  49. simo/core/templates/admin/controller_widgets/button.html +8 -0
  50. simo/core/templates/admin/core/component_change_form.html +97 -0
  51. simo/core/templates/admin/formset_widget.html +88 -118
  52. simo/core/templates/admin/formset_widget_old.html +122 -0
  53. simo/core/templates/admin/user_tools.html +0 -3
  54. simo/core/templates/admin/wizard/wizard_add.html +16 -9
  55. simo/core/utils/__pycache__/admin.cpython-38.pyc +0 -0
  56. simo/core/utils/__pycache__/cache.cpython-38.pyc +0 -0
  57. simo/core/utils/__pycache__/formsets.cpython-38.pyc +0 -0
  58. simo/core/utils/admin.py +11 -0
  59. simo/core/utils/cache.py +15 -0
  60. simo/core/utils/formsets.py +11 -18
  61. simo/core/views.py +2 -85
  62. simo/fleet/__pycache__/auto_urls.cpython-38.pyc +0 -0
  63. simo/fleet/__pycache__/controllers.cpython-38.pyc +0 -0
  64. simo/fleet/__pycache__/forms.cpython-38.pyc +0 -0
  65. simo/fleet/__pycache__/gateways.cpython-38.pyc +0 -0
  66. simo/fleet/__pycache__/models.cpython-38.pyc +0 -0
  67. simo/fleet/__pycache__/socket_consumers.cpython-38.pyc +0 -0
  68. simo/fleet/__pycache__/utils.cpython-38.pyc +0 -0
  69. simo/fleet/__pycache__/views.cpython-38.pyc +0 -0
  70. simo/fleet/auto_urls.py +7 -1
  71. simo/fleet/controllers.py +194 -31
  72. simo/fleet/forms.py +223 -87
  73. simo/fleet/gateways.py +53 -2
  74. simo/fleet/migrations/0036_auto_20240605_0702.py +68 -0
  75. simo/fleet/migrations/0037_alter_colonelpin_options_alter_colonelpin_no_and_more.py +27 -0
  76. simo/fleet/migrations/__pycache__/0036_auto_20240605_0702.cpython-38.pyc +0 -0
  77. simo/fleet/migrations/__pycache__/0037_alter_colonelpin_options_alter_colonelpin_no_and_more.cpython-38.pyc +0 -0
  78. simo/fleet/models.py +35 -6
  79. simo/fleet/socket_consumers.py +1 -1
  80. simo/fleet/templates/fleet/controllers_info/button.md +16 -0
  81. simo/fleet/utils.py +31 -1
  82. simo/fleet/views.py +45 -0
  83. simo/generic/__pycache__/controllers.cpython-38.pyc +0 -0
  84. simo/generic/__pycache__/forms.cpython-38.pyc +0 -0
  85. simo/generic/__pycache__/gateways.cpython-38.pyc +0 -0
  86. simo/generic/controllers.py +61 -16
  87. simo/generic/forms.py +0 -3
  88. simo/generic/gateways.py +2 -0
  89. simo/generic/templates/admin/controller_widgets/blinds.html +2 -1
  90. simo/generic/templates/admin/controller_widgets/weather_forecast.html +1 -1
  91. simo/generic/templates/generic/controllers_info/dummy.md +3 -0
  92. simo/generic/templates/generic/controllers_info/stateselect.md +2 -0
  93. simo/management/__init__.py +0 -0
  94. simo/management/__pycache__/__init__.cpython-38.pyc +0 -0
  95. simo/management/__pycache__/on_http_start.cpython-38.pyc +0 -0
  96. simo/{_hub_template → management/_hub_template}/hub/nginx.conf +2 -2
  97. simo/{auto_update.py → management/auto_update.py} +3 -0
  98. simo/{cli.py → management/copy_template.py} +3 -16
  99. simo/management/install.py +258 -0
  100. simo/{on_http_start.py → management/on_http_start.py} +22 -2
  101. simo/settings.py +20 -4
  102. simo/users/__init__.py +1 -0
  103. simo/users/__pycache__/__init__.cpython-38.pyc +0 -0
  104. simo/users/__pycache__/admin.cpython-38.pyc +0 -0
  105. simo/users/__pycache__/apps.cpython-38.pyc +0 -0
  106. simo/users/__pycache__/models.cpython-38.pyc +0 -0
  107. simo/users/apps.py +9 -0
  108. simo/users/migrations/__pycache__/0029_alter_instanceuser_options_instanceuser_order.cpython-38.pyc +0 -0
  109. simo/users/migrations/__pycache__/0030_alter_instanceuser_options_remove_instanceuser_order.cpython-38.pyc +0 -0
  110. simo/users/models.py +16 -3
  111. {simo-2.0.42.dist-info → simo-2.1.2.dist-info}/METADATA +5 -3
  112. {simo-2.0.42.dist-info → simo-2.1.2.dist-info}/RECORD +122 -95
  113. simo-2.1.2.dist-info/entry_points.txt +2 -0
  114. simo/__pycache__/on_http_start.cpython-38.pyc +0 -0
  115. simo/wsgi.py +0 -7
  116. /simo/{_hub_template → management/_hub_template}/hub/asgi.py +0 -0
  117. /simo/{_hub_template → management/_hub_template}/hub/celeryc.py +0 -0
  118. /simo/{_hub_template → management/_hub_template}/hub/manage.py +0 -0
  119. /simo/{_hub_template → management/_hub_template}/hub/settings.py +0 -0
  120. /simo/{_hub_template → management/_hub_template}/hub/supervisor.conf +0 -0
  121. /simo/{_hub_template → management/_hub_template}/hub/urls.py +0 -0
  122. {simo-2.0.42.dist-info → simo-2.1.2.dist-info}/LICENSE.md +0 -0
  123. {simo-2.0.42.dist-info → simo-2.1.2.dist-info}/WHEEL +0 -0
  124. {simo-2.0.42.dist-info → simo-2.1.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,122 @@
1
+ {% load i18n admin_urls static admin_modify %}
2
+ <style>
3
+ .formset-table th, .formset-table th .label{
4
+ font-weight: normal;
5
+ color: var(--body-quiet-color);
6
+ }
7
+ .formset-table .label.required{
8
+ font-weight: bold;
9
+ }
10
+ form .aligned .formset-table ul{
11
+ margin-left:0;
12
+ }
13
+ .errors .formset-table input, .errors .formset-table select,
14
+ .errors .formset-table textarea{
15
+ border: 1px solid var(--border-color);
16
+ }
17
+ .errors .formset-table .select2-selection{
18
+ border-color: #aaa;
19
+ }
20
+ .formset-table td.errors input, .formset-table td.errors select,
21
+ .formset-table td.errors textarea{
22
+ border: 1px solid var(--error-fg);
23
+ }
24
+ .formset-table td.errors .select2-selection{
25
+ border-color: var(--error-fg);
26
+ }
27
+ .formset-table td.drag {
28
+ cursor: pointer;
29
+ background-image: url(/static/adminsortable2/icons/drag.png);
30
+ background-repeat: repeat;
31
+ width: 20px;
32
+ }
33
+ .formset-table .inline-deletelink{
34
+ float: left
35
+ }
36
+ </style>
37
+
38
+
39
+ <div class="inline-group sortable" id="{{ formset.prefix }}-group">
40
+ <div class="tabular inline-related">
41
+ {{ formset.management_form }}
42
+ <fieldset class="module">
43
+ {{ formset.non_form_errors }}
44
+ <table class="formset-table">
45
+ <thead><tr>
46
+ <th>{% trans "Sort" %}</th>
47
+ {% for field in empty_form %}
48
+ {% if not field.is_hidden and not field.name == 'DELETE' %}
49
+ <th{% if field.required %} class="required"{% endif %}>{{ field.label|capfirst }}
50
+ {% if field.help_text %}&nbsp;<img src="{% static "admin/img/icon-unknown.svg" %}" class="help help-tooltip" width="10" height="10" alt="({{ field.help_text|striptags }})" title="{{ field.help_text|striptags }}" />{% endif %}
51
+ </th>
52
+ {% endif %}
53
+ {% endfor %}
54
+ {% if formset.can_delete %}<th>{% trans "Delete?" %}</th>{% endif %}
55
+ </tr></thead>
56
+
57
+ <tbody>
58
+ {% for form in formset %}
59
+ {% if form.non_field_errors %}
60
+ <tr><td colspan="{{ total_org_forms }}">{{ form.non_field_errors }}</td></tr>
61
+ {% endif %}
62
+
63
+ <tr class="form-row has_original" id="{{ formset.prefix }}-{{ forloop.counter0 }}">
64
+ <td class="drag">&nbsp;</td>
65
+ <td class="original hidden">
66
+ {% for field in form %}
67
+ {% if field.is_hidden %} {{ field }} {% endif %}
68
+ {% endfor %}
69
+ </td>
70
+
71
+ {% for field in form %}
72
+ {% if not field.is_hidden and not field.name == 'DELETE' %}
73
+ <td{% if field.name %} class="field-{{ field.name }}"{% endif %}>
74
+ {{ field }}
75
+ {{ field.errors.as_ul }}
76
+ </td>
77
+ {% endif %}
78
+ {% endfor %}
79
+
80
+ {% if formset.can_delete %}
81
+ <td class="delete">{% if total_org_forms >= forloop.counter0 %}{{ form.DELETE }}{% endif %}</td>
82
+ {% endif %}
83
+ </tr>
84
+
85
+ {% endfor %}
86
+
87
+ <tr class="form-row empty-form" id="{{ formset.prefix }}-empty">
88
+ <td class="drag">&nbsp;</td>
89
+ <td class="original hidden">
90
+ {% for field in empty_form %}
91
+ {% if field.is_hidden %} {{ field }} {% endif %}
92
+ {% endfor %}
93
+ </td>
94
+
95
+ {% for field in empty_form %}
96
+ {% if not field.is_hidden and not field.name == 'DELETE' %}
97
+ <td{% if field.name %} class="field-{{ field.name }}"{% endif %}>
98
+ {{ field }}
99
+ {{ field.errors.as_ul }}
100
+ </td>
101
+ {% endif %}
102
+ {% endfor %}
103
+
104
+ {% if formset.can_delete %}
105
+ <td class="delete"></td>
106
+ {% endif %}
107
+ </tr>
108
+
109
+ </tbody>
110
+ </table>
111
+ </fieldset>
112
+ </div>
113
+ </div>
114
+
115
+ <script type="application/json" class="inline-tabular-config">
116
+ {
117
+ "prefix": "{{ formset.prefix|escapejs }}",
118
+ "addText": "{% filter escapejs %}Add another{% endfilter %}",
119
+ "deleteText": "{% filter escapejs %}{% trans 'Remove' %}{% endfilter %}"
120
+ }
121
+ </script>
122
+ <div class="default_order_field" default_order_field="ORDER" default_order_direction=""></div>
@@ -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>
@@ -1,5 +1,5 @@
1
1
  {% extends "admin/base_site.html" %}
2
- {% load i18n admin_urls static admin_modify %}
2
+ {% load i18n admin_urls static admin_modify markdownify %}
3
3
 
4
4
  {% block extrahead %}{{ block.super }}
5
5
  <script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
@@ -49,18 +49,25 @@
49
49
  <h3 style="margin-bottom: 20px; text-align: center">Step {{ current_step }} of {{ total_steps }}</h3>
50
50
 
51
51
  <fieldset class="module aligned">
52
- {% if selected_gateway %}
53
- <div class="form-row ">
54
- <label class="required"><label for="id_gateway">Gateway:</label></label>
55
- <div class="readonly" style="font-weight:bold;">{{ selected_gateway }}</div>
52
+ {% if selected_gateway or selected_type %}
53
+ <div class="form-row">
54
+ {% if selected_gateway %}
55
+ Gateway: <strong>{{ selected_gateway }}</strong>
56
+ {% endif %}
57
+ {% if selected_type %}
58
+ | Base type: <strong>{{ selected_type }}</strong>
59
+ {% endif %}
56
60
  </div>
57
61
  {% endif %}
58
- {% if selected_type %}
59
- <div class="form-row ">
60
- <label class="required"><label for="id_base_type">Base type:</label></label>
61
- <div class="readonly" style="font-weight:bold;">{{ selected_type }}</div>
62
+
63
+ {% if info %}
64
+ <div class="form-row">
65
+ <div class="markdownified-info">
66
+ {{ info|markdownify }}
67
+ </div>
62
68
  </div>
63
69
  {% endif %}
70
+
64
71
  {% if error %}
65
72
  <ul class="messagelist">
66
73
  <li class="error">{{ error }}</li>
simo/core/utils/admin.py CHANGED
@@ -1,6 +1,11 @@
1
1
  from django import forms
2
2
  from django.shortcuts import render, redirect
3
3
  from django.contrib.admin.helpers import Fieldset
4
+ from django.db import models, router
5
+ from django.utils.text import capfirst
6
+ from django.urls import NoReverseMatch, reverse
7
+ from django.contrib.admin.utils import NestedObjects, quote
8
+ from django.utils.html import format_html
4
9
 
5
10
 
6
11
  class AdminFormActionForm(forms.Form):
@@ -55,3 +60,9 @@ class FormAction:
55
60
  'fieldset': Fieldset(form, fields=form.fields.keys())
56
61
  }
57
62
  return render(request, 'admin/action_intermediate_form.html', context)
63
+
64
+
65
+ class EasyObjectsDeleteMixin:
66
+
67
+ def get_deleted_objects(self, objs, request):
68
+ return [], [], [], []
@@ -0,0 +1,15 @@
1
+ from django.conf import settings
2
+ from django.core.cache import caches
3
+
4
+
5
+ def get_cached_data(
6
+ key, rebuild_function, cache_time=None, cache_name='default', rebuild=False
7
+ ):
8
+ data = caches[cache_name].get(key, 'NONE!')
9
+ if data == 'NONE!' or rebuild:
10
+ print(f"{cache_name} cache rebuild: {rebuild_function.__name__}()")
11
+ data = rebuild_function()
12
+ if not cache_time:
13
+ cache_time = settings.CACHES[cache_name]['TIMEOUT']
14
+ caches[cache_name].set(key, data, cache_time)
15
+ return data
@@ -1,3 +1,4 @@
1
+ import json
1
2
  from django import forms
2
3
  from django.db import models
3
4
  from django.template.loader import render_to_string
@@ -26,21 +27,12 @@ class FormsetWidget(forms.Widget):
26
27
  use_cached = False
27
28
 
28
29
  class Media:
29
- pass
30
- # No longer works with adminsortable2-2
31
- # css = {
32
- # 'all': ['adminsortable2/css/sortable.css']
33
- # }
30
+ css = {
31
+ 'all': ['adminsortable2/css/sortable.css']
32
+ }
34
33
  js = (
35
34
  'admin/js/inlines.js',
36
- # 'adminsortable2/js/plugins/admincompat.js',
37
- # 'adminsortable2/js/libs/jquery.ui.core-1.11.4.js',
38
- # 'adminsortable2/js/libs/jquery.ui.widget-1.11.4.js',
39
- # 'adminsortable2/js/libs/jquery.ui.mouse-1.11.4.js',
40
- # 'adminsortable2/js/libs/jquery.ui.touch-punch-0.2.3.js',
41
- # 'adminsortable2/js/libs/jquery.ui.sortable-1.11.4.js',
42
- # 'adminsortable2/js/inline-tabular.js',
43
- # 'adminsortable2/js/inline-sortable.js',
35
+ 'adminsortable2/js/adminsortable2.js',
44
36
  )
45
37
 
46
38
  def render(self, name, value, attrs=None, renderer=None):
@@ -80,14 +72,15 @@ class FormsetWidget(forms.Widget):
80
72
  attrs = {'id': 'id_%s-__prefix__-%s' % (prefix, name)}
81
73
  if name == "ORDER":
82
74
  field.initial = 9999
83
- field.widget = forms.HiddenInput()
75
+ field.widget = forms.HiddenInput(attrs={"class": '_reorder_'})
84
76
  set_field_html_name_and_id(
85
77
  field, '%s-__prefix__-%s' % (prefix, name), attrs
86
78
  )
87
79
 
88
- if self.formset.can_order:
89
- for form in self.formset:
90
- form.fields['ORDER'].widget = forms.HiddenInput()
80
+ for form in self.formset:
81
+ form.fields['ORDER'].widget = forms.HiddenInput(
82
+ attrs={"class": '_reorder_'}
83
+ )
91
84
 
92
85
  cell_count = len(list(self.formset.form.declared_fields.keys())) + 1
93
86
  if self.formset.can_order:
@@ -99,7 +92,7 @@ class FormsetWidget(forms.Widget):
99
92
  render_to_string(
100
93
  'admin/formset_widget.html', {
101
94
  'formset': self.formset,
102
- 'inline_formset_data': str(inline_formset_data).replace("'", '"'),
95
+ 'inline_formset_data': json.dumps(inline_formset_data),
103
96
  'cell_count': cell_count,
104
97
  'empty_form': empty_form,
105
98
  'total_org_forms': total_org_forms
simo/core/views.py CHANGED
@@ -3,100 +3,17 @@ import threading
3
3
  import subprocess
4
4
  from django.contrib.auth.decorators import login_required
5
5
  from django.urls import reverse
6
- from django.shortcuts import get_object_or_404, render, redirect
7
- from django.http import FileResponse, HttpResponse, Http404
8
- from django.contrib.gis.geos import Point
6
+ from django.shortcuts import redirect
7
+ from django.http import HttpResponse, Http404
9
8
  from django.contrib import messages
10
- from simo.users.models import User
11
- from simo.conf import dynamic_settings
12
9
  from .models import Instance
13
10
  from .tasks import update as update_task, supervisor_restart
14
- from .forms import (
15
- HubConfigForm, CoordinatesForm, TermsAndConditionsForm
16
- )
17
11
  from .middleware import introduce_instance
18
12
 
19
13
 
20
14
  def get_timestamp(request):
21
15
  return HttpResponse(time.time())
22
16
 
23
-
24
- @login_required
25
- def setup_wizard(request):
26
-
27
- step = request.session.get('setup_wizard_step', 1)
28
-
29
- if request.method == 'POST' and 'back' in request.POST and step > 1:
30
- request.session['setup_wizard_step'] = step - 1
31
- return redirect(request.path)
32
-
33
- if step == 1:
34
- cover_img = dynamic_settings['core__cover_image']
35
- if cover_img:
36
- cover_img.field.storage = cover_img.storage
37
- initial = {
38
- 'name': dynamic_settings['core__hub_name'],
39
- 'uid': dynamic_settings['core__hub_uid'],
40
- 'time_zone': dynamic_settings['core__time_zone'],
41
- 'units_of_measure': dynamic_settings['core__units_of_measure'],
42
- 'cover_image': cover_img
43
- }
44
- form = HubConfigForm(initial=initial, user=request.user)
45
- if request.method == 'POST':
46
- form = HubConfigForm(
47
- request.POST, request.FILES, initial=initial, user=request.user
48
- )
49
- if form.is_valid():
50
- dynamic_settings['core__hub_name'] = form.cleaned_data['name']
51
- dynamic_settings['core__hub_uid'] = form.cleaned_data['uid']
52
- dynamic_settings['core__time_zone'] = form.cleaned_data[
53
- 'time_zone'
54
- ]
55
- dynamic_settings['core__units_of_measure'] = form.cleaned_data[
56
- 'units_of_measure'
57
- ]
58
- if not dynamic_settings['core__location_coordinates'] \
59
- and request.POST.get('location-guess'):
60
- dynamic_settings['core__location_coordinates'] = \
61
- request.POST['location-guess']
62
- if form.cleaned_data['cover_image']:
63
- dynamic_settings['core__cover_image'] = \
64
- form.cleaned_data['cover_image']
65
- dynamic_settings['core__cover_image_synced'] = False
66
- request.session['setup_wizard_step'] = 2
67
- return redirect(request.path)
68
- elif step == 2:
69
- initial = {
70
- 'location': dynamic_settings['core__location_coordinates'],
71
- 'share_location': dynamic_settings['core__share_location']
72
- }
73
- form = CoordinatesForm(initial=initial)
74
- if request.method == 'POST':
75
- form = CoordinatesForm(request.POST, initial=initial)
76
- if form.is_valid():
77
- dynamic_settings['core__location_coordinates'] = \
78
- form.cleaned_data['location']
79
- dynamic_settings['core__share_location'] = \
80
- form.cleaned_data['share_location']
81
- request.session['setup_wizard_step'] = 3
82
- return redirect(request.path)
83
- else:
84
- form = TermsAndConditionsForm()
85
- if request.method == 'POST':
86
- form = TermsAndConditionsForm(request.POST)
87
- if form.is_valid() and form.cleaned_data['accept']:
88
- request.session.pop('setup_wizard_step')
89
- messages.success(
90
- request, "Congratulations! "
91
- "Your Hub is now configured and restarting in the background. "
92
- "Will be fully ready in 30 seconds."
93
- )
94
- threading.Thread(target=supervisor_restart).start()
95
- return redirect(reverse('admin:index'))
96
-
97
- return render(request, 'setup_wizard/form.html', {'form': form, 'step': step})
98
-
99
-
100
17
  @login_required
101
18
  def update(request):
102
19
  if not request.user.is_superuser:
Binary file
Binary file
Binary file
simo/fleet/auto_urls.py CHANGED
@@ -2,7 +2,8 @@ from django.urls import path, re_path
2
2
  from .views import (
3
3
  colonels_ping,
4
4
  PinsSelectAutocomplete,
5
- InterfaceSelectAutocomplete
5
+ InterfaceSelectAutocomplete,
6
+ ControlInputSelectAutocomplete
6
7
  )
7
8
 
8
9
  urlpatterns = [
@@ -17,5 +18,10 @@ urlpatterns = [
17
18
  'autocomplete-colonel-interfaces',
18
19
  InterfaceSelectAutocomplete.as_view(),
19
20
  name='autocomplete-interfaces'
21
+ ),
22
+ path(
23
+ 'autocomplete-control-input',
24
+ ControlInputSelectAutocomplete.as_view(),
25
+ name='autocomplete-control_inputs'
20
26
  )
21
27
  ]