Commit c27a895d59bd1c577f9130fdf5deaabeae9e4959

Authored by Alexis Koralewski
1 parent 5f82ae9f
Exists in dev

add display of raw config file for devices, generic_devices and components on the device_detail page

src/core/pyros_django/obsconfig/templates/obsconfig/device_details.html
@@ -15,8 +15,10 @@ th,td{ @@ -15,8 +15,10 @@ th,td{
15 {% with device_detail|get_item:"name" as device_name %} 15 {% with device_detail|get_item:"name" as device_name %}
16 {% for key,value in device_detail.items %} 16 {% for key,value in device_detail.items %}
17 <div> 17 <div>
18 -  
19 - {% if key == "device_config" %} 18 + {% if key == "file" %}
  19 + <p>{{ key }} : {{ value }} <button id="see_device_file" class="btn btn-light fas fa-eye" value="{{ value }}"></button> </p>
  20 +
  21 + {% elif key == "device_config" %}
20 22
21 {% with device_detail|get_item:key as device_config %} 23 {% with device_detail|get_item:key as device_config %}
22 {% for key,value in device_config.items %} 24 {% for key,value in device_config.items %}
@@ -27,11 +29,13 @@ th,td{ @@ -27,11 +29,13 @@ th,td{
27 29
28 {% with element|get_item:"file" as attached_device_file %} 30 {% with element|get_item:"file" as attached_device_file %}
29 31
30 - {% with file_name_to_device_name|get_item:attached_device_file as attached_device %}  
31 - <p> <a href="{% url 'device_details' attached_device %}">{{ attached_device }} </a> is attached to this device </p>  
32 - {% endwith %} 32 + {% with file_name_to_device_name|get_item:attached_device_file as attached_device %}
  33 + <p> <a href="{% url 'device_details' attached_device %}">{{ attached_device }} </a> is attached to this device </p>
  34 + {% endwith %}
33 {% endwith %} 35 {% endwith %}
34 {% endfor %} 36 {% endfor %}
  37 + {% elif key == "generic" %}
  38 + <p>{{ key }} : {{ value }} <button id="see_device_generic_file" class="btn btn-light fas fa-eye" value="{{ value }}"></button> </p>
35 {% else %} 39 {% else %}
36 <p>{{ key }} : {{ value }}</p> 40 <p>{{ key }} : {{ value }}</p>
37 {% endif %} 41 {% endif %}
@@ -65,94 +69,149 @@ th,td{ @@ -65,94 +69,149 @@ th,td{
65 {% endif %} 69 {% endif %}
66 70
67 {% if capabilities %} 71 {% if capabilities %}
68 - <b>Capabilities : </b> 72 + <h2>Capabilities : </h2>
69 <ul> 73 <ul>
70 {% for capability in capabilities %} 74 {% for capability in capabilities %}
71 -  
72 - {% comment %}  
73 75
74 - {% for information,information_value in capability.items %} 76 + {% comment %}
  77 +
  78 + {% for information,information_value in capability.items %}
75 79
76 - <p>{{ information }} : {{ information_value }}</p> 80 + <p>{{ information }} : {{ information_value }}</p>
77 81
78 - {% endfor %}  
79 - {% endcomment %}  
80 -  
81 - <li> <h3> Component : {{capability.component}} </h3> </li>  
82 - <br>  
83 - <b> attributes : </b>  
84 - <ul>  
85 -  
86 - {% for attribute in capability.attributes %}  
87 - {% with capability.attributes|get_item:attribute as attribute %}  
88 - {% if attribute.is_container %}  
89 - <li><b>{{ attribute.label }} :</li></b>  
90 - <table class="table-bordered table-hover table-striped" > 82 + {% endfor %}
  83 + {% endcomment %}
  84 +
  85 + <li> <h3> Component : {{capability.component}} <button value="{{ capability.component }}" class="btn btn-light fas fa-eye see_component_generic_file"></button></h3> </li>
  86 + <br>
  87 + <b> attributes : </b>
  88 + <ul>
  89 +
  90 + {% for attribute in capability.attributes %}
  91 + {% with capability.attributes|get_item:attribute as attribute %}
  92 + {% if attribute.is_container %}
  93 + <li><b>{{ attribute.label }} :</li></b>
  94 + <table class="table-bordered table-hover table-striped" >
  95 + <thead>
  96 + <tr>
  97 + <th> Variable </th>
  98 + <th> Unit </th>
  99 + <th colspan="20"> Values </th>
  100 + </tr>
  101 + </thead>
  102 + <tbody>
  103 + {% for val_name in attribute.value %}
  104 + <tr>
  105 + <td> {{ val_name }} </td>
  106 + <td>{{ attribute.unit|get_item:val_name}} </td>
  107 + {% for value in attribute.value|get_item:val_name %}
  108 +
  109 + {% if value|get_type == 'list' %}
  110 + <td>
  111 + <table class="table-bordered">
  112 + <tbody>
  113 + {% with value as values %}
  114 + <tr>
  115 + {% for value in values %}
  116 + <td> {{value}} </td>
  117 + {% endfor %}
  118 + </tr>
  119 + </tbody>
  120 + </table>
  121 + {% endwith %}
  122 + </td>
  123 +
  124 + {% else %}
  125 + <td> {{value}} </td>
  126 + {% endif %}
  127 + {% endfor %}
  128 + </tr>
  129 + {% endfor %}
  130 + </tbody>
  131 + </table>
  132 + {% elif attribute.is_enum %}
  133 + <li><b>{{ attribute.label }} :</li></b>
  134 + <table class="table-bordered table-hover table-striped" >
91 <thead> 135 <thead>
92 <tr> 136 <tr>
  137 + <tr>
93 <th> Variable </th> 138 <th> Variable </th>
94 - <th> Unit </th>  
95 - <th colspan="20"> Values </th> 139 + <th colspan="20"> Values (One of the following values)</th>
96 </tr> 140 </tr>
97 </thead> 141 </thead>
98 <tbody> 142 <tbody>
99 - {% for val_name in attribute.value %}  
100 <tr> 143 <tr>
101 - <td> {{ val_name }} </td>  
102 - <td>{{ attribute.unit|get_item:val_name}} </td>  
103 - {% for value in attribute.value|get_item:val_name %}  
104 -  
105 - {% if value|get_type == 'list' %}  
106 - <td>  
107 - <table class="table-bordered">  
108 - <tbody>  
109 - {% with value as values %}  
110 - <tr>  
111 - {% for value in values %}  
112 - <td> {{value}} </td>  
113 - {% endfor %}  
114 - </tr>  
115 - </tbody>  
116 - </table>  
117 - {% endwith %}  
118 - </td>  
119 -  
120 - {% else %}  
121 - <td> {{value}} </td>  
122 - {% endif %}  
123 - {% endfor %}  
124 - </tr> 144 + <td> {{ attribute.label}} </td>
  145 + {% for val in attribute.value %}
  146 + <td> {{ val }} </td>
125 {% endfor %} 147 {% endfor %}
  148 + </tr>
126 </tbody> 149 </tbody>
127 - </table>  
128 - {% elif attribute.is_enum %}  
129 - <li><b>{{ attribute.label }} :</li></b>  
130 - <table class="table-bordered table-hover table-striped" >  
131 - <thead>  
132 - <tr>  
133 - <tr>  
134 - <th> Variable </th>  
135 - <th colspan="20"> Values (One of the following values)</th>  
136 - </tr>  
137 - </thead>  
138 - <tbody>  
139 - <tr>  
140 - <td> {{ attribute.label}} </td>  
141 - {% for val in attribute.value %}  
142 - <td> {{ val }} </td>  
143 - {% endfor %}  
144 - </tr>  
145 - </tbody>  
146 - </table>  
147 - {% else %}  
148 - <li>{{ attribute.label }} : {{ attribute.value}} {{ attribute.unit}} </li>  
149 - {% endif %}  
150 - {% endwith %}  
151 - {% endfor %}  
152 - </ul> 150 + </table>
  151 + {% else %}
  152 + <li>{{ attribute.label }} : {{ attribute.value}} {{ attribute.unit}} </li>
  153 + {% endif %}
  154 + {% endwith %}
  155 + {% endfor %}
  156 + </ul>
153 {% endfor %} 157 {% endfor %}
154 </ul> 158 </ul>
155 {% endif %} 159 {% endif %}
156 {% endwith %} 160 {% endwith %}
157 161
  162 +
  163 +{# modal for displaying raw yaml files #}
  164 +
  165 +<div class="modal" tabindex="-1" id="rawFileModal" role="dialog">
  166 + <div class="modal-dialog modal-lg" role="document">
  167 + <div class="modal-content">
  168 + <div class="modal-header">
  169 + <h5 id="#rawFileModal_title" class="modal-title"></h5>
  170 + <button type="button" class="close" data-dismiss="modal" aria-label="Close">
  171 + <span aria-hidden="true">&times;</span>
  172 + </button>
  173 + </div>
  174 + <div class="modal-body">
  175 + <pre id="view_raw_file"></pre>
  176 + </div>
  177 + <div class="modal-footer">
  178 + <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
  179 + </div>
  180 + </div>
  181 + </div>
  182 +</div>
  183 +
  184 +<script>
  185 +$('.see_component_generic_file').on("click",function(){
  186 + console.log($(this));
  187 + console.log($(this).val());
  188 + let file_name = $(this).val()+".yml";
  189 + console.log(file_name);
  190 + $.post("{% url 'view_raw_component_config_file' %}",{"yaml_file":file_name},function(data){
  191 + console.log(data);
  192 + $("#view_raw_file").html(data);
  193 + $(".modal-title").html(file_name);
  194 + $('#rawFileModal').modal('show');
  195 + })
  196 +});
  197 +
  198 +
  199 +$('#see_device_generic_file').on("click",function(){
  200 + let file_name = $("#see_device_generic_file").val();
  201 + $.post("{% url 'view_raw_generic_device_config_file' %}",{"yaml_file":file_name},function(data){
  202 + $("#view_raw_file").html(data);
  203 + $(".modal-title").html(file_name);
  204 + $('#rawFileModal').modal('show');
  205 + })
  206 +});
  207 +
  208 +$('#see_device_file').on("click",function(){
  209 + let file_name = $("#see_device_file").val();
  210 + $.post("{% url 'view_raw_device_config_file' %}",{"yaml_file":file_name},function(data){
  211 + $("#view_raw_file").html(data);
  212 + $(".modal-title").html(file_name);
  213 + $('#rawFileModal').modal('show');
  214 + })
  215 +});
  216 +</script>
158 {% endblock %} 217 {% endblock %}
159 \ No newline at end of file 218 \ No newline at end of file
src/core/pyros_django/obsconfig/urls.py
@@ -11,5 +11,8 @@ urlpatterns = [ @@ -11,5 +11,8 @@ urlpatterns = [
11 path('device_details/<str:device_name>', views.device_details, name='device_details'), 11 path('device_details/<str:device_name>', views.device_details, name='device_details'),
12 path('edit_config',views.edit_config,name="edit_config"), 12 path('edit_config',views.edit_config,name="edit_config"),
13 path('verify_config',views.verify_config,name="verify_config"), 13 path('verify_config',views.verify_config,name="verify_config"),
14 - path('save_config',views.save_config,name="save_config") 14 + path('save_config',views.save_config,name="save_config"),
  15 + path("view_raw_component_config_file",views.view_raw_component_config_file,name="view_raw_component_config_file"),
  16 + path("view_raw_device_config_file",views.view_raw_device_config_file,name="view_raw_device_config_file"),
  17 + path("view_raw_generic_device_config_file",views.view_raw_generic_device_config_file,name="view_raw_generic_device_config_file"),
15 ] 18 ]
16 \ No newline at end of file 19 \ No newline at end of file
src/core/pyros_django/obsconfig/views.py
@@ -6,6 +6,7 @@ from src.core.pyros_django.dashboard.decorator import level_required @@ -6,6 +6,7 @@ from src.core.pyros_django.dashboard.decorator import level_required
6 from django.contrib.auth.decorators import login_required 6 from django.contrib.auth.decorators import login_required
7 from django.http import HttpResponse 7 from django.http import HttpResponse
8 from datetime import datetime 8 from datetime import datetime
  9 +from django.views.decorators.csrf import csrf_exempt
9 import re, yaml,tempfile,json,os 10 import re, yaml,tempfile,json,os
10 11
11 def get_nested_dictionaries_as_list(dic,result=[]): 12 def get_nested_dictionaries_as_list(dic,result=[]):
@@ -98,7 +99,7 @@ def computer_details(request,computer_name): @@ -98,7 +99,7 @@ def computer_details(request,computer_name):
98 99
99 100
100 @login_required 101 @login_required
101 -@level_required("Admin","Unit-PI","Operator","Observer") 102 +@level_required("Admin","Unit-PI","Unit-board","Operator","Observer")
102 def device_details(request,device_name): 103 def device_details(request,device_name):
103 config = ConfigPyros(os.environ["PATH_TO_OBSCONF_FILE"]) 104 config = ConfigPyros(os.environ["PATH_TO_OBSCONF_FILE"])
104 # We're removing "_" at the beginning of each key : 105 # We're removing "_" at the beginning of each key :
@@ -117,7 +118,6 @@ def device_details(request,device_name): @@ -117,7 +118,6 @@ def device_details(request,device_name):
117 118
118 119
119 device_detail = { re.sub("^_","",key):value for key,value in config.get_devices()[device_name].items()} 120 device_detail = { re.sub("^_","",key):value for key,value in config.get_devices()[device_name].items()}
120 -  
121 #test_device= get_nested_dictionaries_as_list(device_detail,[]) 121 #test_device= get_nested_dictionaries_as_list(device_detail,[])
122 122
123 if config.get_device_power(device_name) is not None: 123 if config.get_device_power(device_name) is not None:
@@ -282,4 +282,38 @@ def save_config(request): @@ -282,4 +282,38 @@ def save_config(request):
282 obs_config_file.write(request.POST.get("config")) 282 obs_config_file.write(request.POST.get("config"))
283 283
284 284
285 - return HttpResponse("Ok !")  
286 \ No newline at end of file 285 \ No newline at end of file
  286 + return HttpResponse("Ok !")
  287 +
  288 +@login_required
  289 +@level_required("Admin","Unit-PI","Unit-board","Operator","Observer")
  290 +@csrf_exempt
  291 +def view_raw_component_config_file(request):
  292 + COMPONENT_PATH = os.path.join(os.environ["DJANGO_PATH"],"../../../config/components/")
  293 +
  294 + if request.POST:
  295 + try:
  296 + yaml_file = open(COMPONENT_PATH+request.POST["yaml_file"])
  297 + content = yaml_file.readlines()
  298 + except:
  299 + content = "Component defined within the device configuration file"
  300 + return HttpResponse(content)
  301 +
  302 +@login_required
  303 +@level_required("Admin","Unit-PI","Unit-board","Operator","Observer")
  304 +@csrf_exempt
  305 +def view_raw_generic_device_config_file(request):
  306 + GENERIC_DEVICES_PATH = os.path.join(os.environ["DJANGO_PATH"],"../../../config/devices/")
  307 + if request.POST:
  308 + yaml_file = open(GENERIC_DEVICES_PATH+request.POST["yaml_file"])
  309 + content = yaml_file.readlines()
  310 + return HttpResponse(content)
  311 +
  312 +@login_required
  313 +@level_required("Admin","Unit-PI","Unit-board","Operator","Observer")
  314 +@csrf_exempt
  315 +def view_raw_device_config_file(request):
  316 + obs_folder = os.environ["PATH_TO_OBSCONF_FOLDER"]
  317 + if request.POST:
  318 + yaml_file = open(obs_folder+request.POST["yaml_file"])
  319 + content = yaml_file.readlines()
  320 + return HttpResponse(content)
287 \ No newline at end of file 321 \ No newline at end of file
src/core/pyros_django/pyros/settings.py
@@ -401,5 +401,5 @@ python_version = subprocess.run( &quot;python --version | cut -d &#39; &#39; -f 2 | cut -d &#39;. @@ -401,5 +401,5 @@ python_version = subprocess.run( &quot;python --version | cut -d &#39; &#39; -f 2 | cut -d &#39;.
401 python_version = python_version.stdout 401 python_version = python_version.stdout
402 today = datetime.utcnow().date() 402 today = datetime.utcnow().date()
403 django_version_major,django_version_minor = django.VERSION[:2][0],django.VERSION[:2][1] 403 django_version_major,django_version_minor = django.VERSION[:2][0],django.VERSION[:2][1]
404 -pyros_version = "0.2.6.0" 404 +pyros_version = "0.2.7.0"
405 VERSION_NUMBER = f"{pyros_version}_{django_version_major}.{django_version_minor}_{python_version}_{today}" 405 VERSION_NUMBER = f"{pyros_version}_{django_version_major}.{django_version_minor}_{python_version}_{today}"
406 \ No newline at end of file 406 \ No newline at end of file