Config templates (#222)
* Implemented template editor and template assignment
This commit is contained in:
parent
2140e56e3a
commit
80bc45f322
6 changed files with 1487 additions and 45 deletions
231
index.html
231
index.html
|
@ -8,7 +8,8 @@
|
||||||
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.16/css/dataTables.bootstrap.min.css">
|
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.16/css/dataTables.bootstrap.min.css">
|
||||||
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.5.0/css/buttons.bootstrap.min.css">
|
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.5.0/css/buttons.bootstrap.min.css">
|
||||||
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/select/1.2.5/css/select.dataTables.min.css">
|
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/select/1.2.5/css/select.dataTables.min.css">
|
||||||
<link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.2/css/bootstrap-select.min.css">
|
||||||
|
<link rel="stylesheet" href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css">
|
||||||
|
|
||||||
<link rel="shortcut icon" href="https://root.graef.in:8443/static/xmrigcc/favicon.ico">
|
<link rel="shortcut icon" href="https://root.graef.in:8443/static/xmrigcc/favicon.ico">
|
||||||
|
|
||||||
|
@ -49,8 +50,11 @@
|
||||||
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/select/1.2.4/js/dataTables.select.min.js"></script>
|
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/select/1.2.4/js/dataTables.select.min.js"></script>
|
||||||
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-timeago/1.6.1/jquery.timeago.min.js"></script>
|
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-timeago/1.6.1/jquery.timeago.min.js"></script>
|
||||||
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/numeral.js/2.0.6/numeral.min.js"></script>
|
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/numeral.js/2.0.6/numeral.min.js"></script>
|
||||||
|
|
||||||
<script src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"></script>
|
<script src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"></script>
|
||||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.2/js/bootstrap-select.min.js"></script>
|
||||||
|
|
||||||
<script src="https://use.fontawesome.com/6b3cdfc597.js"></script>
|
<script src="https://use.fontawesome.com/6b3cdfc597.js"></script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
@ -232,11 +236,72 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: '<i class="fa fa-edit"> Multi miner editor</i>',
|
text: '<i class="fa fa-table"> Assign template</i>',
|
||||||
className: 'btn-primary',
|
className: 'btn-info',
|
||||||
enabled: false,
|
enabled: false,
|
||||||
action: function () {
|
action: function () {
|
||||||
$('#multiMinerEditor').modal('show');
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: "/admin/getClientConfigTemplates",
|
||||||
|
dataType:"json",
|
||||||
|
success: function(data) {
|
||||||
|
var htmlContent = "";
|
||||||
|
|
||||||
|
var arrayLength = data["templates"].length;
|
||||||
|
for (var i = 0; i < arrayLength; i++) {
|
||||||
|
htmlContent += "<option>" + data["templates"][i] + "</option>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arrayLength > 0 ) {
|
||||||
|
$('#assignTemplate').prop('disabled', false);
|
||||||
|
|
||||||
|
$('#assignTemplateSelector').html(htmlContent);
|
||||||
|
$('#assignTemplateSelector').selectpicker('refresh');
|
||||||
|
} else {
|
||||||
|
$('#assignTemplate').prop('disabled', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#assignTemplateEditor').modal('show');
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
setError('<strong>Unable to fetch templates</strong> - Please make they exist!');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '<i class="fa fa-edit"> Template Editor</i>',
|
||||||
|
className: 'btn-primary',
|
||||||
|
enabled: true,
|
||||||
|
action: function () {
|
||||||
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: "/admin/getClientConfigTemplates",
|
||||||
|
dataType:"json",
|
||||||
|
success: function(data) {
|
||||||
|
var htmlContent = "";
|
||||||
|
|
||||||
|
var arrayLength = data["templates"].length;
|
||||||
|
for (var i = 0; i < arrayLength; i++) {
|
||||||
|
htmlContent += "<option>" + data["templates"][i] + "</option>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arrayLength > 0 ) {
|
||||||
|
$('#templateEditorSave').prop('disabled', false);
|
||||||
|
|
||||||
|
$('#templateSelector').html(htmlContent);
|
||||||
|
$('#templateSelector').selectpicker('refresh');
|
||||||
|
$('#templateSelector').trigger('change');
|
||||||
|
} else {
|
||||||
|
$('#templateEditorSave').prop('disabled', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#templateEditor').modal('show');
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
setError('<strong>Unable to fetch templates</strong> - Please make they exist!');
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -365,6 +430,7 @@
|
||||||
table.button(5).enable(selectedRows > 0);
|
table.button(5).enable(selectedRows > 0);
|
||||||
table.button(6).enable(selectedRows > 0);
|
table.button(6).enable(selectedRows > 0);
|
||||||
table.button(7).enable(selectedRows > 0);
|
table.button(7).enable(selectedRows > 0);
|
||||||
|
table.button(8).enable(selectedRows > 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
table.on('deselect', function () {
|
table.on('deselect', function () {
|
||||||
|
@ -378,6 +444,7 @@
|
||||||
table.button(5).enable(selectedRows > 0);
|
table.button(5).enable(selectedRows > 0);
|
||||||
table.button(6).enable(selectedRows > 0);
|
table.button(6).enable(selectedRows > 0);
|
||||||
table.button(7).enable(selectedRows > 0);
|
table.button(7).enable(selectedRows > 0);
|
||||||
|
table.button(8).enable(selectedRows > 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
table.buttons().container().appendTo('#clientStatusList_wrapper .col-sm-6:eq(0)');
|
table.buttons().container().appendTo('#clientStatusList_wrapper .col-sm-6:eq(0)');
|
||||||
|
@ -422,6 +489,26 @@
|
||||||
setClientConfig(clientId, clientConfig);
|
setClientConfig(clientId, clientConfig);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#templateEditorSave').click(function(event) {
|
||||||
|
var templateId = $('#templateSelector').val();
|
||||||
|
var template = $('#template').val();
|
||||||
|
|
||||||
|
setTemplateConfig(templateId, template);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#templateEditorSaveAsDialog').click(function(event) {
|
||||||
|
$('#templateDialogSaveAs').modal('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#templateEditorSaveAs').click(function(event) {
|
||||||
|
var templateId = $('#templateName').val();
|
||||||
|
var template = $('#template').val();
|
||||||
|
|
||||||
|
setTemplateConfig(templateId, template);
|
||||||
|
|
||||||
|
$('#templateEditor').modal('hide');
|
||||||
|
});
|
||||||
|
|
||||||
$('#clientStatusList tbody').on( 'click', 'button#LOG', function () {
|
$('#clientStatusList tbody').on( 'click', 'button#LOG', function () {
|
||||||
var data = table.row( $(this).parents('tr') ).data();
|
var data = table.row( $(this).parents('tr') ).data();
|
||||||
var clientId = data['client_status']['client_id'];
|
var clientId = data['client_status']['client_id'];
|
||||||
|
@ -467,29 +554,41 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#multiMinerEditorReplace').click(function(event) {
|
$('#templateSelector').on('changed.bs.select', function (e, clickedIndex, newValue, oldValue) {
|
||||||
table.rows({ selected: true }).eq(0).each(function (index) {
|
var selected = $(e.currentTarget).val();
|
||||||
var row = table.row(index);
|
$.ajax({
|
||||||
var data = row.data();
|
type: "GET",
|
||||||
|
url: "/admin/getClientConfig?clientId=template_" + selected,
|
||||||
|
dataType: "json",
|
||||||
|
success: function (jsonClientConfig) {
|
||||||
|
$('#template').val(JSON.stringify(jsonClientConfig, undefined, 2));
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
setError('<strong>Unable to fetch template ' + selected + '</strong> - Please make sure it readable!');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
var clientId = data['client_status']['client_id'];
|
$('#assignTemplate').click(function(event) {
|
||||||
var search = $('#search').val();
|
var template = $('#assignTemplateSelector').val();
|
||||||
var replacement = $('#replacement').val();
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: "/admin/getClientConfig?clientId=template_" + template,
|
||||||
|
dataType:"json",
|
||||||
|
success: function(jsonClientConfig) {
|
||||||
|
table.rows({ selected: true }).eq(0).each(function (index) {
|
||||||
|
var row = table.row(index);
|
||||||
|
var data = row.data();
|
||||||
|
var clientId = data['client_status']['client_id'];
|
||||||
|
|
||||||
$.ajax({
|
jsonClientConfig['cc-client']['worker-id'] = clientId
|
||||||
type: "GET",
|
|
||||||
url: "/admin/getClientConfig?clientId=" + clientId,
|
|
||||||
dataType:"json",
|
|
||||||
success: function(jsonClientConfig) {
|
|
||||||
jsonClientConfig = JSON.stringify(jsonClientConfig,undefined, 2);
|
|
||||||
jsonClientConfig = jsonClientConfig.replace(new RegExp(search.trim(), 'g'), replacement.trim()).trim();
|
|
||||||
|
|
||||||
setClientConfig(clientId, jsonClientConfig);
|
setClientConfig(clientId, JSON.stringify(jsonClientConfig,undefined, 2));
|
||||||
},
|
});
|
||||||
error: function (data) {
|
},
|
||||||
setError('<strong>Unable to fetch ' + clientId + '_config.json</strong> - Please make sure that you pulled the config before!');
|
error: function (data) {
|
||||||
}
|
setError('<strong>Unable to fetch template ' + template + '</strong> - Please make sure it readable!');
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -685,6 +784,21 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setTemplateConfig(templateId, templateConfig) {
|
||||||
|
$.ajax({
|
||||||
|
url: "/admin/setClientConfig?clientId=template_" + templateId,
|
||||||
|
type: 'POST',
|
||||||
|
dataType: "text",
|
||||||
|
data: templateConfig,
|
||||||
|
success: function(data){
|
||||||
|
setSuccess('<strong>Successfully stored template: ' + templateId + '</strong> - You need to assign it to miners to apply.');
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
setError('<strong>Failed to store template: ' + templateId + '</strong> \nError: ' + JSON.stringify(data,undefined, 2));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
@ -790,32 +904,67 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal fade" id="multiMinerEditor" role="dialog">
|
<div class="modal fade" id="templateEditor" role="dialog">
|
||||||
<div class="modal-dialog modal-lg">
|
<div class="modal-dialog modal-lg">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
<h4 class="modal-title">Multi miner editor</h4>
|
<h4 class="modal-title">Template Editor</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="alert alert-danger fade in">
|
<div class="form-group">
|
||||||
<strong>Warning!</strong> - If you don't know what you are doing, [Cancel].
|
<label for="templateSelector">Template:</label>
|
||||||
</div>
|
<select class="selectpicker form-control" id="templateSelector"></select>
|
||||||
<h5 class="modal-title">
|
<br/>
|
||||||
This will search for <strong>"x"</strong> and replace with <strong>"y"</strong> in all selected miners config<br/><br/>
|
<br/>
|
||||||
<div class="alert alert-info fade in">
|
<textarea class="form-control" rows='20' id="template"></textarea>
|
||||||
<strong>If you accidentally pressed [Replace], no worries just PULL again all miner configs. Don't PUSH it!</strong>
|
|
||||||
</div>
|
|
||||||
</h5>
|
|
||||||
<div class='form-group'>
|
|
||||||
<label for='search'>Search for:</label>
|
|
||||||
<textarea class='form-control' rows='2' cols="1" id='search'></textarea>
|
|
||||||
<label for='replacement'>Replace with:</label>
|
|
||||||
<textarea class='form-control' rows='2' id='replacement'></textarea>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button id="multiMinerEditorReplace" type="button" class="btn btn-success" data-dismiss="modal">Replace</button>
|
<button id="templateEditorSave" type="button" class="btn btn-success" data-dismiss="modal">Save</button>
|
||||||
|
<button id="templateEditorSaveAsDialog" type="button" class="btn btn-primary">Save As...</button>
|
||||||
|
<button type="button" class="btn btn-danger" data-dismiss="modal">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="templateDialogSaveAs" role="dialog">
|
||||||
|
<div class="modal-dialog modal-lg">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
|
<h4 class="modal-title">Save As...</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="templateName">Template name:</label>
|
||||||
|
<input type="text" class="form-control" id="templateName"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button id="templateEditorSaveAs" type="button" class="btn btn-success" data-dismiss="modal">Save</button>
|
||||||
|
<button type="button" class="btn btn-danger" data-dismiss="modal">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="assignTemplateEditor" role="dialog">
|
||||||
|
<div class="modal-dialog modal-lg">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
|
<h4 class="modal-title">Assign template</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="assignTemplateSelector">Template:</label>
|
||||||
|
<select class="selectpicker form-control" id="assignTemplateSelector"></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button id="assignTemplate" type="button" class="btn btn-success" data-dismiss="modal">Assign</button>
|
||||||
<button type="button" class="btn btn-danger" data-dismiss="modal">Cancel</button>
|
<button type="button" class="btn btn-danger" data-dismiss="modal">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -180,6 +180,7 @@ static struct option const options[] = {
|
||||||
{ "api-port", 1, nullptr, 4000 },
|
{ "api-port", 1, nullptr, 4000 },
|
||||||
{ "api-access-token", 1, nullptr, 4001 },
|
{ "api-access-token", 1, nullptr, 4001 },
|
||||||
{ "api-worker-id", 1, nullptr, 4002 },
|
{ "api-worker-id", 1, nullptr, 4002 },
|
||||||
|
{ "reboot-cmd", 1, nullptr, 4021 },
|
||||||
{ "cc-url", 1, nullptr, 4003 },
|
{ "cc-url", 1, nullptr, 4003 },
|
||||||
{ "cc-access-token", 1, nullptr, 4004 },
|
{ "cc-access-token", 1, nullptr, 4004 },
|
||||||
{ "cc-worker-id", 1, nullptr, 4005 },
|
{ "cc-worker-id", 1, nullptr, 4005 },
|
||||||
|
@ -236,6 +237,7 @@ static struct option const config_options[] = {
|
||||||
{ "doublehash-thread-mask", 1, nullptr, 4013 },
|
{ "doublehash-thread-mask", 1, nullptr, 4013 },
|
||||||
{ "multihash-thread-mask", 1, nullptr, 4013 },
|
{ "multihash-thread-mask", 1, nullptr, 4013 },
|
||||||
{ "asm-optimization", 1, nullptr, 4020 },
|
{ "asm-optimization", 1, nullptr, 4020 },
|
||||||
|
{ "reboot-cmd", 1, nullptr, 4021 },
|
||||||
{ nullptr, 0, nullptr, 0 }
|
{ nullptr, 0, nullptr, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -641,7 +643,7 @@ bool Options::parseArg(int key, const char *arg)
|
||||||
case 4020: /* --asm-optimization */
|
case 4020: /* --asm-optimization */
|
||||||
return parseAsmOptimization(arg);
|
return parseAsmOptimization(arg);
|
||||||
|
|
||||||
case 4021: /* --cc-reboot-cmd */
|
case 4021: /* --cc-reboot-cmd || --reboot-cmd */
|
||||||
free(m_ccRebootCmd);
|
free(m_ccRebootCmd);
|
||||||
m_ccRebootCmd = strdup(arg);
|
m_ccRebootCmd = strdup(arg);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -28,6 +28,11 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#include "win_dirent.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "log/Log.h"
|
#include "log/Log.h"
|
||||||
#include <3rdparty/cpp-httplib/httplib.h>
|
#include <3rdparty/cpp-httplib/httplib.h>
|
||||||
#include <3rdparty/rapidjson/document.h>
|
#include <3rdparty/rapidjson/document.h>
|
||||||
|
@ -102,6 +107,8 @@ unsigned Service::handleGET(const Options* options, const std::string& url, cons
|
||||||
resultCode = getAdminPage(options, resp);
|
resultCode = getAdminPage(options, resp);
|
||||||
} else if (url.rfind("/admin/getClientStatusList", 0) == 0) {
|
} else if (url.rfind("/admin/getClientStatusList", 0) == 0) {
|
||||||
resultCode = getClientStatusList(resp);
|
resultCode = getClientStatusList(resp);
|
||||||
|
} else if (url.rfind("/admin/getClientConfigTemplates", 0) == 0) {
|
||||||
|
resultCode = getClientConfigTemplates(options, resp);
|
||||||
} else {
|
} else {
|
||||||
if (!clientId.empty()) {
|
if (!clientId.empty()) {
|
||||||
if (url.rfind("/client/getConfig", 0) == 0 || url.rfind("/admin/getClientConfig", 0) == 0) {
|
if (url.rfind("/client/getConfig", 0) == 0 || url.rfind("/admin/getClientConfig", 0) == 0) {
|
||||||
|
@ -269,7 +276,7 @@ unsigned Service::getClientStatusList(std::string& resp)
|
||||||
|
|
||||||
unsigned Service::setClientStatus(const Options* options, const std::string& clientIp, const std::string& clientId, const std::string& data, std::string& resp)
|
unsigned Service::setClientStatus(const Options* options, const std::string& clientIp, const std::string& clientId, const std::string& data, std::string& resp)
|
||||||
{
|
{
|
||||||
int resultCode = MHD_HTTP_BAD_REQUEST;
|
unsigned resultCode = MHD_HTTP_BAD_REQUEST;
|
||||||
|
|
||||||
rapidjson::Document document;
|
rapidjson::Document document;
|
||||||
if (!document.Parse(data.c_str()).HasParseError()) {
|
if (!document.Parse(data.c_str()).HasParseError()) {
|
||||||
|
@ -347,6 +354,65 @@ unsigned Service::getClientLog(const std::string& clientId, std::string& resp)
|
||||||
return MHD_HTTP_OK;
|
return MHD_HTTP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned Service::getClientConfigTemplates(const Options* options, std::string& resp)
|
||||||
|
{
|
||||||
|
std::string configFolder(".");
|
||||||
|
|
||||||
|
if (options->ccClientConfigFolder() != nullptr) {
|
||||||
|
configFolder = options->ccClientConfigFolder();
|
||||||
|
# ifdef WIN32
|
||||||
|
configFolder += '\\';
|
||||||
|
# else
|
||||||
|
configFolder += '/';
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> templateFiles;
|
||||||
|
|
||||||
|
DIR* dirp = opendir(configFolder.c_str());
|
||||||
|
if (dirp) {
|
||||||
|
struct dirent* entry;
|
||||||
|
while ((entry = readdir(dirp)) != NULL) {
|
||||||
|
if (entry->d_type == DT_REG) {
|
||||||
|
std::string filename = entry->d_name;
|
||||||
|
std::string starting = "template_";
|
||||||
|
std::string ending = "_config.json";
|
||||||
|
|
||||||
|
if (filename.rfind(starting, 0) == 0 && filename.find(ending, (filename.length() - ending.length())) != std::string::npos) {
|
||||||
|
filename.erase(0, starting.length());
|
||||||
|
filename.erase(filename.length()-ending.length());
|
||||||
|
|
||||||
|
templateFiles.push_back(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dirp);
|
||||||
|
}
|
||||||
|
|
||||||
|
rapidjson::Document respDocument;
|
||||||
|
respDocument.SetObject();
|
||||||
|
|
||||||
|
auto& allocator = respDocument.GetAllocator();
|
||||||
|
|
||||||
|
rapidjson::Value templateList(rapidjson::kArrayType);
|
||||||
|
for (auto& templateFile : templateFiles) {
|
||||||
|
rapidjson::Value templateEntry(templateFile.c_str(), allocator);
|
||||||
|
templateList.PushBack(templateEntry, allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
respDocument.AddMember("templates", templateList, allocator);
|
||||||
|
|
||||||
|
rapidjson::StringBuffer buffer(0, 4096);
|
||||||
|
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
||||||
|
writer.SetMaxDecimalPlaces(10);
|
||||||
|
respDocument.Accept(writer);
|
||||||
|
|
||||||
|
resp = buffer.GetString();
|
||||||
|
|
||||||
|
return MHD_HTTP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned Service::getAdminPage(const Options* options, std::string& resp)
|
unsigned Service::getAdminPage(const Options* options, std::string& resp)
|
||||||
{
|
{
|
||||||
std::stringstream data;
|
std::stringstream data;
|
||||||
|
|
|
@ -54,6 +54,7 @@ private:
|
||||||
static unsigned getClientCommand(const std::string& clientId, std::string& resp);
|
static unsigned getClientCommand(const std::string& clientId, std::string& resp);
|
||||||
static unsigned getClientLog(const std::string& clientId, std::string& resp);
|
static unsigned getClientLog(const std::string& clientId, std::string& resp);
|
||||||
static unsigned getClientStatusList(std::string& resp);
|
static unsigned getClientStatusList(std::string& resp);
|
||||||
|
static unsigned getClientConfigTemplates(const Options* options, std::string& resp);
|
||||||
static unsigned getAdminPage(const Options* options, std::string& resp);
|
static unsigned getAdminPage(const Options* options, std::string& resp);
|
||||||
|
|
||||||
static unsigned setClientStatus(const Options* options, const std::string& clientIp, const std::string& clientId, const std::string& data, std::string& resp);
|
static unsigned setClientStatus(const Options* options, const std::string& clientIp, const std::string& clientId, const std::string& data, std::string& resp);
|
||||||
|
|
|
@ -36,14 +36,14 @@
|
||||||
#define APP_DESC "XMRigCC CPU miner"
|
#define APP_DESC "XMRigCC CPU miner"
|
||||||
#define APP_COPYRIGHT "Copyright (C) 2017- BenDr0id"
|
#define APP_COPYRIGHT "Copyright (C) 2017- BenDr0id"
|
||||||
#endif
|
#endif
|
||||||
#define APP_VERSION "1.8.6 (based on XMRig)"
|
#define APP_VERSION "1.8.7 (based on XMRig)"
|
||||||
#define APP_DOMAIN ""
|
#define APP_DOMAIN ""
|
||||||
#define APP_SITE "https://github.com/Bendr0id/xmrigCC"
|
#define APP_SITE "https://github.com/Bendr0id/xmrigCC"
|
||||||
#define APP_KIND "cpu"
|
#define APP_KIND "cpu"
|
||||||
|
|
||||||
#define APP_VER_MAJOR 1
|
#define APP_VER_MAJOR 1
|
||||||
#define APP_VER_MINOR 8
|
#define APP_VER_MINOR 8
|
||||||
#define APP_VER_BUILD 6
|
#define APP_VER_BUILD 7
|
||||||
#define APP_VER_REV 0
|
#define APP_VER_REV 0
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
|
1224
src/win_dirent.h
Normal file
1224
src/win_dirent.h
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue