Browse Source

- lots of style tweaks for mobile

- playing with UI
- working on new /rpc-browser tool
fix-133-memory-crash
Dan Janosik 7 years ago
parent
commit
6d91756529
  1. 78
      app/rpcApi.js
  2. 6
      public/css/styling.css
  3. 66
      routes/baseActionsRouter.js
  4. 56
      views/browser.pug
  5. 18
      views/includes/blocks-list.pug
  6. 2
      views/includes/pagination.pug
  7. 6
      views/index.pug
  8. 19
      views/layout.pug
  9. 4
      views/terminal.pug

78
app/rpcApi.js

@ -462,6 +462,80 @@ function getBlockData(rpcClient, blockHash, txLimit, txOffset) {
}); });
} }
function getHelp() {
return new Promise(function(resolve, reject) {
client.cmd('help', function(err, result, resHeaders) {
if (err) {
console.log("Error 32907th429ghf: " + err);
reject(err);
return;
}
var lines = result.split("\n");
var sections = [];
lines.forEach(function(line) {
if (line.startsWith("==")) {
var sectionName = line.substring(2);
sectionName = sectionName.substring(0, sectionName.length - 2).trim();
sections.push({name:sectionName, methods:[]});
} else if (line.trim().length > 0) {
var methodName = line.trim();
if (methodName.includes(" ")) {
methodName = methodName.substring(0, methodName.indexOf(" "));
}
sections[sections.length - 1].methods.push({name:methodName, content:line.trim()});
}
});
resolve(sections);
});
});
}
function getRpcMethodHelp(methodName) {
return new Promise(function(resolve, reject) {
client.cmd('help', methodName, function(err, result, resHeaders) {
if (err) {
console.log("Error 237hwerf07wehg: " + err);
reject(err);
return;
}
var str = result;
var lines = str.split("\n");
var argumentLines = [];
var catchArgs = false;
lines.forEach(function(line) {
if (line.trim().length == 0) {
catchArgs = false;
}
if (catchArgs) {
argumentLines.push(line);
}
if (line.trim() == "Arguments:") {
catchArgs = true;
}
});
console.log("argLines: " + argumentLines);
resolve(result);
});
});
}
module.exports = { module.exports = {
getBlockchainInfo: getBlockchainInfo, getBlockchainInfo: getBlockchainInfo,
getNetworkInfo: getNetworkInfo, getNetworkInfo: getNetworkInfo,
@ -475,5 +549,7 @@ module.exports = {
getRawTransaction: getRawTransaction, getRawTransaction: getRawTransaction,
getRawTransactions: getRawTransactions, getRawTransactions: getRawTransactions,
getMempoolStats: getMempoolStats, getMempoolStats: getMempoolStats,
getUptimeSeconds: getUptimeSeconds getUptimeSeconds: getUptimeSeconds,
getHelp: getHelp,
getRpcMethodHelp: getRpcMethodHelp
}; };

6
public/css/styling.css

@ -3,7 +3,7 @@ body {
} }
hr { hr {
margin: 15px 0; margin: 5px 0 15px 0;
} }
img.header-image { img.header-image {
@ -40,6 +40,6 @@ code, .monospace {
margin-right: 20px; margin-right: 20px;
} }
.data-cell, .data-header { .nav-link {
text-align: right; padding: 0.5rem 1rem 0.5rem 0;
} }

66
routes/baseActionsRouter.js

@ -382,7 +382,7 @@ router.get("/tx/:transactionId", function(req, res) {
}); });
}); });
router.get("/terminal", function(req, res) { router.get("/rpc-terminal", function(req, res) {
if (!env.debug) { if (!env.debug) {
res.send("Debug mode is off."); res.send("Debug mode is off.");
@ -392,7 +392,7 @@ router.get("/terminal", function(req, res) {
res.render("terminal"); res.render("terminal");
}); });
router.post("/terminal", function(req, res) { router.post("/rpc-terminal", function(req, res) {
if (!env.debug) { if (!env.debug) {
res.send("Debug mode is off."); res.send("Debug mode is off.");
@ -437,5 +437,67 @@ router.post("/terminal", function(req, res) {
}); });
}); });
router.get("/rpc-browser", function(req, res) {
if (!env.debug) {
res.send("Debug mode is off.");
return;
}
rpcApi.getHelp().then(function(result) {
res.locals.gethelp = result;
if (req.query.method) {
res.locals.method = req.query.method;
rpcApi.getRpcMethodHelp(req.query.method.trim()).then(function(result2) {
res.locals.methodhelp = result2;
var lines = result2.split("\n");
var params = [];
var line1Parts = lines[0].trim().split(" ");
line1Parts.shift();
params = line1Parts;
res.locals.methodParams = params;
console.log("params: " + params);
if (req.query.execute) {
client.cmd([{method:req.query.method, params:[]}], function(err3, result3, resHeaders3) {
if (err3) {
res.locals.methodResult = err3;
} else if (result3) {
res.locals.methodResult = result3;
} else {
res.locals.methodResult = {"Error":"No response from node."};
}
res.render("browser");
});
} else {
res.render("browser");
}
}).catch(function(err) {
res.locals.userMessage = "Error loading help content for method " + req.query.method + ": " + err;
res.render("browser");
});
} else {
res.render("browser");
}
}).catch(function(err) {
res.locals.userMessage = "Error loading help content: " + err;
res.render("browser");
});
});
module.exports = router; module.exports = router;

56
views/browser.pug

@ -0,0 +1,56 @@
extends layout
block headContent
title RPC Browser
style.
pre {
white-space: pre-wrap; /* Since CSS 2.1 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}
block content
h1 RPC Browser
hr
div(class="row")
div(class="col-md-3")
each section, sectionIndex in gethelp
h4 #{section.name}
small (#{section.methods.length})
hr
div(class="mb-4")
ol(style="padding-left: 30px;")
each methodX, methodIndex in section.methods
li
a(href=("/rpc-browser?method=" + methodX.name), style=(methodX.name == method ? "font-weight: bold; font-style: italic;" : false)) #{methodX.name}
div(class="col-md-9")
if (methodhelp)
div(class="row")
div(class="col-md-6")
h4(style="display: inline-block;") Command: #{method}
div(class="col-md-6")
a(href=("https://bitcoin.org/en/developer-reference#" + method), class="float-md-right") See developer docs »
hr
pre #{methodhelp}
hr
form(method="get")
input(type="hidden", name="method", value=method)
input(type="submit", name="execute", value="Execute", class="btn btn-primary btn-block")
if (methodResult)
h5(class="mt-3") Result
pre
code #{JSON.stringify(methodResult, null, 4)}

18
views/includes/blocks-list.pug

@ -1,22 +1,22 @@
table(class="table table-striped") table(class="table table-striped table-responsive-sm")
thead thead
tr tr
th //th
th(class="data-header") Height th(class="data-header") Height
th(class="data-header") Timestamp (utc) th(class="data-header") Timestamp (utc)
th(class="data-header") Age th(class="data-header text-right") Age
th(class="data-header") Transactions th(class="data-header text-right") Transactions
th(class="data-header") Size (bytes) th(class="data-header text-right") Size (bytes)
tbody tbody
each block, blockIndex in blocks each block, blockIndex in blocks
if (block) if (block)
tr tr
th #{(blockIndex + blockOffset + 1).toLocaleString()} //th #{(blockIndex + blockOffset + 1).toLocaleString()}
td(class="data-cell monospace") td(class="data-cell monospace")
a(href=("/block-height/" + block.height)) #{block.height.toLocaleString()} a(href=("/block-height/" + block.height)) #{block.height.toLocaleString()}
td(class="data-cell monospace") #{moment.utc(new Date(parseInt(block.time) * 1000)).format("Y-MM-DD HH:mm:ss")} td(class="data-cell monospace") #{moment.utc(new Date(parseInt(block.time) * 1000)).format("Y-MM-DD HH:mm:ss")}
- var timeAgo = moment.duration(moment.utc(new Date()).diff(moment.utc(new Date(parseInt(block.time) * 1000)))); - var timeAgo = moment.duration(moment.utc(new Date()).diff(moment.utc(new Date(parseInt(block.time) * 1000))));
td(class="data-cell monospace") #{timeAgo.format()} td(class="data-cell monospace text-right") #{timeAgo.format()}
td(class="data-cell monospace") #{block.tx.length.toLocaleString()} td(class="data-cell monospace text-right") #{block.tx.length.toLocaleString()}
td(class="data-cell monospace") #{block.size.toLocaleString()} td(class="data-cell monospace text-right") #{block.size.toLocaleString()}

2
views/includes/pagination.pug

@ -4,7 +4,7 @@
- } - }
nav(aria-label="Page navigation") nav(aria-label="Page navigation")
ul(class="pagination pagination-lg justify-content-center") ul(class="pagination pagination-lg justify-content-center flex-wrap")
li(class="page-item", class=(pageNumber == 1 ? "disabled" : false)) li(class="page-item", class=(pageNumber == 1 ? "disabled" : false))
a(class="page-link", href=(pageNumber == 1 ? "javascript:void(0)" : paginationUrlFunction(pageNumber - 1)), aria-label="Previous") a(class="page-link", href=(pageNumber == 1 ? "javascript:void(0)" : paginationUrlFunction(pageNumber - 1)), aria-label="Previous")
span(aria-hidden="true") « span(aria-hidden="true") «

6
views/index.pug

@ -16,15 +16,15 @@ block content
if (getblockchaininfo.initialblockdownload) if (getblockchaininfo.initialblockdownload)
small (#{(getblockchaininfo.headers - getblockchaininfo.blocks).toLocaleString()} behind) small (#{(getblockchaininfo.headers - getblockchaininfo.blocks).toLocaleString()} behind)
span(style="float: right; font-size: 75%;")
a(href="/blocks") Browse Blocks »
- var blocks = latestBlocks; - var blocks = latestBlocks;
- var blockOffset = 0; - var blockOffset = 0;
include includes/blocks-list.pug include includes/blocks-list.pug
hr
a(href="/blocks", class="btn btn-primary btn-block") See more
hr hr
div(class="") div(class="")

19
views/layout.pug

@ -33,17 +33,26 @@ html
ul(class="navbar-nav mr-auto") ul(class="navbar-nav mr-auto")
if (debug) if (debug)
li(class="nav-item") li(class="nav-item")
a(href="/terminal", class="nav-link") RPC Terminal a(href="/rpc-terminal", class="nav-link") RPC Terminal
li(class="nav-item") li(class="nav-item")
a(href="/node-info", class="nav-link") Node Info a(href="/node-info", class="nav-link") Node Details
li(class="nav-item")
a(href="/mempool", class="nav-link") Mempool Info
form(method="post", action="/search", class="form-inline") form(method="post", action="/search", class="form-inline")
div(class="input-group") div(class="input-group")
input(type="text", class="form-control form-control-sm", name="query", placeholder="block height, block hash, txid", value=(query), style="width: 250px;") input(type="text", class="form-control form-control-sm", name="query", placeholder="block height, block hash, txid", value=(query), style="width: 250px;")
span(class="input-group-btn") span(class="input-group-btn")
input(type="submit", class="btn btn-primary", value="Search") input(type="submit", class="btn btn-primary", value="Search")
div(class="container", style="margin-top: -1.0rem;")
ul(class="nav")
li(class="nav-item")
a(href="/rpc-browser", class="nav-link") RPC Browser
li(class="nav-item")
a(href="/rpc-terminal", class="nav-link") RPC Terminal
li(class="nav-item")
a(href="/mempool", class="nav-link") Mempool Summary
hr
div(class="container") div(class="container")
if (userMessage) if (userMessage)
div(class="alert", class=(userMessageType ? ("alert-" + userMessageType) : "alert-info"), role="alert") div(class="alert", class=(userMessageType ? ("alert-" + userMessageType) : "alert-info"), role="alert")

4
views/terminal.pug

@ -1,7 +1,7 @@
extends layout extends layout
block content block content
h1 Terminal h1 RPC Terminal
hr hr
:markdown-it :markdown-it
@ -32,7 +32,7 @@ block endOfBody
postData.cmd = cmd; postData.cmd = cmd;
$.post( $.post(
"/terminal", "/rpc-terminal",
postData, postData,
function(response, textStatus, jqXHR) { function(response, textStatus, jqXHR) {
var t = new Date().getTime(); var t = new Date().getTime();

Loading…
Cancel
Save