From c8937b69245b8fef1fd0abac3efe9d0d64f0fef8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Sat, 10 Feb 2018 22:49:21 +0100 Subject: [PATCH] Make debug interface pretty --- data/debug-interface/debug-interface.qrc | 1 + data/debug-interface/logo.svg | 15 +- data/debug-interface/styles.css | 152 +++++++++-- data/debug-interface/warning.svg | 104 ++++++++ libguh-core/debugserverhandler.cpp | 320 +++++++++++++++++------ 5 files changed, 481 insertions(+), 111 deletions(-) create mode 100644 data/debug-interface/warning.svg diff --git a/data/debug-interface/debug-interface.qrc b/data/debug-interface/debug-interface.qrc index 84752ae6..822ac02c 100644 --- a/data/debug-interface/debug-interface.qrc +++ b/data/debug-interface/debug-interface.qrc @@ -1,6 +1,7 @@ logo.svg + warning.svg styles.css diff --git a/data/debug-interface/logo.svg b/data/debug-interface/logo.svg index 17065d0b..d065589f 100644 --- a/data/debug-interface/logo.svg +++ b/data/debug-interface/logo.svg @@ -14,7 +14,7 @@ id="svg2" version="1.1" inkscape:version="0.91 r13725" - sodipodi:docname="guh-logo.svg" + sodipodi:docname="logo.svg" inkscape:export-filename="/home/timon/guh/guh/guh/icons/guh-logo-512x512.png" inkscape:export-xdpi="92.160004" inkscape:export-ydpi="92.160004"> @@ -252,15 +252,15 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1.979899" - inkscape:cx="30.679884" + inkscape:cx="-124.12599" inkscape:cy="202.52602" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" inkscape:window-width="2880" - inkscape:window-height="1749" + inkscape:window-height="1752" inkscape:window-x="0" - inkscape:window-y="51" + inkscape:window-y="48" inkscape:window-maximized="1" /> @@ -279,13 +279,6 @@ inkscape:groupmode="layer" id="layer1" transform="translate(0,-552.36215)"> - diff --git a/data/debug-interface/styles.css b/data/debug-interface/styles.css index cb0a6d46..e3697824 100644 --- a/data/debug-interface/styles.css +++ b/data/debug-interface/styles.css @@ -18,40 +18,162 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -table { - display: table; - border-collapse: colapse; - border-spacing: 2px; - border-color: gray; +html, +body { + margin:0; + padding:0; + height:100%; } p { color: #676767; font-family: "Ubuntu", Helvetica, "Helvetica Neue", Arial, sans-serif; font-size: 100%; + text-align: center; } h1, h2, h3, h4, h5, h6 { - margin: 0 0 20px 0; font-family: "Ubuntu", Helvetica, "Helvetica Neue", Arial, sans-serif; font-weight: normal; color: #676767; text-transform: none; } -html { +th, td { + padding: 3px; + padding-left: 10px; + padding-right: 10px; color: #676767; - font-family: "Ubuntu", Arial, Helvetica, sans-serif; - background: white; + font-family: "Ubuntu", Helvetica, "Helvetica Neue", Arial, sans-serif; + text-align: left; } -footer { - position: fixed; - left: 0; - bottom: 0; +hr { + color: #efefef; +} + +table { + display: table; + border-collapse: colapse; + border-color: #efefef; width: 100%; - background-color: white; +} + +button { + width: 100%; +} + +.guh-main-logo { + left: 0; + height: 85px; + min-height: 85px; + max-height: 85px; + vertical-align: middle; +} + +.warning { + background-color: #ed3146; + border-radius: 20px; + opacity: 0.8; + width: 80%; + margin-left: auto; + margin-right: auto; +} + +.warning-message { + padding:30px; + margin-left: 60px; + opacity: 1; + color: white; + background-color: transparent; + font-family: "Ubuntu", Helvetica, "Helvetica Neue", Arial, sans-serif; + text-align: center; + float: none; +} + +.warning-image { + padding:12px; + height: 60px; + min-height: 60px; + max-height: 60px; + float: left; +} + +.warning:after { + content: ""; + display: table; + clear: both; +} + +.download-row { + width: 100%; + height: 100px; + left: 0; + right: 0; +} + +.download-name-column { + float: left; + width: 30%; + padding: 10px; +} + +.download-path-column { + float: left; + width: 40%; + padding: 10px; +} + +.download-button-column { + float: left; + width: 20%; + padding: 10px; +} + +.download-row: after { + content: ""; + display: table; + clear: both; +} + +.button { + background-color: #57baae; + border: none; + color: white; + padding: 15px 30px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 16px; + border-radius: 10px; +} + + +.container { + min-height:100%; + position:relative; +} + +.header { + padding:10px; + background-color: #efefef; + text-align: center; +} + +.body { + padding-left: 15%; + padding-right: 15%; + padding-bottom:120px; +} + +.footer { + position:absolute; + bottom:0; + left:0; + right:0; + width:100%; + height:100px; + background-color: #efefef; color: #676767; text-align: center; } diff --git a/data/debug-interface/warning.svg b/data/debug-interface/warning.svg new file mode 100644 index 00000000..ab70a256 --- /dev/null +++ b/data/debug-interface/warning.svg @@ -0,0 +1,104 @@ + + + + + warning icon + + + + + + image/svg+xml + + warning icon + 10.02.2018 + + + Simon Stürz + + + + + guh GmbH + + + Warning icon for the debug interface + + + + + + + + + + + + + + ! + + diff --git a/libguh-core/debugserverhandler.cpp b/libguh-core/debugserverhandler.cpp index 94775af4..c2ce494b 100644 --- a/libguh-core/debugserverhandler.cpp +++ b/libguh-core/debugserverhandler.cpp @@ -46,6 +46,7 @@ QByteArray DebugServerHandler::createDebugXmlDocument() writer.writeStartElement("html"); writer.writeAttribute("lang", GuhCore::instance()->configuration()->locale().name()); + // Head writer.writeStartElement("head"); writer.writeEmptyElement("meta"); @@ -60,18 +61,46 @@ QByteArray DebugServerHandler::createDebugXmlDocument() writer.writeEndElement(); // head - writer.writeStartElement("body"); + // Container + writer.writeStartElement("div"); + writer.writeAttribute("class", "container"); + + // Header + writer.writeStartElement("div"); + writer.writeAttribute("class", "header"); + writer.writeStartElement("h1"); + writer.writeEmptyElement("img"); + writer.writeAttribute("src", "/debug/logo.svg"); + writer.writeAttribute("class", "guh-main-logo"); + writer.writeCharacters(QCoreApplication::translate("main", "nymea debug interface")); + writer.writeEndElement(); // h1 + writer.writeEndElement(); // div header + + // Body + writer.writeStartElement("div"); + writer.writeAttribute("class", "body"); - // Welcome section - writer.writeTextElement("h1", QCoreApplication::translate("main", "nymea debug interface")); - writer.writeEmptyElement("hr"); writer.writeTextElement("p", QCoreApplication::translate("main", "Welcome to the debug interface.")); writer.writeTextElement("p", QCoreApplication::translate("main", "This debug interface was designed to provide an easy possibility to get helpful information about the running nymea server.")); - writer.writeEmptyElement("hr"); - writer.writeTextElement("h3", QCoreApplication::translate("main", "Warning")); - writer.writeTextElement("p", QCoreApplication::translate("main", "Be aware that this debug interface is a security breach and offers access to the system log and therefore to possibly sensible data.")); - writer.writeTextElement("p", QCoreApplication::translate("main", "If you are not using this debug tools, than you should disable it.")); + // Warning + writer.writeStartElement("div"); + writer.writeAttribute("class", "warning"); + // Warning image + writer.writeStartElement("div"); + writer.writeAttribute("class", "warning-image-area"); + writer.writeEmptyElement("img"); + writer.writeAttribute("class", "warning-image"); + writer.writeAttribute("src", "/debug/warning.svg"); + writer.writeEndElement(); // div warning image + // Warning message + writer.writeStartElement("div"); + writer.writeAttribute("class", "warning-message"); + writer.writeCharacters(QCoreApplication::translate("main", "Be aware that this debug interface is a security breach and could offer access to sensible data.")); + writer.writeEndElement(); // div warning message + writer.writeEndElement(); // div warning + + writer.writeEmptyElement("hr"); // System information section @@ -79,24 +108,10 @@ QByteArray DebugServerHandler::createDebugXmlDocument() writer.writeEmptyElement("hr"); writer.writeStartElement("table"); - //writer.writeAttribute("width", "100%"); - writer.writeAttribute("border", "1"); - - writer.writeStartElement("col"); - writer.writeAttribute("align", "left"); - writer.writeEndElement(); // col - - writer.writeStartElement("col"); - writer.writeAttribute("align", "left"); - writer.writeEndElement(); // col - - QString userName = qgetenv("USER"); - if (userName.isEmpty()) - userName = qgetenv("USERNAME"); writer.writeStartElement("tr"); writer.writeTextElement("th", QCoreApplication::translate("main", "User")); - writer.writeTextElement("td", userName); + writer.writeTextElement("td", qgetenv("USER")); writer.writeEndElement(); // tr writer.writeStartElement("tr"); @@ -212,142 +227,244 @@ QByteArray DebugServerHandler::createDebugXmlDocument() // Downloads section writer.writeEmptyElement("hr"); writer.writeTextElement("h2", QCoreApplication::translate("main", "Downloads")); - writer.writeEmptyElement("hr"); // Logs download section + writer.writeEmptyElement("hr"); writer.writeTextElement("h3", QCoreApplication::translate("main", "Logs")); + writer.writeEmptyElement("hr"); - writer.writeStartElement("table"); - writer.writeAttribute("border", "1"); + // Download row + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-row"); + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-name-column"); + writer.writeTextElement("p", QCoreApplication::translate("main", "Log database")); + writer.writeEndElement(); // div download-name-column - writer.writeStartElement("tr"); - writer.writeTextElement("th", QCoreApplication::translate("main", "Log database")); - writer.writeTextElement("td", GuhSettings::logPath()); - writer.writeStartElement("td"); + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-path-column"); + writer.writeTextElement("p", GuhSettings::logPath()); + writer.writeEndElement(); // div download-path-column + + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-button-column"); writer.writeStartElement("form"); + writer.writeAttribute("class", "download-button"); writer.writeAttribute("method", "get"); writer.writeAttribute("action", "/debug/logdb.sql"); writer.writeStartElement("button"); + writer.writeAttribute("class", "button"); writer.writeAttribute("type", "submit"); writer.writeCharacters(QCoreApplication::translate("main", "Download")); writer.writeEndElement(); // button writer.writeEndElement(); // form - writer.writeEndElement(); // td - writer.writeEndElement(); // tr + writer.writeEndElement(); // div download-button-column - writer.writeStartElement("tr"); - writer.writeTextElement("th", QCoreApplication::translate("main", "System logs")); - writer.writeTextElement("td", "/var/log/syslog"); - writer.writeStartElement("td"); + writer.writeEndElement(); // div download-row + + + // Download row + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-row"); + + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-name-column"); + writer.writeTextElement("p", QCoreApplication::translate("main", "System logs")); + writer.writeEndElement(); // div download-name-column + + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-path-column"); + writer.writeTextElement("p", "/var/log/syslog"); + writer.writeEndElement(); // div download-path-column + + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-button-column"); writer.writeStartElement("form"); + writer.writeAttribute("class", "download-button"); writer.writeAttribute("method", "get"); writer.writeAttribute("action", "/debug/syslog"); writer.writeStartElement("button"); + writer.writeAttribute("class", "button"); writer.writeAttribute("type", "submit"); writer.writeCharacters(QCoreApplication::translate("main", "Download")); writer.writeEndElement(); // button writer.writeEndElement(); // form - writer.writeEndElement(); // td - writer.writeEndElement(); // tr + writer.writeEndElement(); // div download-button-column - // TODO: offer logfile download if specified in the command line options - - writer.writeEndElement(); // table + writer.writeEndElement(); // div download-row // Settings download section + writer.writeEmptyElement("hr"); writer.writeTextElement("h3", QCoreApplication::translate("main", "Settings")); + writer.writeEmptyElement("hr"); - writer.writeStartElement("table"); - writer.writeAttribute("border", "1"); + // Download row + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-row"); - writer.writeStartElement("tr"); - writer.writeTextElement("th", QCoreApplication::translate("main", "Guhd settings")); - writer.writeTextElement("td", GuhSettings(GuhSettings::SettingsRoleGlobal).fileName()); - writer.writeStartElement("td"); + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-name-column"); + writer.writeTextElement("p", QCoreApplication::translate("main", "Guhd settings")); + writer.writeEndElement(); // div download-name-column + + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-path-column"); + writer.writeTextElement("p", GuhSettings(GuhSettings::SettingsRoleGlobal).fileName()); + writer.writeEndElement(); // div download-path-column + + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-button-column"); writer.writeStartElement("form"); + writer.writeAttribute("class", "download-button"); writer.writeAttribute("method", "get"); writer.writeAttribute("action", "/debug/settings/guhd"); writer.writeStartElement("button"); + writer.writeAttribute("class", "button"); writer.writeAttribute("type", "submit"); writer.writeCharacters(QCoreApplication::translate("main", "Download")); writer.writeEndElement(); // button writer.writeEndElement(); // form - writer.writeEndElement(); // td - writer.writeEndElement(); // tr + writer.writeEndElement(); // div download-button-column - writer.writeStartElement("tr"); - writer.writeTextElement("th", QCoreApplication::translate("main", "Device settings")); - writer.writeTextElement("td", GuhSettings(GuhSettings::SettingsRoleDevices).fileName()); - writer.writeStartElement("td"); + writer.writeEndElement(); // div download-row + + + // Download row + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-row"); + + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-name-column"); + writer.writeTextElement("p", QCoreApplication::translate("main", "Device settings")); + writer.writeEndElement(); // div download-name-column + + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-path-column"); + writer.writeTextElement("p", GuhSettings(GuhSettings::SettingsRoleDevices).fileName()); + writer.writeEndElement(); // div download-path-column + + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-button-column"); writer.writeStartElement("form"); + writer.writeAttribute("class", "download-button"); writer.writeAttribute("method", "get"); writer.writeAttribute("action", "/debug/settings/devices"); writer.writeStartElement("button"); + writer.writeAttribute("class", "button"); writer.writeAttribute("type", "submit"); writer.writeCharacters(QCoreApplication::translate("main", "Download")); writer.writeEndElement(); // button writer.writeEndElement(); // form - writer.writeEndElement(); // td - writer.writeEndElement(); // tr + writer.writeEndElement(); // div download-button-column - writer.writeStartElement("tr"); - writer.writeTextElement("th", QCoreApplication::translate("main", "Device state settings")); - writer.writeTextElement("td", GuhSettings(GuhSettings::SettingsRoleDeviceStates).fileName()); - writer.writeStartElement("td"); + writer.writeEndElement(); // div download-row + + + // Download row + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-row"); + + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-name-column"); + writer.writeTextElement("p", QCoreApplication::translate("main", "Device states settings")); + writer.writeEndElement(); // div download-name-column + + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-path-column"); + writer.writeTextElement("p", GuhSettings(GuhSettings::SettingsRoleDeviceStates).fileName()); + writer.writeEndElement(); // div download-path-column + + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-button-column"); writer.writeStartElement("form"); + writer.writeAttribute("class", "download-button"); writer.writeAttribute("method", "get"); writer.writeAttribute("action", "/debug/settings/devicestates"); writer.writeStartElement("button"); + writer.writeAttribute("class", "button"); writer.writeAttribute("type", "submit"); writer.writeCharacters(QCoreApplication::translate("main", "Download")); writer.writeEndElement(); // button writer.writeEndElement(); // form - writer.writeEndElement(); // td - writer.writeEndElement(); // tr + writer.writeEndElement(); // div download-button-column + + writer.writeEndElement(); // div download-row - writer.writeStartElement("tr"); - writer.writeTextElement("th", QCoreApplication::translate("main", "Rules settings")); - writer.writeTextElement("td", GuhSettings(GuhSettings::SettingsRoleRules).fileName()); - writer.writeStartElement("td"); + // Download row + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-row"); + + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-name-column"); + writer.writeTextElement("p", QCoreApplication::translate("main", "Rules settings")); + writer.writeEndElement(); // div download-name-column + + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-path-column"); + writer.writeTextElement("p", GuhSettings(GuhSettings::SettingsRoleRules).fileName()); + writer.writeEndElement(); // div download-path-column + + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-button-column"); writer.writeStartElement("form"); + writer.writeAttribute("class", "download-button"); writer.writeAttribute("method", "get"); writer.writeAttribute("action", "/debug/settings/rules"); writer.writeStartElement("button"); + writer.writeAttribute("class", "button"); writer.writeAttribute("type", "submit"); writer.writeCharacters(QCoreApplication::translate("main", "Download")); writer.writeEndElement(); // button writer.writeEndElement(); // form - writer.writeEndElement(); // td - writer.writeEndElement(); // tr + writer.writeEndElement(); // div download-button-column - writer.writeStartElement("tr"); - writer.writeTextElement("th", QCoreApplication::translate("main", "Plugins settings")); - writer.writeTextElement("td", GuhSettings(GuhSettings::SettingsRolePlugins).fileName()); - writer.writeStartElement("td"); + writer.writeEndElement(); // div download-row + + + // Download row + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-row"); + + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-name-column"); + writer.writeTextElement("p", QCoreApplication::translate("main", "Plugins settings")); + writer.writeEndElement(); // div download-name-column + + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-path-column"); + writer.writeTextElement("p", GuhSettings(GuhSettings::SettingsRolePlugins).fileName()); + writer.writeEndElement(); // div download-path-column + + writer.writeStartElement("div"); + writer.writeAttribute("class", "download-button-column"); writer.writeStartElement("form"); + writer.writeAttribute("class", "download-button"); writer.writeAttribute("method", "get"); writer.writeAttribute("action", "/debug/settings/plugins"); writer.writeStartElement("button"); + writer.writeAttribute("class", "button"); writer.writeAttribute("type", "submit"); writer.writeCharacters(QCoreApplication::translate("main", "Download")); writer.writeEndElement(); // button writer.writeEndElement(); // form - writer.writeEndElement(); // td - writer.writeEndElement(); // tr + writer.writeEndElement(); // div download-button-column - writer.writeEndElement(); // table + writer.writeEndElement(); // div download-row - writer.writeEmptyElement("hr"); + writer.writeEndElement(); // div body - writer.writeStartElement("footer"); + + // Footer + writer.writeStartElement("div"); + writer.writeAttribute("class", "footer"); writer.writeTextElement("p", QString("Copyright %1 2018 guh GmbH.").arg(QChar(0xA9))); writer.writeTextElement("p", QCoreApplication::translate("main", "Released under the GNU GENERAL PUBLIC LICENSE Version 2.")); - writer.writeEndElement(); // footer + writer.writeEndElement(); // div footer - writer.writeEndElement(); // body + writer.writeEndElement(); // div container writer.writeEndElement(); // html @@ -364,30 +481,63 @@ QByteArray DebugServerHandler::createErrorXmlDocument(HttpReply::HttpStatusCode writer.writeStartElement("html"); writer.writeAttribute("lang", GuhCore::instance()->configuration()->locale().name()); + // Head writer.writeStartElement("head"); writer.writeEmptyElement("meta"); writer.writeAttribute("http-equiv", "Content-Type"); writer.writeAttribute("content", "text/html; charset=utf-8"); + + writer.writeEmptyElement("link"); + writer.writeAttribute("rel", "stylesheet"); + writer.writeAttribute("href", "/debug/styles.css"); + writer.writeTextElement("title", QCoreApplication::translate("main", "Debug nymea")); writer.writeEndElement(); // head - writer.writeStartElement("body"); + // Container + writer.writeStartElement("div"); + writer.writeAttribute("class", "container"); + // Header + writer.writeStartElement("div"); + writer.writeAttribute("class", "header"); + writer.writeTextElement("p", " "); writer.writeTextElement("h1", QCoreApplication::translate("main", "Error") + QString(" %1").arg(static_cast(statusCode))); - writer.writeEmptyElement("hr"); + writer.writeEndElement(); // div header - writer.writeTextElement("p", errorMessage); + // Body + writer.writeStartElement("div"); + writer.writeAttribute("class", "body"); - writer.writeEmptyElement("hr"); + // Warning + writer.writeStartElement("div"); + writer.writeAttribute("class", "warning"); + // Warning image + writer.writeStartElement("div"); + writer.writeAttribute("class", "warning-image-area"); + writer.writeEmptyElement("img"); + writer.writeAttribute("class", "warning-image"); + writer.writeAttribute("src", "/debug/warning.svg"); + writer.writeEndElement(); // div warning image + // Warning message + writer.writeStartElement("div"); + writer.writeAttribute("class", "warning-message"); + writer.writeCharacters(errorMessage); + writer.writeEndElement(); // div warning message + writer.writeEndElement(); // div warning - writer.writeStartElement("footer"); + writer.writeEndElement(); // div body + + // Footer + writer.writeStartElement("div"); + writer.writeAttribute("class", "footer"); writer.writeTextElement("p", QString("Copyright %1 2018 guh GmbH.").arg(QChar(0xA9))); writer.writeTextElement("p", QCoreApplication::translate("main", "Released under the GNU GENERAL PUBLIC LICENSE Version 2.")); - writer.writeEndElement(); // footer + writer.writeEndElement(); // div footer - writer.writeEndElement(); // body + writer.writeEndElement(); // div container writer.writeEndElement(); // html