web-UI refactoring
Added wpa_supplicant.conf generator refactored web-ui to support dynamic additions of modules added support for module height by ratio (or percentage) Changed format of settings file slightly to support info section height
This commit is contained in:
		| @@ -22,7 +22,7 @@ def wifi_setup(): | ||||
|  | ||||
|  | ||||
| # Inkycal-setup | ||||
| @app.route('/inkycal_config', methods=['GET', 'POST']) | ||||
| @app.route('/inkycal-config-v2-0-0', methods=['GET', 'POST']) | ||||
|  | ||||
| def inkycal_config(): | ||||
|     form = LoginForm() | ||||
| @@ -38,16 +38,20 @@ def inkycal_config(): | ||||
|         language = request.form.get('language') | ||||
|         info_section = True if (request.form.get('info_section') == "on") else False | ||||
|  | ||||
|         info_height = int(request.form.get('info_section_height')) if info_section == True else None | ||||
|  | ||||
|         # template for basic settings | ||||
|         template = { | ||||
|             "model": model, | ||||
|             "update_interval": update_interval, | ||||
|             "orientation": int(request.form.get('orientation')), | ||||
|             "info_section": info_section, | ||||
|             "info_section_height": info_height, | ||||
|             "calibration_hours": [calibration_hour_1, calibration_hour_2, calibration_hour_3], | ||||
|             "modules": [], | ||||
|             } | ||||
|  | ||||
|  | ||||
|         # common module config (shared by all modules) | ||||
|         padding_x = int(request.form.get('padding_x')) | ||||
|         padding_y = int(request.form.get('padding_y')) | ||||
| @@ -56,30 +60,42 @@ def inkycal_config(): | ||||
|  | ||||
|         common_settings = {"padding_x":padding_x, "padding_y":padding_y, "fontsize":fontsize, "language":language} | ||||
|  | ||||
|         # display size | ||||
|         display_size = Display.get_display_size(model) | ||||
|         width, height = int(display_size[0]), int(display_size[1]) | ||||
|          | ||||
|  | ||||
|         # loop over the modules, add their config data based on user selection, merge the common_settings into each module's config | ||||
|         for i in range(1,4): | ||||
|             conf = {} | ||||
|             module = 'module'+str(i) | ||||
|             if request.form.get(module) != "None": | ||||
|         no_of_modules = int(request.form.get("module_counter")) | ||||
|  | ||||
|         # display size ---- Since Inkycal works in vertical mode (only), the width and height have to be flipped here | ||||
|         display_size = Display.get_display_size(model) # returns width,height but flipping these for vertical mode | ||||
|         height, width = int(display_size[0]), int(display_size[1]) | ||||
|  | ||||
|         # If info section was active, substract the height of the info section from the display height | ||||
|         if info_section == True: | ||||
|             height = height-info_height | ||||
|  | ||||
|         # get all module heights, calculate single part | ||||
|         module_sizes = [int(request.form.get("module"+str(i)+"_height")) for i in range(1, no_of_modules+1)] | ||||
|  | ||||
|         if sum(module_sizes) != 0: | ||||
|             single_part = height / sum(module_sizes) | ||||
|  | ||||
|         for i in range(1, no_of_modules+1): | ||||
|             conf = {} | ||||
|             module = 'selected_module'+str(i) | ||||
|  | ||||
|             if request.form.get(module) != "None": | ||||
|                 conf = {"position":i , "name": request.form.get(module), "config":{}} | ||||
|  | ||||
|                 for modules in settings: | ||||
|                     if modules['name'] == request.form.get(module): | ||||
|  | ||||
|                         conf['config']['size'] = (width, int(height*int(request.form.get(module+'_height')) /100)) | ||||
|                         module_height = int( request.form.get("module"+str(i)+"_height") ) | ||||
|                         conf['config']['size'] = (width, int(single_part*module_height) ) | ||||
|  | ||||
|                         # Add required fields to the config of the module in question | ||||
|                         # True/False choices are converted to string for some reason, leading to incorrect values | ||||
|                         # Convert "True" to True, "False" to False and empty input to None | ||||
|                         if 'requires' in modules: | ||||
|                             for key in modules['requires']: | ||||
|                                 val = request.form.get(module+'_'+key).replace(" ", "") | ||||
|                                 val = request.form.get('module'+str(i)+'_'+key).replace(" ", "") | ||||
|                                 if val == "True": | ||||
|                                     val = True | ||||
|                                 elif val == "False": | ||||
| @@ -95,7 +111,7 @@ def inkycal_config(): | ||||
|                         if 'optional' in modules: | ||||
|                             for key in modules['optional']: | ||||
|                                 if request.form.get(module+'_'+key): | ||||
|                                     val = request.form.get(module+'_'+key).replace(" ", "") | ||||
|                                     val = request.form.get('module'+str(i)+'_'+key).replace(" ", "") | ||||
|                                     if val == "True": | ||||
|                                         val = True | ||||
|                                     elif val == "False": | ||||
| @@ -124,4 +140,6 @@ def inkycal_config(): | ||||
|         except Exception as e: | ||||
|             flash(str(e)) | ||||
|  | ||||
|     return render_template('inkycal_config.html', title='Inkycal-Setup', conf=settings, form=form) | ||||
|  | ||||
|     return render_template('inkycal-config-v2-0-0.html', title='Inkycal-Setup', conf=settings, form=form) | ||||
|  | ||||
|   | ||||
| @@ -31,7 +31,7 @@ | ||||
|                         </li> | ||||
|  | ||||
|                         <li class="nav-item"> | ||||
|                             <a class="nav-link" href="/inkycal_config">Setup</a> | ||||
|                             <a class="nav-link" href="/inkycal-config-v2-0-0">Setup</a> | ||||
|                         </li> | ||||
|                         <li class="nav-item"> | ||||
|                             <a class="nav-link" href="/setup_wifi">WiFi-setup</a> | ||||
|   | ||||
							
								
								
									
										463
									
								
								server/app/templates/inkycal-config-v2-0-0.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										463
									
								
								server/app/templates/inkycal-config-v2-0-0.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,463 @@ | ||||
| {% extends "base.html" %} | ||||
|  | ||||
| <!-- Main container --> | ||||
| {% block content %} | ||||
|  | ||||
| <!-- Wrap everything in a container--> | ||||
| <div class="container"> | ||||
|  | ||||
| <!-- heading --> | ||||
| <h3>Inkycal-Setup v.2.0.0</h3> | ||||
|  | ||||
| <!-- project link--> | ||||
| <div class="alert alert-light" role="alert"> | ||||
|   <a href="https://github.com/aceisace/Inky-Calendar">For Inkycal Project of ace innovation laboratory - aceinnolab.com - by aceisace</a><br> | ||||
| </div> | ||||
|  | ||||
| <!-- Inkycal logo --> | ||||
| <img class="img-fluid" src="https://github.com/aceisace/Inky-Calendar/blob/development/Gallery/logo.png?raw=true" alt="Inkycal Logo"> | ||||
|  | ||||
| <br><br> | ||||
|  | ||||
| <!-- Instructions --> | ||||
| <div class="alert alert-primary" role="alert"> | ||||
|     <h4 class="alert-heading">Instructions</h4> | ||||
|     Insert your personal details and preferences and click on 'Generate'.<br> | ||||
|     Copy the downloaded file to the Raspberry Pi.<br> | ||||
|     The location does not matter, however, you need to know the path to this file.<br> | ||||
|     <hr> | ||||
|     <p class="mb-0">If no value is filled in for any of the row, the default value will be used.</p> | ||||
| </div> | ||||
|  | ||||
| <!-- Main form --> | ||||
| <form class="needs-validation" method="post" novalidate> | ||||
|     {{ form.hidden_tag() }} | ||||
|  | ||||
|     <h4> General settings </h4> | ||||
|  | ||||
|     <!-- group E-Paper settings in a single row--> | ||||
|     <div class="form-row"> | ||||
|  | ||||
|     <!-- model selection start--> | ||||
|     <div class="col"> | ||||
|         <label for="model">Model</label> | ||||
|         <select class="form-control" id="model" name="model"> | ||||
|  | ||||
|             <option value="9_in_7">                     9.7" ePaper                         </option> | ||||
|  | ||||
|             <option value="epd_7_in_5_v3_colour">       7.5" v3 (880x528px) colour          </option> | ||||
|             <option value="epd_7_in_5_v3" selected>     7.5" v3 (880x528px) black-white     </option> | ||||
|  | ||||
|             <option value="epd_7_in_5_v2_colour">       7.5" v2 (800x400px) colour          </option> | ||||
|             <option value="epd_7_in_5_v2">              7.5" v2 (800x400px) black-white     </option> | ||||
|  | ||||
|             <option value="epd_7_in_5_colour">          7.5" v1 (600x384px) colour          </option> | ||||
|             <option value="epd_7_in_5">                 7.5" v1 (600x384px) black-white     </option> | ||||
|  | ||||
|             <option value="epd_5_in_83_colour">         5.83" colour                        </option> | ||||
|             <option value="epd_5_in_83">                5.83" black-white                   </option> | ||||
|  | ||||
|             <option value="epd_4_in_2_colour">          4.2" colour                         </option> | ||||
|             <option value="epd_4_in_2">                 4.2" black-white                    </option> | ||||
|         </select> | ||||
|     </div> | ||||
|  | ||||
|  | ||||
|     <!-- Update interval start--> | ||||
|     <div class="col"> | ||||
|         <label>Update interval</label><br> | ||||
|         <select class="form-control" id="update_interval" name="update_interval"> | ||||
|             <option value=60 checked>           every 60 minutes                        </option> | ||||
|             <option value=30>                   every 30 minutes                        </option> | ||||
|             <option value=20>                   every 20 minutes                        </option> | ||||
|             <option value=15>                   every 15 minutes                        </option> | ||||
|             <option value=10>                   every 10 minutes                        </option> | ||||
|         </select> | ||||
|     </div> | ||||
|  | ||||
|     <!-- Update interval end--> | ||||
|  | ||||
|  | ||||
|     <!-- Orientation start --> | ||||
|     <div class="col"> | ||||
|         <label>Orientation</label><br> | ||||
|  | ||||
|         <select class="form-control" id="orientation" name="orientation"> | ||||
|             <option value=0 checked>            Flex cable left                         </option> | ||||
|             <option value=180>                  Flex cable right                        </option> | ||||
|         </select> | ||||
|  | ||||
|     </div> | ||||
|  | ||||
|     </div><br> <!-- row end --> | ||||
|  | ||||
|     <!-- Calibration start --> | ||||
|     <div class="form-group"> | ||||
|         <label>When should the display be calibrated? (Leave blank if you're unsure)</label> | ||||
|  | ||||
|         <!-- Info about calibration (collapsible info)--> | ||||
|         <details> | ||||
|  | ||||
|             <summary>Info about calibration</summary> | ||||
|             <blockquote class="blockquote"> | ||||
|                 Calibration is a way to retain nice colours on ePaper displays. It works by flushing colours a few times on the entire display. | ||||
|                 Please choose 3 hours in 24-hour format (0-24) to specify at which hours calibration should be executed. | ||||
|                 Please also note that it takes around 10-20 minutes to calibrate, so best to choose hours when you won't be looking at Inkycal. | ||||
|             </blockquote> | ||||
|  | ||||
|         </details> | ||||
|  | ||||
|  | ||||
|         <!-- Calibration hours input fields--> | ||||
|         <div class="form-row"> | ||||
|             <div class="col"> | ||||
|                 <input type="number" class="form-control" name="calibration_hour_1" value=0 min=0 max=24> | ||||
|             </div> | ||||
|  | ||||
|             <div class="col"> | ||||
|                 <input type="number" class="form-control" name="calibration_hour_2" value=12 min=0 max=24> | ||||
|                 </div> | ||||
|  | ||||
|             <div class="col"> | ||||
|                 <input type="number" class="form-control" name="calibration_hour_3" value=18 min=0 max=24> | ||||
|             </div> | ||||
|         </div> | ||||
|         <!-- Calibration hours input end--> | ||||
|     </div> | ||||
|     <!-- Calibration end--> | ||||
|  | ||||
|     <!-- Info section --> | ||||
|     <div class="form-row"> | ||||
|         <div class="col"> | ||||
|             <div class="form-check"> | ||||
|                 <input type="checkbox" class="form-check-input" id="info_section" name="info_section"> | ||||
|                 <label class="form-check-label" for="info_section">Show time of last update?</label> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|         <div class="col" id="info_height"> | ||||
|             <div class="form-check"> | ||||
|                 <label class="form-check-label" for="info_section_height">Height in pixels</label> | ||||
|                 <input type="number" class="form-control" id="info_section_height" name="info_section_height" value=30 min=0 max=100> | ||||
|             </div> | ||||
|         </div> | ||||
|          | ||||
|     </div><br> | ||||
|  | ||||
|     <h4> Common module settings </h4> | ||||
|     <div class="form-row"> | ||||
|         <!-- language selection- shared by all modules --> | ||||
|         <div class="col"> | ||||
|             <label for="language">Language</label> | ||||
|             <select class="form-control" id="language" name="language"> | ||||
|  | ||||
|                 <option value="en" selected>    English                     </option> | ||||
|                 <option value="de">             German                      </option> | ||||
|                 <option value="ru">             Russian                     </option> | ||||
|                 <option value="it">             Italian                     </option> | ||||
|                 <option value="es">             Spanish                     </option> | ||||
|                 <option value="fr">             French                      </option> | ||||
|                 <option value="el">             Greek                       </option> | ||||
|                 <option value="sv">             Swedish                     </option> | ||||
|                 <option value="nl">             Dutch                       </option> | ||||
|                 <option value="pl">             Polish                      </option> | ||||
|                 <option value="ua">             Ukrainian                   </option> | ||||
|                 <option value="nb">             Norwegian                   </option> | ||||
|                 <option value="vi">             Vietnamese                  </option> | ||||
|                 <option value="zh-tw">          Chinese-Taiwanese           </option> | ||||
|                 <option value="zh">             Chinese                     </option> | ||||
|                 <option value="ja">             Japanese                    </option> | ||||
|                 <option value="ko">             Korean                      </option> | ||||
|  | ||||
|             </select> | ||||
|         </div> | ||||
|  | ||||
|  | ||||
|         <!--fontsize selection - shared by all modules--> | ||||
|         <div class="col"> | ||||
|             <label for="fontsize">Fontsize</label> | ||||
|             <input type="number" class="form-control" name="fontsize" placeholder=12 value=12 min=0 max=30> | ||||
|         </div> | ||||
|  | ||||
|         <!--padding-top-bottom - shared by all modules--> | ||||
|         <div class="col"> | ||||
|             <label for="padding_y">Padding top/bottom (in pixels) </label> | ||||
|             <input type="number" class="form-control" name="padding_y" placeholder=10 value=10 min=0 max=30> | ||||
|         </div> | ||||
|  | ||||
|         <!--padding-left-right - shared by all modules--> | ||||
|         <div class="col"> | ||||
|             <label for="padding_x">Padding right/left (in pixels) </label> | ||||
|             <input type="number" class="form-control" name="padding_x" placeholder=10 value=10 min=0 max=30> | ||||
|         </div> | ||||
|  | ||||
|     </div><br> | ||||
|  | ||||
|  | ||||
|     <!--Create templates for modules with their respective config for later use--> | ||||
|     {% for module in conf %} | ||||
|     <template id={{ module["name"] }} > | ||||
|         <div class="card"><div class="card-header">{{ module["name_str"] }} config</div> | ||||
|             <div class="card-body"> | ||||
|  | ||||
|                 {% if module['requires'] != {} %} | ||||
|                     <h5 class="card-title">Required config</h5> | ||||
|                 {% endif %} | ||||
|  | ||||
|                 {% for key in module["requires"] %} | ||||
|                     {% if 'options' in module["requires"][key] %} | ||||
|                         <label for={{key}}>{{module["requires"][key]["label"]}} *</label> | ||||
|  | ||||
|                         <select class="form-control" id={{key}} name={{ module["name"] }}_{{key}} required> | ||||
|                         {% for option in module["requires"][key]['options'] %} | ||||
|                             <option value={{option}}> {{option}} </option> | ||||
|                         {% endfor %} | ||||
|                         </select> | ||||
|  | ||||
|                         <div class="invalid-feedback">Sorry, but this field should not be empty</div> | ||||
|                         <div class="valid-feedback"> Looks good! </div> | ||||
|                     {% endif %} | ||||
|  | ||||
|                     {% if not 'options' in module["requires"][key] %} | ||||
|                         <label for={{key}}>{{module["requires"][key]["label"]}} *</label> | ||||
|                         <input type="text" class="form-control" id={{key}} name={{ module["name"] }}_{{key}} required> | ||||
|                         <div class="invalid-feedback">Sorry, but this field should not be empty</div> | ||||
|                         <div class="valid-feedback"> Looks good! </div> | ||||
|                     {% endif %} | ||||
|                     <br> | ||||
|                 {% endfor %} | ||||
|  | ||||
|  | ||||
|                 {% if module['optional'] != {} %} | ||||
|                     <h5 class="card-title">Optional config</h5> | ||||
|                 {% endif %} | ||||
|  | ||||
|                 {% for key in module["optional"] %} | ||||
|  | ||||
|                     {% if 'options' in module["optional"][key] %} | ||||
|                         <label for={{key}}>{{module["optional"][key]["label"]}}</label> | ||||
|  | ||||
|                         <select class="form-control" id={{key}} name={{ module["name"] }}_{{key}}> | ||||
|                         {% for option in module["optional"][key]['options'] %} | ||||
|                             <option value={{option}}> {{option}} </option> | ||||
|                         {% endfor %} | ||||
|                         </select> | ||||
|  | ||||
|                         <div class="invalid-feedback">Sorry, but this field should not be empty</div> | ||||
|                         <div class="valid-feedback"> Looks good! </div> | ||||
|                     {% endif %} | ||||
|  | ||||
|                     {% if not 'options' in module["optional"][key] %} | ||||
|                         <label for={{key}}>{{module["optional"][key]["label"]}}</label> | ||||
|                         <input type="text" class="form-control" id={{key}} name={{ module["name"] }}_{{key}}> | ||||
|                     {% endif %} | ||||
|                 {% endfor %} | ||||
|  | ||||
|             </div> | ||||
|         </div> | ||||
|     </template> | ||||
|     {% endfor %} | ||||
|  | ||||
|     <h4> Modules config </h4> | ||||
|  | ||||
|     <div class="alert alert-primary" role="alert"> | ||||
|         Fields marked with an asterisk(*) are required <br> | ||||
|         <hr> | ||||
|         Module height is calculated by ratio (parts) e.g. <br> | ||||
|         module 1 = 20 parts, module 2 = 30 parts -> total of 50 parts <br> | ||||
|         If your display has a height of 400 px, then each part is: 400/50 = 8px <br> | ||||
|         Module 1 with 30 parts will have 20 * 8px = 160 px <br> | ||||
|         Module 2 with 50 parts will have 30 * 8px = 240 px <br> | ||||
|     </div> | ||||
|  | ||||
|     <!-- Basic template to choose module --> | ||||
|     <template id='module_template'> | ||||
|  | ||||
|         <div id="module_id"> | ||||
|             <div class="form-row"> | ||||
|                 <div class="col-md-8"> | ||||
|                 <label for="module" id="module_label">Module</label> | ||||
|                     <select class="form-control" id="selected_module" name="selected_module"> | ||||
|                         <option value="None" checked>Empty</option> | ||||
|                         {% for module in conf%} | ||||
|                             <option value={{ module['name'] }} > {{module['name_str'] }} </option> | ||||
|                         {% endfor %} | ||||
|                     </select> | ||||
|                 </div> | ||||
|  | ||||
|                 <div class="col-md-4"> | ||||
|                     <label for="module_height">Module height (by ratio)</label> | ||||
|                     <input type="number" class="form-control" id="module_height" name="module_height" value=20 placeholder=20 min=0 max=1200> | ||||
|                 </div> | ||||
|  | ||||
|             </div><br> | ||||
|             <div id="module_conf"></div> | ||||
|         </div> | ||||
|  | ||||
|     </template> | ||||
|  | ||||
|     <div class="module_section" id="modules"><!-- modules are added in this div --></div> | ||||
|  | ||||
|  | ||||
|     <br> | ||||
|     <div class="form-group"> | ||||
|         <input class="btn btn-success" type="button" id="add_module" value="Add module"> | ||||
|         <input class="btn btn-warning" type="button" id="remove_module" value="Remove last module"> | ||||
|     </div> | ||||
|  | ||||
|     <input type="number" class="d-none" id="module_counter" name="module_counter" value=0 min=0 max=10 readonly> | ||||
|  | ||||
| <!--Show config of selected modules--> | ||||
| <script> | ||||
| $(document).ready(function(){ | ||||
|  | ||||
| var num_modules = 0; | ||||
|  | ||||
| function add_module() { | ||||
|  | ||||
|     num_modules += 1; | ||||
|     var new_name = 'module'+num_modules; | ||||
|     console.log('added module:',new_name); | ||||
|  | ||||
|     var content = document.getElementById("module_template").content; | ||||
|     var targetContainer = document.getElementById("modules"); | ||||
|     targetContainer.appendChild(document.importNode(content, true)); | ||||
|  | ||||
|     $('#module_id').attr("id", new_name); | ||||
|  | ||||
|     $('#selected_module').attr("name", $('#selected_module').attr("name")+num_modules); | ||||
|     $('#selected_module').attr("id", $('#selected_module').attr("id")+num_modules); | ||||
|  | ||||
|     $('#module_label').text("Module "+num_modules); | ||||
|     $('#module_label').attr("id", new_name+'_label'); | ||||
|  | ||||
|     $('#module_height').attr("name", new_name+'_height'); | ||||
|     $('#module_height').attr("id", new_name+'_height'); | ||||
|  | ||||
|     $('#module_conf').attr("name", new_name+'_conf'); | ||||
|     $('#module_conf').attr("id", new_name+'_conf'); | ||||
|  | ||||
|     $('#module_counter').attr('value', num_modules); | ||||
| } | ||||
|  | ||||
| function remove_module() { | ||||
|     var new_name = 'module'+num_modules; | ||||
|     //console.log('removing last module'); | ||||
|     $('#module'+num_modules).remove(); | ||||
|     num_modules -= 1; | ||||
|     $('#module_counter').attr('value', num_modules); | ||||
| } | ||||
|  | ||||
| $('#add_module').click(function(){ | ||||
|     if (num_modules >= 10) { | ||||
|         console.log('you have exceeded the max number of modules!'); | ||||
|         return false | ||||
|     } else { | ||||
|     add_module(); | ||||
|     } | ||||
| }) | ||||
|  | ||||
| $('#remove_module').click(function(){ | ||||
|     if (num_modules <= 0) { | ||||
|         console.log('Cannot remove any more modules!'); | ||||
|         return false | ||||
|     } else { | ||||
|     console.log('removed module'+num_modules); | ||||
|     remove_module(); | ||||
|     } | ||||
| }) | ||||
|  | ||||
| $("#info_height").hide(); | ||||
|  | ||||
| $("#info_section").click(function(){ | ||||
|     if($(this).prop("checked") == true){ | ||||
|         $('#info_height').show(); | ||||
|     } else { | ||||
|         $('#info_height').hide(); | ||||
|     } | ||||
| }); | ||||
|  | ||||
| function insert_config(module_no, module_name) { | ||||
|     console.log('module', module_no, ' set to ', module_name); | ||||
|  | ||||
|     remove_config(module_no); | ||||
|  | ||||
|     var module_template = document.querySelector("#"+module_name); | ||||
|     var clone = document.importNode(module_template.content, true); | ||||
|     $("#module"+module_no+"_conf").append(clone); | ||||
|  | ||||
|     // With the selected module name known, we can replace the name tag of that module's config for unique id's | ||||
|     // This allows having multiple modules running with different configs for each instance | ||||
|  | ||||
|     $("#module"+module_no+"_conf input").each(function(i) { | ||||
|         $(this).attr('id', "module"+module_no+"_"+$(this).attr('id')); | ||||
|         $(this).attr('name', $(this).attr('name').replace(module_name, "module"+module_no)); | ||||
|     }); | ||||
|  | ||||
|     $("#module"+module_no+"_conf select").each(function(i) { | ||||
|         $(this).attr('id', "module"+module_no+"_"+$(this).attr('id')); | ||||
|         $(this).attr('name', $(this).attr('name').replace(module_name, "module"+module_no)); | ||||
|     }); | ||||
|  | ||||
| } | ||||
|  | ||||
| function remove_config(module_number) { | ||||
|     $("#module"+module_number+"_conf").empty(); | ||||
| } | ||||
|  | ||||
| $('#add_module, #remove_module').on('click',function() { //every time the add/remove module button is clicked | ||||
|  | ||||
|     $("[id^=selected_module]").on('change',function() { | ||||
|  | ||||
|         if ($(this).find("option:selected").val() == "None") { //check if parent is a certain name | ||||
|  | ||||
|             var module_index = $(this).attr('id').replace('selected_module', ""); | ||||
|             var is_module = $.isNumeric(module_index); | ||||
|             //console.log("module_index", module_index, "is_module", is_module); | ||||
|             if (is_module) { remove_config(module_index); } | ||||
|  | ||||
|         } else { | ||||
|             console.log("found module"); | ||||
|             var module_name = $(this).find("option:selected").val(); | ||||
|             //console.log($(this).attr('id')); | ||||
|             var module_index = $(this).attr('id').replace('selected_module', ""); | ||||
|             var is_module = $.isNumeric(module_index); | ||||
|             //console.log("name of module:", module_name, "index_of_module:", module_index, "is this a module: ", is_module); | ||||
|             if (document.getElementById(module_name) && is_module) { | ||||
|                 insert_config(module_index, module_name); | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     }); | ||||
| }); | ||||
| </script> | ||||
|  | ||||
|  | ||||
| <script> // validation | ||||
| (function() { | ||||
|   'use strict'; | ||||
|   window.addEventListener('load', function() { | ||||
|     var forms = document.getElementsByClassName('needs-validation'); | ||||
|     var validation = Array.prototype.filter.call(forms, function(form) { | ||||
|       form.addEventListener('submit', function(event) { | ||||
|         if (form.checkValidity() === false) { | ||||
|           event.preventDefault(); | ||||
|           event.stopPropagation(); | ||||
|         } | ||||
|         form.classList.add('was-validated'); | ||||
|       }, false); | ||||
|     }); | ||||
|   }, false); | ||||
| })(); | ||||
| </script> | ||||
|  | ||||
|  | ||||
| <div class="form-group"><br> | ||||
|     <button class="btn btn-primary btn-lg btn-block" type="submit">Generate settings file</button> | ||||
| </div> | ||||
|  | ||||
| </form> | ||||
|  | ||||
| </div> | ||||
| {% endblock %} | ||||
| @@ -7,7 +7,394 @@ | ||||
| <div class="container"> | ||||
|  | ||||
| <!-- heading --> | ||||
| <h3>Raspberry Pi Wifi setup (coming soon)</h3> | ||||
| <h3>Raspberry Pi Wifi setup</h3> | ||||
|  | ||||
| <!-- Instructions --> | ||||
| <div class="alert alert-primary" role="alert"> | ||||
|     <h4 class="alert-heading">Instructions</h4> | ||||
|     Insert your Wi-Fi network's details in the form below, then click on generate [wpa_supplicant.conf]<br> | ||||
|     If not done already, flash Raspberry Pi OS on a micro SD card and open the /boot folder on your computer<br> | ||||
|     Copy the wpa_supplicant.conf file in this folder, eject the microSD card, insert it in the Raspberry Pi and boot.<br> | ||||
|     Your Raspberry Pi should now be connected to the network you have entered on this page.<br> | ||||
|     <hr> | ||||
|     <p class="mb-0">Don't worry, none of your details are shared with anyone, this page does not send any data to anywhere.</p> | ||||
| </div> | ||||
|  | ||||
|  | ||||
| <form novalidate> | ||||
| <div class="form-group"> | ||||
|     <label for="country">Country</label> | ||||
|     <select class="form-control" id="country"> | ||||
|         <option value="AF">Afghanistan</option> | ||||
|         <option value="AX">Aland Islands</option> | ||||
|         <option value="AL">Albania</option> | ||||
|         <option value="DZ">Algeria</option> | ||||
|         <option value="AS">American Samoa</option> | ||||
|         <option value="AD">Andorra</option> | ||||
|         <option value="AO">Angola</option> | ||||
|         <option value="AI">Anguilla</option> | ||||
|         <option value="AQ">Antarctica</option> | ||||
|         <option value="AG">Antigua and Barbuda</option> | ||||
|         <option value="AR">Argentina</option> | ||||
|         <option value="AM">Armenia</option> | ||||
|         <option value="AW">Aruba</option> | ||||
|         <option value="AU">Australia</option> | ||||
|         <option value="AT">Austria</option> | ||||
|         <option value="AZ">Azerbaijan</option> | ||||
|  | ||||
|         <option value="BS">Bahamas</option> | ||||
|         <option value="BH">Bahrain</option> | ||||
|         <option value="BD">Bangladesh</option> | ||||
|         <option value="BB">Barbados</option> | ||||
|         <option value="BY">Belarus</option> | ||||
|         <option value="BE">Belgium</option> | ||||
|         <option value="BZ">Belize</option> | ||||
|         <option value="BJ">Benin</option> | ||||
|         <option value="BM">Bermuda</option> | ||||
|         <option value="BT">Bhutan</option> | ||||
|         <option value="BO">Bolivia</option> | ||||
|         <option value="BA">Bosnia and Herzegovina</option> | ||||
|         <option value="BW">Botswana</option> | ||||
|         <option value="BV">Bouvet Island</option> | ||||
|         <option value="BR">Brazil</option> | ||||
|         <option value="IO">British Indian Ocean Territory</option> | ||||
|         <option value="VG">British Virgin Islands</option> | ||||
|         <option value="BN">Brunei Darussalam</option> | ||||
|         <option value="BG">Bulgaria</option> | ||||
|         <option value="BF">Burkina Faso</option> | ||||
|         <option value="BI">Burundi</option> | ||||
|  | ||||
|         <option value="KH">Cambodia</option> | ||||
|         <option value="CM">Cameroon</option> | ||||
|         <option value="CA">Canada</option> | ||||
|         <option value="CV">Cape Verde</option> | ||||
|         <option value="KY">Cayman Islands</option> | ||||
|         <option value="CF">Central African Republic</option> | ||||
|         <option value="TD">Chad</option> | ||||
|         <option value="CL">Chile</option> | ||||
|         <option value="CN">China</option> | ||||
|         <option value="CX">Christmas Island</option> | ||||
|         <option value="CC">Cocos (Keeling) Islands</option> | ||||
|         <option value="CO">Colombia</option> | ||||
|         <option value="KM">Comoros</option> | ||||
|         <option value="CG">Congo(Brazzaville)</option> | ||||
|         <option value="CD">Congo, (Kinshasa)</option> | ||||
|         <option value="CK">Cook Islands</option> | ||||
|         <option value="CR">Costa Rica</option> | ||||
|         <option value="CI">Cote d\Ivoire</option> | ||||
|         <option value="HR">Croatia</option> | ||||
|         <option value="CU">Cuba</option> | ||||
|         <option value="CY">Cyprus</option> | ||||
|         <option value="CZ">Czech Republic</option> | ||||
|  | ||||
|         <option value="DK">Denmark</option> | ||||
|         <option value="DJ">Djibouti</option> | ||||
|         <option value="DM">Dominica</option> | ||||
|         <option value="DO">Dominican Republic</option> | ||||
|  | ||||
|         <option value="EC">Ecuador</option> | ||||
|         <option value="EG">Egypt</option> | ||||
|         <option value="SV">El Salvador</option> | ||||
|         <option value="GQ">Equatorial Guinea</option> | ||||
|         <option value="ER">Eritrea</option> | ||||
|         <option value="EE">Estonia</option> | ||||
|         <option value="ET">Ethiopia</option> | ||||
|  | ||||
|         <option value="FK">Falkland Islands (Malvinas)</option> | ||||
|         <option value="FO">Faroe Islands</option> | ||||
|         <option value="FJ">Fiji</option> | ||||
|         <option value="FI">Finland</option> | ||||
|         <option value="FR">France</option> | ||||
|         <option value="GF">French Guiana</option> | ||||
|         <option value="PF">French Polynesia</option> | ||||
|         <option value="TF">French Southern Territories</option> | ||||
|  | ||||
|         <option value="GA">Gabon</option> | ||||
|         <option value="GM">Gambia</option> | ||||
|         <option value="GE">Georgia</option> | ||||
|         <option value="DE" selected>Germany</option> | ||||
|         <option value="GH">Ghana</option> | ||||
|         <option value="GI">Gibraltar</option> | ||||
|         <option value="GR">Greece</option> | ||||
|         <option value="GL">Greenland</option> | ||||
|         <option value="GD">Grenada</option> | ||||
|         <option value="GP">Guadeloupe</option> | ||||
|         <option value="GU">Guam</option> | ||||
|         <option value="GT">Guatemala</option> | ||||
|         <option value="GG">Guernsey</option> | ||||
|         <option value="GN">Guinea</option> | ||||
|         <option value="GW">Guinea-Bissau</option> | ||||
|         <option value="GY">Guyana</option> | ||||
|  | ||||
|         <option value="HT">Haiti</option> | ||||
|         <option value="HM">Heard and Mcdonald Islands</option> | ||||
|         <option value="VA">Holy See(Vatican City State)</option> | ||||
|         <option value="HN">Honduras</option> | ||||
|         <option value="HK">Hong Kong, SAR China</option> | ||||
|         <option value="HU">Hungary</option> | ||||
|  | ||||
|         <option value="IS">Iceland</option> | ||||
|         <option value="IN">India</option> | ||||
|         <option value="ID">Indonesia</option> | ||||
|         <option value="IR">Iran, Islamic Republic of</option> | ||||
|         <option value="IQ">Iraq</option> | ||||
|         <option value="IE">Ireland</option> | ||||
|         <option value="IM">Isle of Man</option> | ||||
|         <option value="IL">Israel</option> | ||||
|         <option value="IT">Italy</option> | ||||
|  | ||||
|         <option value="JM">Jamaica</option> | ||||
|         <option value="JP">Japan</option> | ||||
|         <option value="JE">Jersey</option> | ||||
|         <option value="JO">Jordan</option> | ||||
|  | ||||
|         <option value="KZ">Kazakhstan</option> | ||||
|         <option value="KE">Kenya</option> | ||||
|         <option value="KI">Kiribati</option> | ||||
|         <option value="KP">Korea(North)</option> | ||||
|         <option value="KR">Korea(South)</option> | ||||
|         <option value="KW">Kuwait</option> | ||||
|         <option value="KG">Kyrgyzstan</option> | ||||
|  | ||||
|         <option value="LA">Lao PDR</option> | ||||
|         <option value="LV">Latvia</option> | ||||
|         <option value="LB">Lebanon</option> | ||||
|         <option value="LS">Lesotho</option> | ||||
|         <option value="LR">Liberia</option> | ||||
|         <option value="LY">Libya</option> | ||||
|         <option value="LI">Liechtenstein</option> | ||||
|         <option value="LT">Lithuania</option> | ||||
|         <option value="LU">Luxembourg</option> | ||||
|  | ||||
|         <option value="MO">Macao, SAR China</option> | ||||
|         <option value="MK">Macedonia, Republic of</option> | ||||
|         <option value="MG">Madagascar</option> | ||||
|         <option value="MW">Malawi</option> | ||||
|         <option value="MY">Malaysia</option> | ||||
|         <option value="MV">Maldives</option> | ||||
|         <option value="ML">Mali</option> | ||||
|         <option value="MT">Malta</option> | ||||
|         <option value="MH">Marshall Islands</option> | ||||
|         <option value="MQ">Martinique</option> | ||||
|         <option value="MR">Mauritania</option> | ||||
|         <option value="MU">Mauritius</option> | ||||
|         <option value="YT">Mayotte</option> | ||||
|         <option value="MX">Mexico</option> | ||||
|         <option value="FM">Micronesia, Federated States of</option> | ||||
|         <option value="MD">Moldova</option> | ||||
|         <option value="MC">Monaco</option> | ||||
|         <option value="MN">Mongolia</option> | ||||
|         <option value="ME">Montenegro</option> | ||||
|         <option value="MS">Montserrat</option> | ||||
|         <option value="MA">Morocco</option> | ||||
|         <option value="MZ">Mozambique</option> | ||||
|         <option value="MM">Myanmar</option> | ||||
|  | ||||
|         <option value="NA">Namibia</option> | ||||
|         <option value="NR">Nauru</option> | ||||
|         <option value="NP">Nepal</option> | ||||
|         <option value="NL">Netherlands</option> | ||||
|         <option value="AN">Netherlands Antilles</option> | ||||
|         <option value="NC">New Caledonia</option> | ||||
|         <option value="NZ">New Zealand</option> | ||||
|         <option value="NI">Nicaragua</option> | ||||
|         <option value="NE">Niger</option> | ||||
|         <option value="NG">Nigeria</option> | ||||
|         <option value="NU">Niue</option> | ||||
|         <option value="NF">Norfolk Island</option> | ||||
|         <option value="MP">Northern Mariana Islands</option> | ||||
|         <option value="NO">Norway</option> | ||||
|  | ||||
|         <option value="OM">Oman</option> | ||||
|  | ||||
|         <option value="PK">Pakistan</option> | ||||
|         <option value="PW">Palau</option> | ||||
|         <option value="PS">Palestinian Territory</option> | ||||
|         <option value="PA">Panama</option> | ||||
|         <option value="PG">Papua New Guinea</option> | ||||
|         <option value="PY">Paraguay</option> | ||||
|         <option value="PE">Peru</option> | ||||
|         <option value="PH">Philippines</option> | ||||
|         <option value="PN">Pitcairn</option> | ||||
|         <option value="PL">Poland</option> | ||||
|         <option value="PT">Portugal</option> | ||||
|         <option value="PR">Puerto Rico</option> | ||||
|  | ||||
|         <option value="QA">Qatar</option> | ||||
|  | ||||
|         <option value="RE">Réunion</option> | ||||
|         <option value="RO">Romania</option> | ||||
|         <option value="RU">Russian Federation</option> | ||||
|         <option value="RW">Rwanda</option> | ||||
|  | ||||
|         <option value="SH">Saint Helena</option> | ||||
|         <option value="KN">Saint Kitts and Nevis</option> | ||||
|         <option value="LC">Saint Lucia</option> | ||||
|         <option value="PM">Saint Pierre and Miquelon</option> | ||||
|         <option value="VC">Saint Vincent and Grenadines</option> | ||||
|         <option value="BL">Saint-Barthélemy</option> | ||||
|         <option value="MF">Saint-Martin (French part)</option> | ||||
|         <option value="WS">Samoa</option> | ||||
|         <option value="SM">San Marino</option> | ||||
|         <option value="ST">Sao Tome and Principe</option> | ||||
|         <option value="SA">Saudi Arabia</option> | ||||
|         <option value="SN">Senegal</option> | ||||
|         <option value="RS">Serbia</option> | ||||
|         <option value="SC">Seychelles</option> | ||||
|         <option value="SL">Sierra Leone</option> | ||||
|         <option value="SG">Singapore</option> | ||||
|         <option value="SK">Slovakia</option> | ||||
|         <option value="SI">Slovenia</option> | ||||
|         <option value="SB">Solomon Islands</option> | ||||
|         <option value="SO">Somalia</option> | ||||
|         <option value="ZA">South Africa</option> | ||||
|         <option value="GS">South Georgia and the South Sandwich Islands</option> | ||||
|         <option value="SS">South Sudan</option> | ||||
|         <option value="ES">Spain</option> | ||||
|         <option value="LK">Sri Lanka</option> | ||||
|         <option value="SD">Sudan</option> | ||||
|         <option value="SR">Suriname</option> | ||||
|         <option value="SJ">Svalbard and Jan Mayen Islands</option> | ||||
|         <option value="SZ">Swaziland</option> | ||||
|         <option value="SE">Sweden</option> | ||||
|         <option value="CH">Switzerland</option> | ||||
|         <option value="SY">Syrian Arab Republic (Syria)</option> | ||||
|  | ||||
|         <option value="TW">Taiwan, Republic of China</option> | ||||
|         <option value="TJ">Tajikistan</option> | ||||
|         <option value="TZ">Tanzania, United Republic of</option> | ||||
|         <option value="TH">Thailand</option> | ||||
|         <option value="TL">Timor-Leste</option> | ||||
|         <option value="TG">Togo</option> | ||||
|         <option value="TK">Tokelau</option> | ||||
|         <option value="TO">Tonga</option> | ||||
|         <option value="TT">Trinidad and Tobago</option> | ||||
|         <option value="TN">Tunisia</option> | ||||
|         <option value="TR">Turkey</option> | ||||
|         <option value="TM">Turkmenistan</option> | ||||
|         <option value="TC">Turks and Caicos Islands</option> | ||||
|         <option value="TV">Tuvalu</option> | ||||
|  | ||||
|         <option value="UG">Uganda</option> | ||||
|         <option value="UA">Ukraine</option> | ||||
|         <option value="AE">United Arab Emirates</option> | ||||
|         <option value="GB">United Kingdom</option> | ||||
|         <option value="US">United States of America</option> | ||||
|         <option value="UY">Uruguay</option> | ||||
|         <option value="UM">US Minor Outlying Islands</option> | ||||
|         <option value="UZ">Uzbekistan</option> | ||||
|  | ||||
|         <option value="VU">Vanuatu</option> | ||||
|         <option value="VE">Venezuela(Bolivarian Republic)</option> | ||||
|         <option value="VN">Viet Nam</option> | ||||
|         <option value="VI">Virgin Islands, US</option> | ||||
|  | ||||
|         <option value="WF">Wallis and Futuna Islands</option> | ||||
|         <option value="EH">Western Sahara</option> | ||||
|  | ||||
|         <option value="YE">Yemen</option> | ||||
|  | ||||
|         <option value="ZM">Zambia</option> | ||||
|         <option value="ZW">Zimbabwe</option> | ||||
|     </select> | ||||
| </div> | ||||
|  | ||||
|  | ||||
| <div class="form-group"> | ||||
|     <label for="security_type">Security Type</label> | ||||
|     <select class="form-control" id="security_type"> | ||||
|  | ||||
|         <option value="wpa_pass" selected>WPA/WPA2 (most common option)</option> | ||||
|         <option value="wpa">Open Network (no password)</option> | ||||
|         <option value="hidden_pass">Hidden SSID with password</option> | ||||
|         <option value="hidden">Hidden SSID (no password)</option> | ||||
|  | ||||
|     </select> | ||||
| </div> | ||||
|  | ||||
| <div class="form-group"> | ||||
|     <label for="ssid">SSID (Name of network)</label> | ||||
|     <input class="form-control" type="text" id="ssid"> | ||||
| </div> | ||||
|  | ||||
| <div class="form-group"> | ||||
|     <label for="password">password</label> | ||||
|     <input class="form-control" type="text" id="password"> | ||||
| </div> | ||||
|  | ||||
| <div class="form-group"> | ||||
|     <div class="card"> | ||||
|       <div class="card-body"> | ||||
|         <h5 class="card-title">Preview</h5> | ||||
|         <p class="card-text" id="wpa"></p> | ||||
|       </div> | ||||
|     </div> | ||||
| </div> | ||||
|  | ||||
|  | ||||
| <div class="form-group"> | ||||
|     <button type="button" class="btn btn-primary" onclick="getHTML('wpa_supplicant.conf', 'wpa', 'text/plain')">Download wpa_supplicant.conf</button> | ||||
| </div> | ||||
|  | ||||
| </form> | ||||
| </div> | ||||
|  | ||||
| <script> | ||||
| $(document).ready(function(){ | ||||
|  | ||||
|     $("#security_type").change(function(){ | ||||
|         var security_type = $("#security_type").val(); | ||||
|         //console.log('security_type', security_type); | ||||
|  | ||||
|     if (security_type=="wpa" || security_type=="hidden"){ | ||||
|         $("#password").replaceWith('<input class="form-control" type="text" id="password" readonly>') | ||||
|     } else { $("#password").replaceWith('<input class="form-control" type="text" id="password">') } | ||||
|     }); | ||||
|  | ||||
|     $('form').on('input', function(){ | ||||
|         var country = $("#country").val(); | ||||
|         var security_type = $("#security_type").val(); | ||||
|         var ssid =  ( $("#ssid").val() != null ) ?  $("#ssid").val().trim() : ""; | ||||
|         var password = ( $("#password").val() != null ) ? $("#password").val().trim() : ""; | ||||
|  | ||||
|         var wpa = [ | ||||
|         "country="+country, | ||||
|         "update_config=1", | ||||
|         "ctrl_interface=/var/run/wpa_supplicant", | ||||
|         "network={", | ||||
|         '    ssid="'+ssid+'"', | ||||
|         ]; | ||||
|  | ||||
|         if (security_type=="wpa"){ | ||||
|             wpa.push("    key_mgmt=NONE"); | ||||
|         } else if (security_type=="wpa_pass"){ | ||||
|             wpa.push('    psk="'+password+'"',"    key_mgmt=WPA-PSK") | ||||
|         } else if (security_type=="hidden"){ | ||||
|             wpa.push("    key_mgmt=NONE","    scan_ssid=1") | ||||
|         } else if (security_type=="hidden_pass"){ | ||||
|             wpa.push('    psk="'+password+'"', "    scan_ssid=1") | ||||
|         } | ||||
|         wpa.push("}"); | ||||
|         //console.log(wpa.join('\n')); | ||||
|  | ||||
|         document.getElementById("wpa").innerHTML = wpa.join("<br />").replaceAll('    ', '    '); | ||||
|     }); | ||||
|  | ||||
|     }).change(); | ||||
| </script> | ||||
|  | ||||
| <script> | ||||
| function getHTML(filename, id, mimeType) { | ||||
| var elHtml = document.getElementById(id).innerText; | ||||
| if (navigator.msSaveBlob) { | ||||
|   navigator.msSaveBlob(new Blob([elHtml], { type: mimeType + ';charset=utf-8;' }), filename); | ||||
| } else { | ||||
|     var link = document.createElement('a'); | ||||
|     mimeType = mimeType || 'text/plain'; | ||||
|     link.setAttribute('download', filename); | ||||
|     link.setAttribute('href', 'data:' + mimeType  +  ';charset=utf-8,' + encodeURIComponent(elHtml)); | ||||
|     link.click(); | ||||
| }} | ||||
| </script> | ||||
|  | ||||
| {% endblock %} | ||||
		Reference in New Issue
	
	Block a user