commit
a2a82f0490
3 changed files with 258 additions and 113 deletions
|
@ -1,3 +1,9 @@
|
|||
Version 0.1.6 (2017-03-28)
|
||||
- Executing commands on remote machine now possbile (Issue #30)
|
||||
- Using icons from https://materialdesignicons.com
|
||||
- Icon browser added
|
||||
- UI improvements
|
||||
|
||||
Version 0.1.5 (2017-02-28)
|
||||
- UI improvements
|
||||
- Added git init
|
||||
|
|
208
configurator.py
208
configurator.py
|
@ -13,6 +13,8 @@ import base64
|
|||
import ipaddress
|
||||
import signal
|
||||
import cgi
|
||||
import shlex
|
||||
import subprocess
|
||||
from string import Template
|
||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
import urllib.request
|
||||
|
@ -44,7 +46,7 @@ GIT = False
|
|||
### End of options
|
||||
|
||||
RELEASEURL = "https://api.github.com/repos/danielperna84/hass-poc-configurator/releases/latest"
|
||||
VERSION = "0.1.5"
|
||||
VERSION = "0.1.6"
|
||||
BASEDIR = "."
|
||||
DEV = False
|
||||
HTTPD = None
|
||||
|
@ -62,6 +64,7 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0" />
|
||||
<title>HASS Configurator</title>
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/MaterialDesign-Webfont/1.8.36/css/materialdesignicons.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/css/materialize.min.css">
|
||||
<style type="text/css" media="screen">
|
||||
body {
|
||||
|
@ -100,6 +103,14 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.select-wrapper input.select-dropdown {
|
||||
width: 96%;
|
||||
overflow: hidden;
|
||||
direction: ltr;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#edit_float {
|
||||
z-index: 10;
|
||||
}
|
||||
|
@ -273,7 +284,7 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
box-shadow: 0 1px 0 0 #03a9f4 !important
|
||||
}
|
||||
|
||||
#modal_acekeyboard, #modal_components {
|
||||
#modal_acekeyboard, #modal_components, #modal_icons {
|
||||
top: auto;
|
||||
width: 96%;
|
||||
min-height: 96%;
|
||||
|
@ -442,7 +453,7 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
|
||||
.fbmenuicon_pad {
|
||||
min-height: 64px;
|
||||
margin-top: 8px !important;
|
||||
margin-top: 6px !important;
|
||||
margin-right: 18px !important;
|
||||
color: #616161 !important;
|
||||
}
|
||||
|
@ -565,20 +576,26 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
<main>
|
||||
<ul id="dropdown_menu" class="dropdown-content z-depth-4">
|
||||
<li><a target="_blank" href="#modal_components">HASS Components</a></li>
|
||||
<li><a target="_blank" href="#modal_icons">Material Icons</a></li>
|
||||
<li><a href="#" data-activates="ace_settings" class="ace_settings-collapse">Editor Settings</a></li>
|
||||
<li><a href="#modal_about">About PoC</a></li>
|
||||
<li><a href="#modal_about">About HASS-Configurator</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#modal_check_config">Check HASS Configuration</a></li>
|
||||
<li><a href="#modal_restart">Restart HASS</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#modal_exec_command">Execute shell command</a></li>
|
||||
</ul>
|
||||
<ul id="dropdown_menu_mobile" class="dropdown-content z-depth-4">
|
||||
<li><a target="_blank" href="https://home-assistant.io/help/">Need HASS Help?</a></li>
|
||||
<li><a target="_blank" href="https://home-assistant.io/components/">HASS Components</a></li>
|
||||
<li><a target="_blank" href="https://materialdesignicons.com/">Material Icons</a></li>
|
||||
<li><a href="#" data-activates="ace_settings" class="ace_settings-collapse">Editor Settings</a></li>
|
||||
<li><a href="#modal_about">About PoC</a></li>
|
||||
<li><a href="#modal_about">About HASS-Configurator</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#modal_check_config">Check HASS Configuration</a></li>
|
||||
<li><a href="#modal_restart">Restart HASS</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#modal_exec_command">Execute shell command</a></li>
|
||||
</ul>
|
||||
<ul id="dropdown_gitmenu" class="dropdown-content z-depth-4">
|
||||
<li><a href="#modal_init" class="nowrap waves-effect">git init</a></li>
|
||||
|
@ -597,9 +614,18 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
<a class="modal-action modal-close waves-effect btn-flat Right light-blue-text">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_icons" class="modal bottom-sheet modal-fixed-footer">
|
||||
<div class="modal-content_nopad">
|
||||
<iframe src="https://materialdesignicons.com/" style="height: 90vh; width: 100vw"> </iframe>
|
||||
<a target="_blank" href="https://materialdesignicons.com/" class="hide-on-med-and-down modal_btn waves-effect btn-large btn-flat left"><i class="material-icons">launch</i></a>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class="modal-action modal-close waves-effect btn-flat Right light-blue-text">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_acekeyboard" class="modal bottom-sheet modal-fixed-footer">
|
||||
<div class="modal-content centered">
|
||||
<h4>Ace Keyboard Shortcuts</h4>
|
||||
<h4 class="grey-text text-darken-3">Ace Keyboard Shortcuts<i class="mdi mdi-keyboard right grey-text text-darken-3" style="font-size: 2rem;"></i></h4>
|
||||
<br>
|
||||
<ul class="collapsible popout" data-collapsible="expandable">
|
||||
<li>
|
||||
|
@ -1107,7 +1133,7 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
</div>
|
||||
<div id="modal_save" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Save</h4>
|
||||
<h4 class="grey-text text-darken-3">Save<i class="grey-text text-darken-3 material-icons right" style="font-size: 2rem;">save</i></h4>
|
||||
<p>Do you really want to save?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -1117,7 +1143,7 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
</div>
|
||||
<div id="modal_upload" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Upload File</h4>
|
||||
<h4 class="grey-text text-darken-3">Upload File<i class="grey-text text-darken-3 material-icons right" style="font-size: 2.28rem;">file_upload</i></h4>
|
||||
<p>Please choose a file to upload</p>
|
||||
<form action="#" id="uploadform">
|
||||
<div class="file-field input-field">
|
||||
|
@ -1138,14 +1164,7 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
</div>
|
||||
<div id="modal_init" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="row no-padding">
|
||||
<div class="col s11 no-padding">
|
||||
<h4>git init</h4>
|
||||
</div>
|
||||
<div class="col s1">
|
||||
<img src="https://image.flaticon.com/icons/svg/52/52234.svg" style="max-width: 40px;" >
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="grey-text text-darken-3">git init<i class="mdi mdi-git right grey-text text-darken-3" style="font-size: 2.48rem;"></i></h4>
|
||||
<p>Are you sure you want to initialize a repository at the current path?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -1155,14 +1174,7 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
</div>
|
||||
<div id="modal_commit" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="row no-padding">
|
||||
<div class="col s11 no-padding">
|
||||
<h4>git commit</h4>
|
||||
</div>
|
||||
<div class="col s1">
|
||||
<img src="https://image.flaticon.com/icons/svg/52/52234.svg" style="max-width: 40px;" >
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="grey-text text-darken-3">git commit<i class="mdi mdi-git right grey-text text-darken-3" style="font-size: 2.48rem;"></i></h4>
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
<input type="text" id="commitmessage">
|
||||
|
@ -1177,7 +1189,7 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
</div>
|
||||
<div id="modal_close" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Close File</h4>
|
||||
<h4 class="grey-text text-darken-3">Close File<i class="grey-text text-darken-3 material-icons right" style="font-size: 2.28rem;">close</i></h4>
|
||||
<p>Are you sure you want to close the current file? Unsaved changes will be lost.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -1187,7 +1199,7 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
</div>
|
||||
<div id="modal_delete" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Delete</h4>
|
||||
<h4 class="grey-text text-darken-3">Delete</h4>
|
||||
<p>Are you sure you want to delete <span class="fb_currentfile"></span>?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -1197,14 +1209,7 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
</div>
|
||||
<div id="modal_gitadd" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="row no-padding">
|
||||
<div class="col s11 no-padding">
|
||||
<h4>git add</h4>
|
||||
</div>
|
||||
<div class="col s1">
|
||||
<img src="https://image.flaticon.com/icons/svg/52/52234.svg" style="max-width: 40px;" >
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="grey-text text-darken-3">git add<i class="mdi mdi-git right grey-text text-darken-3" style="font-size: 2.48rem;"></i></h4>
|
||||
<p>Are you sure you want to add <span class="fb_currentfile"></span> to the index?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -1214,8 +1219,8 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
</div>
|
||||
<div id="modal_check_config" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Check configuration</h4>
|
||||
<p>Do you really want to check the configuration?</p>
|
||||
<h4 class="grey-text text-darken-3">Check configuration<i class="mdi mdi-settings right grey-text text-darken-3" style="font-size: 2rem;"></i></h4>
|
||||
<p>Do you want to check the configuration?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class=" modal-action modal-close waves-effect waves-red btn-flat light-blue-text">No</a>
|
||||
|
@ -1224,7 +1229,7 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
</div>
|
||||
<div id="modal_restart" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Restart</h4>
|
||||
<h4 class="grey-text text-darken-3">Restart<i class="mdi mdi-restart right grey-text text-darken-3" style="font-size: 2rem;"></i></h4>
|
||||
<p>Do you really want to restart Home Assistant?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -1232,9 +1237,27 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
<a onclick="restart()" class=" modal-action modal-close waves-effect waves-green btn-flat light-blue-text">Yes</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_exec_command" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4 class="grey-text text-darken-3">Execute shell command<i class="mdi mdi-laptop right grey-text text-darken-3" style="font-size: 2rem;"></i></h4>
|
||||
<pre class="col s6" id="command_history"></pre>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
<input placeholder="/bin/ls -l /var/log" id="commandline" type="text">
|
||||
<label for="commandline">Command</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class=" modal-action modal-close waves-effect waves-red btn-flat light-blue-text">Close</a>
|
||||
<a onclick="document.getElementById('command_history').innerText='';" class=" modal-action waves-effect waves-green btn-flat light-blue-text">Clear</a>
|
||||
<a onclick="exec_command()" class=" modal-action waves-effect waves-green btn-flat light-blue-text">Execute</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_markdirty" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Unsaved Changes</h4>
|
||||
<h4 class="grey-text text-darken-3">Unsaved Changes<i class="grey-text text-darken-3 material-icons right" style="font-size: 2rem;">save</i></h4>
|
||||
<p>You have unsaved changes in the current file. Please save the changes or close the file before opening a new one.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -1245,7 +1268,7 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
</div>
|
||||
<div id="modal_newfolder" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>New Folder</h4>
|
||||
<h4 class="grey-text text-darken-3">New Folder<i class="grey-text text-darken-3 material-icons right" style="font-size: 2rem;">create_new_folder</i></h4>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
|
@ -1261,7 +1284,7 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
</div>
|
||||
<div id="modal_newfile" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>New File</h4>
|
||||
<h4 class="grey-text text-darken-3">New File<i class="grey-text text-darken-3 material-icons right" style="font-size: 2rem;">note_add</i></h4>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
|
@ -1277,14 +1300,7 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
</div>
|
||||
<div id="modal_newbranch" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="row no-padding">
|
||||
<div class="col s11 no-padding">
|
||||
<h4>New Branch</h4>
|
||||
</div>
|
||||
<div class="col s1">
|
||||
<img src="https://image.flaticon.com/icons/svg/52/52234.svg" style="max-width: 40px;" >
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="grey-text text-darken-3">New Branch<i class="mdi mdi-git right grey-text text-darken-3" style="font-size: 2.48rem;"></i></h4>
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
<input type="text" id="newbranch">
|
||||
|
@ -1299,7 +1315,7 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
</div>
|
||||
<div id="modal_about" class="modal modal-fixed-footer">
|
||||
<div class="modal-content">
|
||||
<h4><a class="black-text" href="https://github.com/danielperna84/hass-poc-configurator/" target="_blank">HASS Configurator</a></h4>
|
||||
<h4 class="grey-text text-darken-3"><a class="black-text" href="https://github.com/danielperna84/hass-poc-configurator/" target="_blank">HASS Configurator</a></h4>
|
||||
<p>Version: <a class="$versionclass" href="https://github.com/danielperna84/hass-poc-configurator/releases/lafbicon_pad" target="_blank">$current</a></p>
|
||||
<p>Web-based file editor designed to modify configuration files of <a class="light-blue-text" href="https://home-assistant.io/" target="_blank">Home Assistant</a> or other textual files. Use at your own risk.</p>
|
||||
<p>Published under the MIT license</p>
|
||||
|
@ -1333,7 +1349,7 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
<img src="https://evwilkin.github.io/images/materializecss.png">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<p class="grey-text text-darken-2">Materialize CSS</p>
|
||||
<p class="grey-text text-darken-2">Materialize</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
@ -1438,13 +1454,13 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
<a class="col s3 waves-effect fbtoolbarbutton tooltipped" href="#modal_newfile" data-position="bottom" data-delay="500" data-tooltip="New File"><i class="grey-text text-darken-2 material-icons fbtoolbarbutton_icon">note_add</i></a>
|
||||
<a class="col s3 waves-effect fbtoolbarbutton tooltipped" href="#modal_newfolder" data-position="bottom" data-delay="500" data-tooltip="New Folder"><i class="grey-text text-darken-2 material-icons fbtoolbarbutton_icon">create_new_folder</i></a>
|
||||
<a class="col s3 waves-effect fbtoolbarbutton tooltipped" href="#modal_upload" data-position="bottom" data-delay="500" data-tooltip="Upload File"><i class="grey-text text-darken-2 material-icons fbtoolbarbutton_icon">file_upload</i></a>
|
||||
<a class="col s3 waves-effect fbtoolbarbutton tooltipped dropdown-button" data-activates="dropdown_gitmenu" data-alignment='right' data-beloworigin='true' data-delay='500' data-position="bottom" data-tooltip="Git"><i class="grey-text text-darken-2 material-icons fbtoolbarbutton_icon">call_split</i></a>
|
||||
<a class="col s3 waves-effect fbtoolbarbutton tooltipped dropdown-button" data-activates="dropdown_gitmenu" data-alignment='right' data-beloworigin='true' data-delay='500' data-position="bottom" data-tooltip="Git"><i class="mdi mdi-git grey-text text-darken-2 material-icons" style="padding-top: 17px;"></i></a>
|
||||
</ul>
|
||||
<ul class="row center toolbar_mobile hide-on-med-and-up grey lighten-4" style="margin-bottom: 0;">
|
||||
<a class="col s3 waves-effect fbtoolbarbutton" href="#modal_newfile"><i class="grey-text text-darken-2 material-icons fbtoolbarbutton_icon">note_add</i></a>
|
||||
<a class="col s3 waves-effect fbtoolbarbutton" href="#modal_newfolder"><i class="grey-text text-darken-2 material-icons fbtoolbarbutton_icon">create_new_folder</i></a>
|
||||
<a class="col s3 waves-effect fbtoolbarbutton" href="#modal_upload"><i class="grey-text text-darken-2 material-icons fbtoolbarbutton_icon">file_upload</i></a>
|
||||
<a class="col s3 waves-effect fbtoolbarbutton dropdown-button" data-activates="dropdown_gitmenu_mobile" data-alignment='right' data-beloworigin='true'><i class="grey-text text-darken-2 material-icons fbtoolbarbutton_icon">call_split</i></a>
|
||||
<a class="col s3 waves-effect fbtoolbarbutton dropdown-button" data-activates="dropdown_gitmenu_mobile" data-alignment='right' data-beloworigin='true'><i class="mdi mdi-git grey-text text-darken-2 material-icons" style="padding-top: 17px;"></i></a>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
|
@ -1986,19 +2002,25 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
nameparts = itemdata.name.split('.');
|
||||
extension = nameparts[nameparts.length -1];
|
||||
if (['c', 'cpp', 'css', 'htm', 'html', 'js', 'json', 'php', 'py', 'sh', 'sql', 'xml', 'yaml'].indexOf(extension.toLocaleLowerCase()) > +1 ) {
|
||||
iicon.innerHTML = 'code';
|
||||
iicon.classList.add('mdi', 'mdi-file-xml');
|
||||
}
|
||||
else if (['txt', 'doc', 'docx'].indexOf(extension.toLocaleLowerCase()) > -1 ) {
|
||||
iicon.classList.add('mdi', 'mdi-file-document');
|
||||
}
|
||||
else if (['bmp', 'gif', 'jpg', 'jpeg', 'png', 'tif', 'webp'].indexOf(extension.toLocaleLowerCase()) > -1 ) {
|
||||
iicon.innerHTML = 'image';
|
||||
iicon.classList.add('mdi', 'mdi-file-image');
|
||||
}
|
||||
else if (['mp3', 'ogg', 'wav'].indexOf(extension) > -1 ) {
|
||||
iicon.innerHTML = 'audiotrack';
|
||||
iicon.classList.add('mdi', 'mdi-file-music');
|
||||
}
|
||||
else if (['avi', 'flv', 'mkv', 'mp4', 'mpg', 'mpeg', 'webm'].indexOf(extension.toLocaleLowerCase()) > -1 ) {
|
||||
iicon.innerHTML = 'video_label';
|
||||
iicon.classList.add('mdi', 'mdi-file-video');
|
||||
}
|
||||
else if (['pdf'].indexOf(extension.toLocaleLowerCase()) > -1 ) {
|
||||
iicon.classList.add('mdi', 'mdi-file-pdf');
|
||||
}
|
||||
else {
|
||||
iicon.innerHTML = 'insert_drive_file';
|
||||
iicon.classList.add('mdi', 'mdi-file');
|
||||
}
|
||||
item.setAttribute("onclick", "loadfile('" + encodeURI(itemdata.fullpath) + "')");
|
||||
stats.innerHTML = "Mod.: " + date.toUTCString() + " Size: " + (itemdata.size/1024).toFixed(1) + " KiB";
|
||||
|
@ -2265,6 +2287,31 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
}
|
||||
}
|
||||
|
||||
function exec_command() {
|
||||
var command = document.getElementById('commandline').value;
|
||||
if (command.length > 0) {
|
||||
data = new Object();
|
||||
data.command = command;
|
||||
data.timeout = 15;
|
||||
$.post("api/exec_command", data).done(function(resp) {
|
||||
if (resp.error) {
|
||||
var $toastContent = $("<div><pre>" + resp.message + "</pre></div>");
|
||||
Materialize.toast($toastContent, 5000);
|
||||
}
|
||||
else {
|
||||
var history = document.getElementById('command_history');
|
||||
history.innerText += resp.message + ': ' + resp.returncode + "\n";
|
||||
if (resp.stdout) {
|
||||
history.innerText += resp.stdout;
|
||||
}
|
||||
if (resp.stderr) {
|
||||
history.innerText += resp.stderr;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function delete_element() {
|
||||
var path = document.getElementById('fb_currentfile').value;
|
||||
if (path.length > 0) {
|
||||
|
@ -2945,6 +2992,53 @@ class RequestHandler(BaseHTTPRequestHandler):
|
|||
print(err)
|
||||
else:
|
||||
response['message'] = "Missing filename or text"
|
||||
elif req.path == '/api/exec_command':
|
||||
try:
|
||||
postvars = parse_qs(self.rfile.read(length).decode('utf-8'), keep_blank_values=1)
|
||||
except Exception as err:
|
||||
print(err)
|
||||
response['message'] = "%s" % (str(err))
|
||||
postvars = {}
|
||||
if 'command' in postvars.keys():
|
||||
if postvars['command']:
|
||||
try:
|
||||
command = shlex.split(postvars['command'][0])
|
||||
timeout = 15
|
||||
if 'timeout' in postvars.keys():
|
||||
if postvars['timeout']:
|
||||
timeout = int(postvars['timeout'][0])
|
||||
try:
|
||||
proc = subprocess.Popen(
|
||||
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
stdout, stderr = proc.communicate(timeout=timeout)
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'text/json')
|
||||
self.end_headers()
|
||||
response['error'] = False
|
||||
response['message'] = "Command executed: %s" % postvars['command'][0]
|
||||
response['returncode'] = proc.returncode
|
||||
try:
|
||||
response['stdout'] = stdout.decode(sys.getdefaultencoding())
|
||||
except Exception as err:
|
||||
print(err)
|
||||
response['stdout'] = stdout.decode("utf-8", errors="replace")
|
||||
try:
|
||||
response['stderr'] = stderr.decode(sys.getdefaultencoding())
|
||||
except Exception as err:
|
||||
print(err)
|
||||
response['stderr'] = stderr.decode("utf-8", errors="replace")
|
||||
self.wfile.write(bytes(json.dumps(response), "utf8"))
|
||||
return
|
||||
except Exception as err:
|
||||
print(err)
|
||||
response['error'] = True
|
||||
response['message'] = str(err)
|
||||
|
||||
except Exception as err:
|
||||
response['message'] = "%s" % (str(err))
|
||||
print(err)
|
||||
else:
|
||||
response['message'] = "Missing command"
|
||||
elif req.path == '/api/gitadd':
|
||||
try:
|
||||
postvars = parse_qs(self.rfile.read(length).decode('utf-8'), keep_blank_values=1)
|
||||
|
|
157
dev.html
157
dev.html
|
@ -5,6 +5,7 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0" />
|
||||
<title>HASS Configurator</title>
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/MaterialDesign-Webfont/1.8.36/css/materialdesignicons.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/css/materialize.min.css">
|
||||
<style type="text/css" media="screen">
|
||||
body {
|
||||
|
@ -43,6 +44,14 @@
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.select-wrapper input.select-dropdown {
|
||||
width: 96%;
|
||||
overflow: hidden;
|
||||
direction: ltr;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#edit_float {
|
||||
z-index: 10;
|
||||
}
|
||||
|
@ -216,7 +225,7 @@
|
|||
box-shadow: 0 1px 0 0 #03a9f4 !important
|
||||
}
|
||||
|
||||
#modal_acekeyboard, #modal_components {
|
||||
#modal_acekeyboard, #modal_components, #modal_icons {
|
||||
top: auto;
|
||||
width: 96%;
|
||||
min-height: 96%;
|
||||
|
@ -385,7 +394,7 @@
|
|||
|
||||
.fbmenuicon_pad {
|
||||
min-height: 64px;
|
||||
margin-top: 8px !important;
|
||||
margin-top: 6px !important;
|
||||
margin-right: 18px !important;
|
||||
color: #616161 !important;
|
||||
}
|
||||
|
@ -508,20 +517,26 @@
|
|||
<main>
|
||||
<ul id="dropdown_menu" class="dropdown-content z-depth-4">
|
||||
<li><a target="_blank" href="#modal_components">HASS Components</a></li>
|
||||
<li><a target="_blank" href="#modal_icons">Material Icons</a></li>
|
||||
<li><a href="#" data-activates="ace_settings" class="ace_settings-collapse">Editor Settings</a></li>
|
||||
<li><a href="#modal_about">About PoC</a></li>
|
||||
<li><a href="#modal_about">About HASS-Configurator</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#modal_check_config">Check HASS Configuration</a></li>
|
||||
<li><a href="#modal_restart">Restart HASS</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#modal_exec_command">Execute shell command</a></li>
|
||||
</ul>
|
||||
<ul id="dropdown_menu_mobile" class="dropdown-content z-depth-4">
|
||||
<li><a target="_blank" href="https://home-assistant.io/help/">Need HASS Help?</a></li>
|
||||
<li><a target="_blank" href="https://home-assistant.io/components/">HASS Components</a></li>
|
||||
<li><a target="_blank" href="https://materialdesignicons.com/">Material Icons</a></li>
|
||||
<li><a href="#" data-activates="ace_settings" class="ace_settings-collapse">Editor Settings</a></li>
|
||||
<li><a href="#modal_about">About PoC</a></li>
|
||||
<li><a href="#modal_about">About HASS-Configurator</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#modal_check_config">Check HASS Configuration</a></li>
|
||||
<li><a href="#modal_restart">Restart HASS</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#modal_exec_command">Execute shell command</a></li>
|
||||
</ul>
|
||||
<ul id="dropdown_gitmenu" class="dropdown-content z-depth-4">
|
||||
<li><a href="#modal_init" class="nowrap waves-effect">git init</a></li>
|
||||
|
@ -540,9 +555,18 @@
|
|||
<a class="modal-action modal-close waves-effect btn-flat Right light-blue-text">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_icons" class="modal bottom-sheet modal-fixed-footer">
|
||||
<div class="modal-content_nopad">
|
||||
<iframe src="https://materialdesignicons.com/" style="height: 90vh; width: 100vw"> </iframe>
|
||||
<a target="_blank" href="https://materialdesignicons.com/" class="hide-on-med-and-down modal_btn waves-effect btn-large btn-flat left"><i class="material-icons">launch</i></a>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class="modal-action modal-close waves-effect btn-flat Right light-blue-text">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_acekeyboard" class="modal bottom-sheet modal-fixed-footer">
|
||||
<div class="modal-content centered">
|
||||
<h4>Ace Keyboard Shortcuts</h4>
|
||||
<h4 class="grey-text text-darken-3">Ace Keyboard Shortcuts<i class="mdi mdi-keyboard right grey-text text-darken-3" style="font-size: 2rem;"></i></h4>
|
||||
<br>
|
||||
<ul class="collapsible popout" data-collapsible="expandable">
|
||||
<li>
|
||||
|
@ -1050,7 +1074,7 @@
|
|||
</div>
|
||||
<div id="modal_save" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Save</h4>
|
||||
<h4 class="grey-text text-darken-3">Save<i class="grey-text text-darken-3 material-icons right" style="font-size: 2rem;">save</i></h4>
|
||||
<p>Do you really want to save?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -1060,7 +1084,7 @@
|
|||
</div>
|
||||
<div id="modal_upload" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Upload File</h4>
|
||||
<h4 class="grey-text text-darken-3">Upload File<i class="grey-text text-darken-3 material-icons right" style="font-size: 2.28rem;">file_upload</i></h4>
|
||||
<p>Please choose a file to upload</p>
|
||||
<form action="#" id="uploadform">
|
||||
<div class="file-field input-field">
|
||||
|
@ -1081,14 +1105,7 @@
|
|||
</div>
|
||||
<div id="modal_init" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="row no-padding">
|
||||
<div class="col s11 no-padding">
|
||||
<h4>git init</h4>
|
||||
</div>
|
||||
<div class="col s1">
|
||||
<img src="https://image.flaticon.com/icons/svg/52/52234.svg" style="max-width: 40px;" >
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="grey-text text-darken-3">git init<i class="mdi mdi-git right grey-text text-darken-3" style="font-size: 2.48rem;"></i></h4>
|
||||
<p>Are you sure you want to initialize a repository at the current path?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -1098,14 +1115,7 @@
|
|||
</div>
|
||||
<div id="modal_commit" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="row no-padding">
|
||||
<div class="col s11 no-padding">
|
||||
<h4>git commit</h4>
|
||||
</div>
|
||||
<div class="col s1">
|
||||
<img src="https://image.flaticon.com/icons/svg/52/52234.svg" style="max-width: 40px;" >
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="grey-text text-darken-3">git commit<i class="mdi mdi-git right grey-text text-darken-3" style="font-size: 2.48rem;"></i></h4>
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
<input type="text" id="commitmessage">
|
||||
|
@ -1120,7 +1130,7 @@
|
|||
</div>
|
||||
<div id="modal_close" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Close File</h4>
|
||||
<h4 class="grey-text text-darken-3">Close File<i class="grey-text text-darken-3 material-icons right" style="font-size: 2.28rem;">close</i></h4>
|
||||
<p>Are you sure you want to close the current file? Unsaved changes will be lost.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -1130,7 +1140,7 @@
|
|||
</div>
|
||||
<div id="modal_delete" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Delete</h4>
|
||||
<h4 class="grey-text text-darken-3">Delete</h4>
|
||||
<p>Are you sure you want to delete <span class="fb_currentfile"></span>?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -1140,14 +1150,7 @@
|
|||
</div>
|
||||
<div id="modal_gitadd" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="row no-padding">
|
||||
<div class="col s11 no-padding">
|
||||
<h4>git add</h4>
|
||||
</div>
|
||||
<div class="col s1">
|
||||
<img src="https://image.flaticon.com/icons/svg/52/52234.svg" style="max-width: 40px;" >
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="grey-text text-darken-3">git add<i class="mdi mdi-git right grey-text text-darken-3" style="font-size: 2.48rem;"></i></h4>
|
||||
<p>Are you sure you want to add <span class="fb_currentfile"></span> to the index?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -1157,8 +1160,8 @@
|
|||
</div>
|
||||
<div id="modal_check_config" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Check configuration</h4>
|
||||
<p>Do you really want to check the configuration?</p>
|
||||
<h4 class="grey-text text-darken-3">Check configuration<i class="mdi mdi-settings right grey-text text-darken-3" style="font-size: 2rem;"></i></h4>
|
||||
<p>Do you want to check the configuration?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class=" modal-action modal-close waves-effect waves-red btn-flat light-blue-text">No</a>
|
||||
|
@ -1167,7 +1170,7 @@
|
|||
</div>
|
||||
<div id="modal_restart" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Restart</h4>
|
||||
<h4 class="grey-text text-darken-3">Restart<i class="mdi mdi-restart right grey-text text-darken-3" style="font-size: 2rem;"></i></h4>
|
||||
<p>Do you really want to restart Home Assistant?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -1175,9 +1178,27 @@
|
|||
<a onclick="restart()" class=" modal-action modal-close waves-effect waves-green btn-flat light-blue-text">Yes</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_exec_command" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4 class="grey-text text-darken-3">Execute shell command<i class="mdi mdi-laptop right grey-text text-darken-3" style="font-size: 2rem;"></i></h4>
|
||||
<pre class="col s6" id="command_history"></pre>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
<input placeholder="/bin/ls -l /var/log" id="commandline" type="text">
|
||||
<label for="commandline">Command</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class=" modal-action modal-close waves-effect waves-red btn-flat light-blue-text">Close</a>
|
||||
<a onclick="document.getElementById('command_history').innerText='';" class=" modal-action waves-effect waves-green btn-flat light-blue-text">Clear</a>
|
||||
<a onclick="exec_command()" class=" modal-action waves-effect waves-green btn-flat light-blue-text">Execute</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_markdirty" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Unsaved Changes</h4>
|
||||
<h4 class="grey-text text-darken-3">Unsaved Changes<i class="grey-text text-darken-3 material-icons right" style="font-size: 2rem;">save</i></h4>
|
||||
<p>You have unsaved changes in the current file. Please save the changes or close the file before opening a new one.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -1188,7 +1209,7 @@
|
|||
</div>
|
||||
<div id="modal_newfolder" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>New Folder</h4>
|
||||
<h4 class="grey-text text-darken-3">New Folder<i class="grey-text text-darken-3 material-icons right" style="font-size: 2rem;">create_new_folder</i></h4>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
|
@ -1204,7 +1225,7 @@
|
|||
</div>
|
||||
<div id="modal_newfile" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>New File</h4>
|
||||
<h4 class="grey-text text-darken-3">New File<i class="grey-text text-darken-3 material-icons right" style="font-size: 2rem;">note_add</i></h4>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
|
@ -1220,14 +1241,7 @@
|
|||
</div>
|
||||
<div id="modal_newbranch" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="row no-padding">
|
||||
<div class="col s11 no-padding">
|
||||
<h4>New Branch</h4>
|
||||
</div>
|
||||
<div class="col s1">
|
||||
<img src="https://image.flaticon.com/icons/svg/52/52234.svg" style="max-width: 40px;" >
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="grey-text text-darken-3">New Branch<i class="mdi mdi-git right grey-text text-darken-3" style="font-size: 2.48rem;"></i></h4>
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
<input type="text" id="newbranch">
|
||||
|
@ -1242,7 +1256,7 @@
|
|||
</div>
|
||||
<div id="modal_about" class="modal modal-fixed-footer">
|
||||
<div class="modal-content">
|
||||
<h4><a class="black-text" href="https://github.com/danielperna84/hass-poc-configurator/" target="_blank">HASS Configurator</a></h4>
|
||||
<h4 class="grey-text text-darken-3"><a class="black-text" href="https://github.com/danielperna84/hass-poc-configurator/" target="_blank">HASS Configurator</a></h4>
|
||||
<p>Version: <a class="$versionclass" href="https://github.com/danielperna84/hass-poc-configurator/releases/lafbicon_pad" target="_blank">$current</a></p>
|
||||
<p>Web-based file editor designed to modify configuration files of <a class="light-blue-text" href="https://home-assistant.io/" target="_blank">Home Assistant</a> or other textual files. Use at your own risk.</p>
|
||||
<p>Published under the MIT license</p>
|
||||
|
@ -1276,7 +1290,7 @@
|
|||
<img src="https://evwilkin.github.io/images/materializecss.png">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<p class="grey-text text-darken-2">Materialize CSS</p>
|
||||
<p class="grey-text text-darken-2">Materialize</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
@ -1381,13 +1395,13 @@
|
|||
<a class="col s3 waves-effect fbtoolbarbutton tooltipped" href="#modal_newfile" data-position="bottom" data-delay="500" data-tooltip="New File"><i class="grey-text text-darken-2 material-icons fbtoolbarbutton_icon">note_add</i></a>
|
||||
<a class="col s3 waves-effect fbtoolbarbutton tooltipped" href="#modal_newfolder" data-position="bottom" data-delay="500" data-tooltip="New Folder"><i class="grey-text text-darken-2 material-icons fbtoolbarbutton_icon">create_new_folder</i></a>
|
||||
<a class="col s3 waves-effect fbtoolbarbutton tooltipped" href="#modal_upload" data-position="bottom" data-delay="500" data-tooltip="Upload File"><i class="grey-text text-darken-2 material-icons fbtoolbarbutton_icon">file_upload</i></a>
|
||||
<a class="col s3 waves-effect fbtoolbarbutton tooltipped dropdown-button" data-activates="dropdown_gitmenu" data-alignment='right' data-beloworigin='true' data-delay='500' data-position="bottom" data-tooltip="Git"><i class="grey-text text-darken-2 material-icons fbtoolbarbutton_icon">call_split</i></a>
|
||||
<a class="col s3 waves-effect fbtoolbarbutton tooltipped dropdown-button" data-activates="dropdown_gitmenu" data-alignment='right' data-beloworigin='true' data-delay='500' data-position="bottom" data-tooltip="Git"><i class="mdi mdi-git grey-text text-darken-2 material-icons" style="padding-top: 17px;"></i></a>
|
||||
</ul>
|
||||
<ul class="row center toolbar_mobile hide-on-med-and-up grey lighten-4" style="margin-bottom: 0;">
|
||||
<a class="col s3 waves-effect fbtoolbarbutton" href="#modal_newfile"><i class="grey-text text-darken-2 material-icons fbtoolbarbutton_icon">note_add</i></a>
|
||||
<a class="col s3 waves-effect fbtoolbarbutton" href="#modal_newfolder"><i class="grey-text text-darken-2 material-icons fbtoolbarbutton_icon">create_new_folder</i></a>
|
||||
<a class="col s3 waves-effect fbtoolbarbutton" href="#modal_upload"><i class="grey-text text-darken-2 material-icons fbtoolbarbutton_icon">file_upload</i></a>
|
||||
<a class="col s3 waves-effect fbtoolbarbutton dropdown-button" data-activates="dropdown_gitmenu_mobile" data-alignment='right' data-beloworigin='true'><i class="grey-text text-darken-2 material-icons fbtoolbarbutton_icon">call_split</i></a>
|
||||
<a class="col s3 waves-effect fbtoolbarbutton dropdown-button" data-activates="dropdown_gitmenu_mobile" data-alignment='right' data-beloworigin='true'><i class="mdi mdi-git grey-text text-darken-2 material-icons" style="padding-top: 17px;"></i></a>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
|
@ -1929,19 +1943,25 @@
|
|||
nameparts = itemdata.name.split('.');
|
||||
extension = nameparts[nameparts.length -1];
|
||||
if (['c', 'cpp', 'css', 'htm', 'html', 'js', 'json', 'php', 'py', 'sh', 'sql', 'xml', 'yaml'].indexOf(extension.toLocaleLowerCase()) > +1 ) {
|
||||
iicon.innerHTML = 'code';
|
||||
iicon.classList.add('mdi', 'mdi-file-xml');
|
||||
}
|
||||
else if (['txt', 'doc', 'docx'].indexOf(extension.toLocaleLowerCase()) > -1 ) {
|
||||
iicon.classList.add('mdi', 'mdi-file-document');
|
||||
}
|
||||
else if (['bmp', 'gif', 'jpg', 'jpeg', 'png', 'tif', 'webp'].indexOf(extension.toLocaleLowerCase()) > -1 ) {
|
||||
iicon.innerHTML = 'image';
|
||||
iicon.classList.add('mdi', 'mdi-file-image');
|
||||
}
|
||||
else if (['mp3', 'ogg', 'wav'].indexOf(extension) > -1 ) {
|
||||
iicon.innerHTML = 'audiotrack';
|
||||
iicon.classList.add('mdi', 'mdi-file-music');
|
||||
}
|
||||
else if (['avi', 'flv', 'mkv', 'mp4', 'mpg', 'mpeg', 'webm'].indexOf(extension.toLocaleLowerCase()) > -1 ) {
|
||||
iicon.innerHTML = 'video_label';
|
||||
iicon.classList.add('mdi', 'mdi-file-video');
|
||||
}
|
||||
else if (['pdf'].indexOf(extension.toLocaleLowerCase()) > -1 ) {
|
||||
iicon.classList.add('mdi', 'mdi-file-pdf');
|
||||
}
|
||||
else {
|
||||
iicon.innerHTML = 'insert_drive_file';
|
||||
iicon.classList.add('mdi', 'mdi-file');
|
||||
}
|
||||
item.setAttribute("onclick", "loadfile('" + encodeURI(itemdata.fullpath) + "')");
|
||||
stats.innerHTML = "Mod.: " + date.toUTCString() + " Size: " + (itemdata.size/1024).toFixed(1) + " KiB";
|
||||
|
@ -2208,6 +2228,31 @@
|
|||
}
|
||||
}
|
||||
|
||||
function exec_command() {
|
||||
var command = document.getElementById('commandline').value;
|
||||
if (command.length > 0) {
|
||||
data = new Object();
|
||||
data.command = command;
|
||||
data.timeout = 15;
|
||||
$.post("api/exec_command", data).done(function(resp) {
|
||||
if (resp.error) {
|
||||
var $toastContent = $("<div><pre>" + resp.message + "</pre></div>");
|
||||
Materialize.toast($toastContent, 5000);
|
||||
}
|
||||
else {
|
||||
var history = document.getElementById('command_history');
|
||||
history.innerText += resp.message + ': ' + resp.returncode + "\n";
|
||||
if (resp.stdout) {
|
||||
history.innerText += resp.stdout;
|
||||
}
|
||||
if (resp.stderr) {
|
||||
history.innerText += resp.stderr;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function delete_element() {
|
||||
var path = document.getElementById('fb_currentfile').value;
|
||||
if (path.length > 0) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue