diff options
author | Simon Rettberg | 2019-03-15 17:19:24 +0100 |
---|---|---|
committer | Simon Rettberg | 2019-03-15 17:19:24 +0100 |
commit | d58d44512321e7a369feb2dcfdb9bb88d260541b (patch) | |
tree | 9119a93ebb4e3936b134246bc3ebbceffbdda571 /modules-available | |
parent | [locationinfo] Update translations (diff) | |
download | slx-admin-d58d44512321e7a369feb2dcfdb9bb88d260541b.tar.gz slx-admin-d58d44512321e7a369feb2dcfdb9bb88d260541b.tar.xz slx-admin-d58d44512321e7a369feb2dcfdb9bb88d260541b.zip |
[statistics/roomplanner] Add SVG roomplan generator
Show in machine details if machine is part of some location's room plan.
Diffstat (limited to 'modules-available')
7 files changed, 111 insertions, 41 deletions
diff --git a/modules-available/roomplanner/api.inc.php b/modules-available/roomplanner/api.inc.php index 29c34747..1494ba28 100644 --- a/modules-available/roomplanner/api.inc.php +++ b/modules-available/roomplanner/api.inc.php @@ -1,3 +1,14 @@ <?php +if (Request::any('show') === 'svg') { + $ret = PvsGenerator::generateSvg(Request::any('locationid', 0, 'int'), + Request::any('machineuuid', false, 'string')); + if ($ret === false) { + Header('HTTP/1.1 404 Not Found'); + exit; + } + Header('Content-Type: image/svg+xml'); + die($ret); +} + die(PvsGenerator::generate()); diff --git a/modules-available/roomplanner/inc/pvsgenerator.inc.php b/modules-available/roomplanner/inc/pvsgenerator.inc.php index 5a7de9f0..4cda4582 100644 --- a/modules-available/roomplanner/inc/pvsgenerator.inc.php +++ b/modules-available/roomplanner/inc/pvsgenerator.inc.php @@ -8,12 +8,6 @@ class PvsGenerator public static function generate() { - - if (!Module::isAvailable('locations')) { - die('sorry, but the locations module is required'); - } - - /* get all rooms */ $rooms = array(); // Use left joins everywhere so we still have the complete list of locations below @@ -127,38 +121,60 @@ class PvsGenerator { $out = ""; - /* this is a virtual grid, we first need this to do some optimizations */ - $grid = array(); - /* add each contained client with position and ip */ - foreach ($machines as $machine) { - $grid[$machine['clientip']] = [$machine['gridCol'], $machine['gridRow']]; - } /* find bounding box */ - PvsGenerator::boundingBox($grid, $minX, $minY, $maxX, $maxY); + PvsGenerator::boundingBox($machines, $minX, $minY, $maxX, $maxY); $clientSizeX = 4; /* TODO: optimize */ $clientSizeY = 4; /* TODO: optimize */ $sizeX = max($maxX - $minX + $clientSizeX, 1); /* never negative */ $sizeY = max($maxY - $minY + $clientSizeY, 1); /* and != 0 to avoid divide-by-zero in pvsmgr */ - /* zoom all clients into bounding box */ - foreach ($grid as $ip => $pos) { - $newX = $grid[$ip][X] - $minX; - $newY = $grid[$ip][Y] - $minY; - $grid[$ip] = [$newX, $newY]; - } - + /* output basic settings for this room */ $out .= "gridSize=@Size($sizeX $sizeY)\n"; $out .= "clientSize=@Size($clientSizeX $clientSizeY)\n"; - $out .= "client\\size=" . count($grid) . "\n"; + $out .= "client\\size=" . count($machines) . "\n"; + /* output individual client positions, shift coordinates to origin */ $i = 1; - foreach ($grid as $ip => $pos) { - $out .= "client\\" . $i . "\\ip=$ip\n"; - $out .= "client\\" . $i++ . "\\pos=@Point(" . $pos[X] . ' ' . $pos[Y] . ")\n"; + foreach ($machines as $pos) { + $out .= "client\\$i\\ip={$pos['clientip']}\n"; + $out .= "client\\$i\\pos=@Point(" . ($pos['gridCol'] - $minX) . ' ' . ($pos['gridRow'] - $minY) . ")\n"; + $i++; } return $out; + } + /** + * Render given location's room plan as SVG + * @param int $locationId + * @param string|false $highlightUuid + * @return string SVG + */ + public static function generateSvg($locationId, $highlightUuid = false) + { + $machines = self::getMachines($locationId); + if (empty($machines)) + return false; + PvsGenerator::boundingBox($machines, $minX, $minY, $maxX, $maxY); + $clientSizeX = 4; /* TODO: optimize */ + $clientSizeY = 4; /* TODO: optimize */ + $sizeX = max($maxX - $minX + $clientSizeX, 1); /* never negative */ + $sizeY = max($maxY - $minY + $clientSizeY, 1); /* and != 0 to avoid divide-by-zero in pvsmgr */ + if (is_string($highlightUuid)) { + $highlightUuid = strtolower($highlightUuid); + } + foreach ($machines as &$machine) { + if (strtolower($machine['machineuuid']) === $highlightUuid) { + $machine['class'] = 'hl'; + } + } + return Render::parse('svg-plan', [ + 'width' => $sizeX + 2, + 'height' => $sizeY + 2, + 'minX' => $minX - 1, + 'minY' => $minY - 1, + 'machines' => $machines, + ], 'roomplanner'); // FIXME: Needs module param if called from api.inc.php } /** @@ -170,7 +186,7 @@ class PvsGenerator private static function getMachines($roomid) { $ret = Database::simpleQuery( - 'SELECT clientip, position FROM machine WHERE fixedlocationid = :locationid', + 'SELECT machineuuid, clientip, position FROM machine WHERE fixedlocationid = :locationid', ['locationid' => $roomid]); $machines = array(); @@ -181,32 +197,30 @@ class PvsGenerator if ($position === false || !isset($position['gridRow']) || !isset($position['gridCol'])) continue; // TODO: Remove entry/set to NULL? - $machine = array(); - $machine['clientip'] = $row['clientip']; - $machine['gridRow'] = $position['gridRow']; - $machine['gridCol'] = $position['gridCol']; - $machine['tutor'] = false; /* TODO: find out if machine is default tutor */ - $machine['manager'] = false; /* TODO: find out if machine is manager */ - - $machines[] = $machine; + $machines[] = array( + 'machineuuid' => $row['machineuuid'], + 'clientip' => $row['clientip'], + 'gridRow' => $position['gridRow'], + 'gridCol' => $position['gridCol'], + ); } return $machines; } - private static function boundingBox($grid, &$minX, &$minY, &$maxX, &$maxY) + private static function boundingBox($machines, &$minX, &$minY, &$maxX, &$maxY) { $minX = PHP_INT_MAX; /* PHP_INT_MIN is only available since PHP 7 */ $maxX = ~PHP_INT_MAX; $minY = PHP_INT_MAX; $maxY = ~PHP_INT_MAX; - foreach ($grid as $pos) { - $minX = min($minX, $pos[X]); - $maxX = max($maxX, $pos[X]); - $minY = min($minY, $pos[Y]); - $maxY = max($maxY, $pos[Y]); + foreach ($machines as $pos) { + $minX = min($minX, $pos['gridCol']); + $maxX = max($maxX, $pos['gridCol']); + $minY = min($minY, $pos['gridRow']); + $maxY = max($maxY, $pos['gridRow']); } } diff --git a/modules-available/roomplanner/templates/svg-plan.html b/modules-available/roomplanner/templates/svg-plan.html new file mode 100644 index 00000000..1fdb5d1a --- /dev/null +++ b/modules-available/roomplanner/templates/svg-plan.html @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + version="1.1" + viewBox="0 0 {{width}} {{height}}" + width="{{width}}mm" + height="{{height}}mm"> + <style type="text/css"> + <![CDATA[ + rect { + stroke: #000; + fill: #fff; + stroke-width: .5; + } + rect.hl { + fill: #f00; + } + ]]> + </style> + <g transform="translate(-{{minX}}, -{{minY}})"> + {{#machines}} + <rect + x="{{gridCol}}" + y="{{gridRow}}" + height="3.8" + width="3.8" + class="{{class}}" /> + {{/machines}} + </g> +</svg> diff --git a/modules-available/statistics/lang/de/template-tags.json b/modules-available/statistics/lang/de/template-tags.json index 2567eea1..c0d646e7 100644 --- a/modules-available/statistics/lang/de/template-tags.json +++ b/modules-available/statistics/lang/de/template-tags.json @@ -73,6 +73,7 @@ "lang_replaceMachinesHeading": "Rechner ersetzen", "lang_replaceNew": "Alter Rechner", "lang_replaceOld": "Neuer Rechner", + "lang_roomplan": "Raumplan", "lang_runMode": "Betriebsmodus", "lang_runmodeMachines": "Mit besonderem Betriebsmodus", "lang_runtimeHours": "Laufzeit (Stunden)", diff --git a/modules-available/statistics/lang/en/template-tags.json b/modules-available/statistics/lang/en/template-tags.json index 1d9cd4da..044c8df5 100644 --- a/modules-available/statistics/lang/en/template-tags.json +++ b/modules-available/statistics/lang/en/template-tags.json @@ -73,6 +73,7 @@ "lang_replaceMachinesHeading": "Replace machines", "lang_replaceNew": "Old machine", "lang_replaceOld": "New machine", + "lang_roomplan": "Location", "lang_runMode": "Mode of operation", "lang_runmodeMachines": "With special mode of operation", "lang_runtimeHours": "Runtime (hours)", diff --git a/modules-available/statistics/page.inc.php b/modules-available/statistics/page.inc.php index b9a3229f..d1749187 100644 --- a/modules-available/statistics/page.inc.php +++ b/modules-available/statistics/page.inc.php @@ -805,7 +805,7 @@ class Page_Statistics extends Page private function showMachine($uuid) { $client = Database::queryFirst('SELECT machineuuid, locationid, macaddr, clientip, firstseen, lastseen, logintime, lastboot, state, - mbram, live_tmpsize, live_tmpfree, live_swapsize, live_swapfree, live_memsize, live_memfree, + mbram, live_tmpsize, live_tmpfree, live_swapsize, live_swapfree, live_memsize, live_memfree, Length(position) AS hasroomplan, kvmstate, cpumodel, id44mb, data, hostname, currentuser, currentsession, notes FROM machine WHERE machineuuid = :uuid', array('uuid' => $uuid)); if ($client === false) { diff --git a/modules-available/statistics/templates/machine-main.html b/modules-available/statistics/templates/machine-main.html index b859b79a..8156f0aa 100644 --- a/modules-available/statistics/templates/machine-main.html +++ b/modules-available/statistics/templates/machine-main.html @@ -16,7 +16,7 @@ {{lang_machineSummary}} </div> <div class="panel-body"> - <table class="table table-condensed"> + <table class="table table-condensed" style="margin-bottom:-5px"> <tr> <td class="text-nowrap">{{lang_uuid}}</td> <td>{{machineuuid}}</td> @@ -88,6 +88,19 @@ </td> </tr> {{/modeid}} + {{#hasroomplan}} + <tr> + <td class="text-nowrap"> + {{lang_roomplan}} + </td> + <td class="text-center"> + <a href="?do=roomplanner&locationid={{locationid}}" target="_blank" + onclick="window.open(this.href, '_blank', 'toolbar=0,scrollbars,resizable');return false"> + <img src="api.php?do=roomplanner&show=svg&locationid={{locationid}}&machineuuid={{machineuuid}}"/> + </a> + </td> + </tr> + {{/hasroomplan}} </table> </div> </div> |