Merge pull request #33 from danielperna84/dev

Changes for 0.1.6
This commit is contained in:
Daniel Perna 2017-03-28 20:02:26 +02:00 committed by GitHub
commit a2a82f0490
3 changed files with 258 additions and 113 deletions

View file

@ -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

View file

@ -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() + "&nbsp;&nbsp;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
View file

@ -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() + "&nbsp;&nbsp;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) {