mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-09 21:17:18 +03:00
system config UI work in progress
This commit is contained in:
@@ -32,6 +32,20 @@ var task_state_t = {
|
||||
4 : "eDeleted"
|
||||
|
||||
}
|
||||
var escapeHTML = function(unsafe) {
|
||||
return unsafe.replace(/[&<"']/g, function(m) {
|
||||
switch (m) {
|
||||
case '&':
|
||||
return '&';
|
||||
case '<':
|
||||
return '<';
|
||||
case '"':
|
||||
return '"';
|
||||
default:
|
||||
return ''';
|
||||
}
|
||||
});
|
||||
};
|
||||
var releaseURL = 'https://api.github.com/repos/sle118/squeezelite-esp32/releases';
|
||||
var recovery = false;
|
||||
var enableAPTimer = true;
|
||||
@@ -737,7 +751,7 @@ function getMessages() {
|
||||
$("#syslogTable").append(
|
||||
"<tr class='"+msg["type"]+"'>"+
|
||||
"<td>"+msg_time.toLocaleString()+"</td>"+
|
||||
"<td>"+msg["message"]+"</td>"+
|
||||
"<td>"+escapeHTML(msg["message"]).replace(/\n/g, '<br />')+"</td>"+
|
||||
"</tr>"
|
||||
);
|
||||
break;
|
||||
@@ -921,15 +935,124 @@ function checkStatus(){
|
||||
blockAjax = false;
|
||||
});
|
||||
}
|
||||
function runCommand(button) {
|
||||
pardiv = button.parentNode.parentNode;
|
||||
fields=document.getElementById("flds-"+button.value);
|
||||
cmdstring=button.value+' ';
|
||||
if(fields){
|
||||
hint = pardiv.hint;
|
||||
allfields=fields.getElementsByTagName("input");
|
||||
for (i = 0; i < allfields.length; i++) {
|
||||
attr=allfields[i].attributes;
|
||||
qts='';
|
||||
opt='';
|
||||
optspacer=' ';
|
||||
|
||||
if (attr.longopts.value!== "undefined"){
|
||||
opt+= '--' + attr.longopts.value;
|
||||
optspacer='=';
|
||||
}
|
||||
else if(attr.shortopts.value!== "undefined"){
|
||||
opt= '-' + attr.shortopts.value;
|
||||
}
|
||||
|
||||
if(attr.hasvalue.value== "true" ){
|
||||
if(allfields[i].value!=''){
|
||||
qts = (/\s/.test(allfields[i].value))?'"':'';
|
||||
cmdstring+=opt+optspacer+qts +allfields[i].value +qts+ ' ';
|
||||
}
|
||||
}
|
||||
else {
|
||||
// this is a checkbox
|
||||
if(allfields[i].checked) cmdstring+=opt+ ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(cmdstring);
|
||||
|
||||
var data = { 'timestamp': Date.now() };
|
||||
data['command'] = cmdstring;
|
||||
|
||||
$.ajax({
|
||||
url: '/commands.json',
|
||||
dataType: 'text',
|
||||
method: 'POST',
|
||||
cache: false,
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
data: JSON.stringify(data),
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(xhr.status);
|
||||
console.log(thrownError);
|
||||
if (thrownError != '') showMessage(thrownError, 'MESSAGING_ERROR');
|
||||
}
|
||||
});
|
||||
enableStatusTimer = true;
|
||||
}
|
||||
|
||||
|
||||
function getCommands() {
|
||||
$.getJSON("/commands.json", function(data) {
|
||||
console.log(data);
|
||||
innerhtml='';
|
||||
|
||||
data.commands.forEach(function(command) {
|
||||
innerhtml+='<tr><td>';
|
||||
innerhtml+=escapeHTML(command.help).replace(/\n/g, '<br />')+'<br>';
|
||||
innerhtml+='<div >';
|
||||
if(command.hasOwnProperty("argtable")){
|
||||
innerhtml+='<table class="table table-hover" id="flds-'+command.name+'"><tbody>';
|
||||
command.argtable.forEach(function (arg){
|
||||
innerhtml+="<tr>";
|
||||
ctrlname=command.name+'-'+arg.longopts;
|
||||
innerhtml+='<td><label for="'+ctrlname+'">'+ arg.glossary+'</label></td>';
|
||||
ctrltype="text";
|
||||
if(arg.checkbox){
|
||||
ctrltype="checkbox";
|
||||
}
|
||||
curvalue=data.values?.[command.name]?.[arg.longopts] || '';
|
||||
placeholder=arg?.datatype || '';
|
||||
innerhtml+='<td><input type="'+ctrltype+'" id="'+ctrlname+'" name="'+ctrlname+'" placeholder="'+placeholder+'" hasvalue="'+arg.hasvalue+'" ';
|
||||
|
||||
|
||||
innerhtml+='datatype="'+arg.datatype+'" ';
|
||||
innerhtml+='hasvalue='+arg.hasvalue+' ';
|
||||
innerhtml+='longopts="'+arg.longopts+'" ';
|
||||
innerhtml+='shortopts="'+arg.shortopts+'" ';
|
||||
innerhtml+='checkbox='+arg.checkbox+' ';
|
||||
|
||||
|
||||
|
||||
if(arg.checkbox){
|
||||
if(curvalue=data.values?.[command.name]?.[arg.longopts] ){
|
||||
innerhtml+='checked=true ';
|
||||
}
|
||||
else{
|
||||
innerhtml+='checked=false ';
|
||||
}
|
||||
|
||||
|
||||
innerhtml+='></input></td>';
|
||||
}
|
||||
else {
|
||||
innerhtml+='value="'+curvalue+'" ';
|
||||
innerhtml+='></input></td>'+ curvalue.length>0?'<td>last: '+curvalue+'</td>':'';
|
||||
}
|
||||
|
||||
innerhtml+="</tr>";
|
||||
});
|
||||
innerhtml+='</tbody></table><br>';
|
||||
|
||||
}
|
||||
innerhtml+='<div class="buttons"><input id="btn-'+ command.name + '" type="button" class="btn btn-danger btn-sm" value="'+command.name+'" onclick="runCommand(this);"></div></div><td></tr>';
|
||||
|
||||
});
|
||||
$("#commands-list").append(innerhtml);
|
||||
|
||||
})
|
||||
.fail(function(xhr, ajaxOptions, thrownError) {
|
||||
console.log(xhr.status);
|
||||
console.log(thrownError);
|
||||
$("#commands-list").empty();
|
||||
if (thrownError != '') showMessage(thrownError, 'MESSAGING_ERROR');
|
||||
blockAjax = false;
|
||||
});
|
||||
|
||||
@@ -80,7 +80,7 @@ union sockaddr_aligned {
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_in6 sin6;
|
||||
} aligned_sockaddr_t;
|
||||
|
||||
esp_err_t post_handler_buff_receive(httpd_req_t * req);
|
||||
static const char redirect_payload1[]="<html><head><title>Redirecting to Captive Portal</title><meta http-equiv='refresh' content='0; url=";
|
||||
static const char redirect_payload2[]="'></head><body><p>Please wait, refreshing. If page does not refresh, click <a href='";
|
||||
static const char redirect_payload3[]="'>here</a> to login.</p></body></html>";
|
||||
@@ -483,6 +483,54 @@ esp_err_t console_cmd_get_handler(httpd_req_t *req){
|
||||
ESP_LOGD_LOC(TAG, "Error retrieving command json string. ");
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Unable to format command");
|
||||
}
|
||||
cJSON_free(cmdlist);
|
||||
ESP_LOGD_LOC(TAG, "done serving [%s]", req->uri);
|
||||
return err;
|
||||
}
|
||||
esp_err_t console_cmd_post_handler(httpd_req_t *req){
|
||||
char success[]="{}";
|
||||
ESP_LOGD_LOC(TAG, "serving [%s]", req->uri);
|
||||
bool bOTA=false;
|
||||
char * otaURL=NULL;
|
||||
esp_err_t err = post_handler_buff_receive(req);
|
||||
if(err!=ESP_OK){
|
||||
return err;
|
||||
}
|
||||
if(!is_user_authenticated(req)){
|
||||
// todo: redirect to login page
|
||||
// return ESP_OK;
|
||||
}
|
||||
err = set_content_type_from_req(req);
|
||||
if(err != ESP_OK){
|
||||
return err;
|
||||
}
|
||||
|
||||
char *command= ((rest_server_context_t *)(req->user_ctx))->scratch;
|
||||
|
||||
cJSON *root = cJSON_Parse(command);
|
||||
if(root == NULL){
|
||||
ESP_LOGE_LOC(TAG, "Parsing command. Received content was: %s",command);
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Malformed command json. Unable to parse content.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
char * root_str = cJSON_Print(root);
|
||||
if(root_str!=NULL){
|
||||
ESP_LOGD(TAG, "Processing command item: \n%s", root_str);
|
||||
free(root_str);
|
||||
}
|
||||
cJSON *item=cJSON_GetObjectItemCaseSensitive(root, "command");
|
||||
if(!item){
|
||||
ESP_LOGE_LOC(TAG, "Command not found. Received content was: %s",command);
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Malformed command json. Unable to parse content.");
|
||||
err = ESP_FAIL;
|
||||
}
|
||||
else{
|
||||
// navigate to the first child of the config structure
|
||||
run_command(cJSON_GetStringValue(item));
|
||||
}
|
||||
|
||||
httpd_resp_send(req, (const char *)success, strlen(success));
|
||||
|
||||
ESP_LOGD_LOC(TAG, "done serving [%s]", req->uri);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ esp_err_t flash_post_handler(httpd_req_t *req);
|
||||
esp_err_t status_get_handler(httpd_req_t *req);
|
||||
esp_err_t messages_get_handler(httpd_req_t *req);
|
||||
esp_err_t console_cmd_get_handler(httpd_req_t *req);
|
||||
esp_err_t console_cmd_post_handler(httpd_req_t *req);
|
||||
esp_err_t ap_scan_handler(httpd_req_t *req);
|
||||
esp_err_t redirect_ev_handler(httpd_req_t *req);
|
||||
esp_err_t redirect_200_ev_handler(httpd_req_t *req);
|
||||
|
||||
@@ -70,6 +70,9 @@
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" href="#tab-syslog">Syslog</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" href="#tab-commands">System</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" href="#tab-nvs">NVS editor</a>
|
||||
</li>
|
||||
@@ -295,6 +298,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- firmware -->
|
||||
<div class="tab-pane fade" id="tab-commands">
|
||||
<table class="table table-hover" id="commands-list-table">
|
||||
<tbody id="commands-list">
|
||||
</tbody>
|
||||
</table>
|
||||
</div> <!-- system -->
|
||||
|
||||
<div class="tab-pane fade" id="tab-syslog">
|
||||
<table class="table table-hover">
|
||||
|
||||
@@ -60,6 +60,8 @@ void register_regular_handlers(httpd_handle_t server){
|
||||
|
||||
httpd_uri_t commands_get = { .uri = "/commands.json", .method = HTTP_GET, .handler = console_cmd_get_handler, .user_ctx = rest_context };
|
||||
httpd_register_uri_handler(server, &commands_get);
|
||||
httpd_uri_t commands_post = { .uri = "/commands.json", .method = HTTP_POST, .handler = console_cmd_post_handler, .user_ctx = rest_context };
|
||||
httpd_register_uri_handler(server, &commands_post);
|
||||
|
||||
httpd_uri_t config_post = { .uri = "/config.json", .method = HTTP_POST, .handler = config_post_handler, .user_ctx = rest_context };
|
||||
httpd_register_uri_handler(server, &config_post);
|
||||
|
||||
Reference in New Issue
Block a user