From b16e404dd98ed9536f1a048090c48fbab2225b19 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 4 Jan 2018 18:29:51 +0100 Subject: [inc/Database] Add profiling info (timing, query count) --- inc/database.inc.php | 54 ++++++++++++++++++++++++++++++++++++++++++++++------ index.php | 9 +++++++++ 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/inc/database.inc.php b/inc/database.inc.php index c1292cd8..082b13b6 100644 --- a/inc/database.inc.php +++ b/inc/database.inc.php @@ -18,6 +18,8 @@ class Database private static $returnErrors; private static $lastError = false; private static $explainList = array(); + private static $queryCount = 0; + private static $queryTime = 0; /** * Connect to the DB if not already connected. @@ -120,10 +122,11 @@ class Database public static function simpleQuery($query, $args = array(), $ignoreError = null) { self::init(); - if (CONFIG_DEBUG && preg_match('/^\s*SELECT/is', $query)) { - self::$explainList[] = [$query, $args]; + if (CONFIG_DEBUG && !isset(self::$explainList[$query]) && preg_match('/^\s*SELECT/is', $query)) { + self::$explainList[$query] = [$args]; } // Support passing nested arrays for IN statements, automagically refactor + $oquery = $query; self::handleArrayArgument($query, $args); try { if (!isset(self::$statements[$query])) { @@ -131,12 +134,24 @@ class Database } else { self::$statements[$query]->closeCursor(); } + $start = microtime(true); if (self::$statements[$query]->execute($args) === false) { self::$lastError = implode("\n", self::$statements[$query]->errorInfo()); if ($ignoreError === true || ($ignoreError === null && self::$returnErrors)) return false; Util::traceError("Database Error: \n" . self::$lastError); } + if (CONFIG_DEBUG) { + $duration = microtime(true) - $start; + self::$queryTime += $duration; + $duration = round($duration, 3); + if (isset(self::$explainList[$oquery])) { + self::$explainList[$oquery][] = $duration; + } elseif ($duration > 0.1) { + error_log('SLOW ****** ' . $duration . "s *********\n" . $query); + } + self::$queryCount += 1; + } return self::$statements[$query]; } catch (Exception $e) { self::$lastError = '(' . $e->getCode() . ') ' . $e->getMessage(); @@ -149,20 +164,35 @@ class Database public static function examineLoggedQueries() { - foreach (self::$explainList as $e) { - self::explainQuery($e[0], $e[1]); + foreach (self::$explainList as $q => $a) { + self::explainQuery($q, $a); } } - private static function explainQuery($query, $args) + private static function explainQuery($query, $data) { + $args = array_shift($data); + $slow = false; + $veryslow = false; + foreach ($data as &$ts) { + if ($ts > 0.004) { + $slow = true; + if ($ts > 0.015) { + $ts = "[$ts]"; + $veryslow = true; + } + } + } + if (!$slow) + return; + unset($ts); $res = self::simpleQuery('EXPLAIN ' . $query, $args, true); if ($res === false) return; $rows = $res->fetchAll(PDO::FETCH_ASSOC); if (empty($rows)) return; - $log = false; + $log = $veryslow; $lens = array(); foreach (array_keys($rows[0]) as $key) { $lens[$key] = strlen($key); @@ -181,6 +211,7 @@ class Database if (!$log) return; error_log('Possible slow query: ' . $query); + error_log('Times: ' . implode(', ', $data)); $border = $head = ''; foreach ($lens as $key => $len) { $border .= '+' . str_repeat('-', $len + 2); @@ -255,6 +286,7 @@ class Database public static function prepare($query) { self::init(); + self::$queryCount += 1; // Cannot know actual count return self::$dbh->prepare($query); } @@ -352,4 +384,14 @@ class Database return $res[$aiKey]; } + public static function getQueryCount() + { + return self::$queryCount; + } + + public static function getQueryTime() + { + return self::$queryTime; + } + } diff --git a/index.php b/index.php index 3322d150..d7018e17 100644 --- a/index.php +++ b/index.php @@ -12,6 +12,8 @@ if (CONFIG_SQL_PASS === '%MYSQL_OPENSLX_PASS%') { require_once('inc/user.inc.php'); +$global_start = microtime(true); + /** * Page class which all module's pages must be extending from */ @@ -213,6 +215,13 @@ if (defined('CONFIG_DEBUG') && CONFIG_DEBUG) { if (defined('CONFIG_FOOTER')) { Render::addTemplate('footer', array('text' => CONFIG_FOOTER), 'main'); } +if (CONFIG_DEBUG) { + $duration = microtime(true) - $global_start; + Render::addTemplate('footer', array('text' => + round($duration, 3) . 's, ' + . Database::getQueryCount() . ' queries, ' + . round(Database::getQueryTime(), 3) . 's query time total'), 'main'); +} Render::addTemplate('tm-callback-trigger', array(), 'main'); -- cgit v1.2.3-55-g7522 From 406cd79ff35ab1dd3ba796207f2ea471e87f17d5 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 4 Jan 2018 18:34:28 +0100 Subject: [statistics_reporting] Query rewrite: Use iterative approach Several simple test cases yielded incorrect results, also sessions partially overlapping with the selected hours were not handled properly. Iterative processing of logged events instead of single humongous unmaintainable SQL query. --- .../statistics_reporting/inc/getdata.inc.php | 142 +++--- .../statistics_reporting/inc/queries.inc.php | 512 +++++++++++++-------- .../statistics_reporting/page.inc.php | 30 +- modules-available/statistics_reporting/style.css | 9 + .../templates/table-client.html | 50 +- .../templates/table-location.html | 40 +- .../templates/table-total.html | 40 +- 7 files changed, 499 insertions(+), 324 deletions(-) diff --git a/modules-available/statistics_reporting/inc/getdata.inc.php b/modules-available/statistics_reporting/inc/getdata.inc.php index ae4d5aa4..13d39502 100644 --- a/modules-available/statistics_reporting/inc/getdata.inc.php +++ b/modules-available/statistics_reporting/inc/getdata.inc.php @@ -10,24 +10,59 @@ class GetData public static $lowerTimeBound = 0; public static $upperTimeBound = 24; public static $salt; + private static $TS_LIST = false; + private static $SECS_LIST = false; + + private static function fillLocation(&$entry, $anonymize) + { + $locations = Location::getLocationsAssoc(); + if ($anonymize) { + $entry['locationname'] = md5($entry['locationid'] . self::$salt); + } elseif (isset($locations[$entry['locationid']])) { + $entry['locationname'] = $locations[$entry['locationid']]['locationname']; + $entry['parentlocations'] = array_reduce($locations[$entry['locationid']]['parents'], function ($carry, $item) { + return $carry . sprintf("%04d", $item); + }) . sprintf("%04d", $entry['locationid']); + } else { + $entry['locationname'] = Dictionary::translate('notAssigned', true); + } + if ($anonymize) { + unset($entry['locationid']); + } + } + + private static function addPrintables(&$entry) + { + if (self::$SECS_LIST === false) { + self::$SECS_LIST = ['totalTime', 'totalOffTime', 'totalIdleTime', 'totalSessionTime', 'totalStandbyTime', 'medianSessionLength']; + } + if (self::$TS_LIST === false) { + self::$TS_LIST = ['lastStart', 'lastLogout']; + } + $perc = isset($entry['totalTime']) && $entry['totalTime'] > 0; + foreach (self::$SECS_LIST as $k) { + if (isset($entry[$k])) { + $entry[$k . '_s'] = self::formatSeconds($entry[$k]); + if ($perc && $k !== 'totalTime') { + $entry[$k . '_p'] = round($entry[$k] / $entry['totalTime'] * 100); + } + } + } + foreach (self::$TS_LIST as $k) { + if (isset($entry[$k])) { + $entry[$k . '_s'] = Util::prettyTime($entry[$k]); + } + } + } // total public static function total($flags = 0) { $printable = 0 !== ($flags & GETDATA_PRINTABLE); // total time online, average time online, total number of logins - $res = Queries::getOverallStatistics(self::$from, self::$to, self::$lowerTimeBound, self::$upperTimeBound); - $row = $res->fetch(PDO::FETCH_ASSOC); - $data = array('totalTime' => $row['sum'], 'medianSessionLength' => self::calcMedian($row['median']), 'longSessions' => $row['longSessions'], 'shortSessions' => $row['shortSessions']); - - //total time offline - $res = Queries::getTotalOfflineStatistics(self::$from, self::$to, self::$lowerTimeBound, self::$upperTimeBound); - $row = $res->fetch(PDO::FETCH_ASSOC); - $data['totalOffTime'] = $row['timeOff']; + $data = Queries::getOverallStatistics(self::$from, self::$to, self::$lowerTimeBound, self::$upperTimeBound); if ($printable) { - $data["totalTime_s"] = self::formatSeconds($data["totalTime"]); - $data["medianSessionLength_s"] = self::formatSeconds($data["medianSessionLength"]); - $data["totalOffTime_s"] = self::formatSeconds($data["totalOffTime"]); + self::addPrintables($data); } $data['uniqueUsers'] = Queries::getUniqueUserCount(self::$from, self::$to); @@ -38,63 +73,29 @@ class GetData public static function perLocation($flags = 0) { $anonymize = 0 !== ($flags & GETDATA_ANONYMOUS); $printable = 0 !== ($flags & GETDATA_PRINTABLE); - $res = Queries::getLocationStatistics(self::$from, self::$to, self::$lowerTimeBound, self::$upperTimeBound); - $data = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - self::nullToZero($row); - $median = self::calcMedian(self::calcMedian($row['medianSessionLength'])); - $entry = array( - 'location' => ($anonymize ? $row['locHash'] : $row['locName']), - 'totalTime' => $row['timeSum'], - 'medianSessionLength' => $median, - 'totalOffTime' => $row['offlineSum'], - 'longSessions' => $row['longSessions'], - 'shortSessions' => $row['shortSessions'] - ); - if (!$anonymize) { - $entry['locationId'] = $row['locId']; - } + $data = Queries::getLocationStatistics(self::$from, self::$to, self::$lowerTimeBound, self::$upperTimeBound); + foreach ($data as &$entry) { + //self::nullToZero($entry); + self::fillLocation($entry, $anonymize); if ($printable) { - $entry['totalTime_s'] = self::formatSeconds($row['timeSum']); - $entry['medianSessionLength_s'] = self::formatSeconds($median); - $entry['totalOffTime_s'] = self::formatSeconds($row['offlineSum']); + self::addPrintables($entry); } - $data[] = $entry; } return $data; } // per client - public static function perClient($flags = 0) { + public static function perClient($flags = 0, $new = false) { $anonymize = 0 !== ($flags & GETDATA_ANONYMOUS); $printable = 0 !== ($flags & GETDATA_PRINTABLE); - $res = Queries::getClientStatistics(self::$from, self::$to, self::$lowerTimeBound, self::$upperTimeBound); - $data = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - self::nullToZero($row); - $median = self::calcMedian(self::calcMedian($row['medianSessionLength'])); - $entry = array( - 'hostname' => ($anonymize ? $row['clientHash'] : $row['clientName']), - 'totalTime' => $row['timeSum'], - 'medianSessionLength' => $median, - 'totalOffTime' => $row['offlineSum'], - 'lastStart' => $row['lastStart'], - 'lastLogout' => $row['lastLogout'], - 'longSessions' => $row['longSessions'], - 'shortSessions' => $row['shortSessions'], - 'location' => ($anonymize ? $row['locHash'] : $row['locName']), - ); - if (!$anonymize) { - $entry['locationId'] = $row['locId']; - } + $data = Queries::getClientStatistics(self::$from, self::$to, self::$lowerTimeBound, self::$upperTimeBound); + foreach ($data as &$entry) { + //self::nullToZero($entry); + $entry['hostname'] = ($anonymize ? md5($entry['clientName'] . self::$salt) : $entry['clientName']); + self::fillLocation($entry, $anonymize); if ($printable) { - $entry['totalTime_s'] = self::formatSeconds($row['timeSum']); - $entry['medianSessionLength_s'] = self::formatSeconds($median); - $entry['totalOffTime_s'] = self::formatSeconds($row['offlineSum']); - $entry['lastStart_s'] = $row['lastStart'] == 0 ? "" : date(DATE_ISO8601, $row['lastStart']); - $entry['lastLogout_s'] = $row['lastLogout'] == 0 ? "" : date(DATE_ISO8601, $row['lastLogout']); + self::addPrintables($entry); } - $data[] = $entry; } return $data; } @@ -104,9 +105,11 @@ class GetData $anonymize = 0 !== ($flags & GETDATA_ANONYMOUS); $res = Queries::getUserStatistics(self::$from, self::$to, self::$lowerTimeBound, self::$upperTimeBound); $data = array(); - $user = $anonymize ? 'userHash' : 'name'; while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $data[] = array('user' => $row[$user], 'sessions' => $row['count']); + if ($anonymize && $row['name'] !== 'anonymous') { + $row['name'] = md5($row['name'] . self::$salt); + } + $data[] = array('user' => $row['name'], 'sessions' => $row['count']); } return $data; } @@ -117,10 +120,12 @@ class GetData $anonymize = 0 !== ($flags & GETDATA_ANONYMOUS); $res = Queries::getVMStatistics(self::$from, self::$to, self::$lowerTimeBound, self::$upperTimeBound); $data = array(); - $vm = $anonymize ? 'vmHash' : 'name'; while ($row = $res->fetch(PDO::FETCH_ASSOC)) { self::nullToZero($row); - $data[] = array('vm' => $row[$vm], 'sessions' => $row['count']); + if ($anonymize) { + $row['name'] = md5($row['name'] . self::$salt); + } + $data[] = array('vm' => $row['name'], 'sessions' => $row['count']); } return $data; } @@ -140,19 +145,4 @@ class GetData return sprintf('%dd, %02d:%02d:%02d', $seconds / (3600*24), ($seconds % (3600*24)) / 3600, ($seconds%3600) / 60, $seconds%60); } - // Calculate Median - private static function calcMedian($string) { - $arr = explode(",", $string); - sort($arr, SORT_NUMERIC); - $count = count($arr); //total numbers in array - $middleval = floor(($count-1)/2); // find the middle value, or the lowest middle value - if($count % 2) { // odd number, middle is the median - $median = $arr[(int) $middleval]; - } else { // even number, calculate avg of 2 medians - $low = $arr[(int) $middleval]; - $high = $arr[(int) $middleval+1]; - $median = (($low+$high)/2); - } - return round($median); - } } \ No newline at end of file diff --git a/modules-available/statistics_reporting/inc/queries.inc.php b/modules-available/statistics_reporting/inc/queries.inc.php index bd8eb72e..395bb548 100644 --- a/modules-available/statistics_reporting/inc/queries.inc.php +++ b/modules-available/statistics_reporting/inc/queries.inc.php @@ -4,214 +4,342 @@ class Queries { - // Client Data: Name, Time Online, Median Time Online, Time Offline, last start, last logout, Last Time Booted, Number of Sessions > 60Sec, Number of Sessions < 60Sec, name of location, id of location (anonymized), machine uuid (anonymized) - public static function getClientStatistics($from, $to, $lowerTimeBound = 0, $upperTimeBound = 24) { - $notassigned = Dictionary::translate('notAssigned', true); - Database::exec("SET SESSION group_concat_max_len = 1000000000"); - $res = Database::simpleQuery("SELECT t2.name AS clientName, timeSum, medianSessionLength, offlineSum, IFNULL(lastStart, 0) as lastStart, IFNULL(lastLogout, 0) as lastLogout, longSessions, shortSessions, t2.locId, t2.locName, MD5(CONCAT(t2.locId, :salt)) AS locHash, MD5(CONCAT(t2.uuid, :salt)) AS clientHash FROM ( - SELECT machine.machineuuid AS 'uuid', SUM(CAST(sessionTable.length AS UNSIGNED)) AS 'timeSum', GROUP_CONCAT(sessionTable.length) AS 'medianSessionLength', SUM(sessionTable.length >= 60) AS 'longSessions', SUM(sessionTable.length < 60) AS 'shortSessions', MAX(sessionTable.endInBound) AS 'lastLogout' - FROM ".self::getBoundedTableQueryString('~session-length', $from, $to, $lowerTimeBound, $upperTimeBound)." sessionTable - RIGHT JOIN machine ON sessionTable.machineuuid = machine.machineuuid - GROUP BY machine.machineuuid - ) t1 - RIGHT JOIN ( - SELECT IF(machine.hostname = '', machine.clientip, machine.hostname) AS 'name', machine.machineuuid AS 'uuid', SUM(CAST(offlineTable.length AS UNSIGNED)) AS 'offlineSum', MAX(offlineTable.endInBound) AS 'lastStart', IFNULL(location.locationname, '$notassigned') AS 'locName', location.locationid AS 'locId' - FROM ".self::getBoundedTableQueryString('~offline-length', $from, $to, $lowerTimeBound, $upperTimeBound)." offlineTable - RIGHT JOIN machine ON offlineTable.machineuuid = machine.machineuuid - LEFT JOIN location ON machine.locationid = location.locationid - GROUP BY machine.machineuuid - ) t2 - ON t1.uuid = t2.uuid", array("salt" => GetData::$salt)); + private static function keepKeys(&$array, $list) + { + foreach (array_keys($array) as $key) { + if (!in_array($key, $list)) { + unset($array[$key]); + } + } + } - return $res; + public static function getClientStatistics($from, $to, $lowerTimeBound = 0, $upperTimeBound = 24) + { + $res = Database::simpleQuery("SELECT m.machineuuid, m.hostname, m.clientip, + m.locationid, m.firstseen -- , m.lastboot, m.logintime, m.state + FROM machine m WHERE firstseen <= $to"); // " WHERE lastseen >= :from", compact('from')); + $machines = self::getStats3($res, $from, $to, $lowerTimeBound, $upperTimeBound); + foreach ($machines as &$machine) { + $machine['medianSessionLength'] = self::calcMedian($machine['sessions']); + unset($machine['sessions']); + $machine['clientName'] = $machine['hostname'] ? $machine['hostname'] : $machine['clientip']; + } + return $machines; } - // Location Data: Name, ID (anonymized), Time Online, Median Time Online, Time Offline, Number of Sessions > 60Sec, Number of Sessions < 60Sec - public static function getLocationStatistics($from, $to, $lowerTimeBound = 0, $upperTimeBound = 24) { - $notassigned = Dictionary::translate('notAssigned', true); - Database::exec("SET SESSION group_concat_max_len = 1000000000"); - $res = Database::simpleQuery("SELECT t2.locId, t2.locName, MD5(CONCAT(t2.locId, :salt)) AS locHash, timeSum, medianSessionLength, offlineSum, longSessions, shortSessions FROM ( - SELECT location.locationid AS 'locId', SUM(CAST(sessionTable.length AS UNSIGNED)) AS 'timeSum', GROUP_CONCAT(sessionTable.length) AS 'medianSessionLength', SUM(sessionTable.length >= 60) AS 'longSessions', SUM(sessionTable.length < 60) AS 'shortSessions' - FROM ".self::getBoundedTableQueryString('~session-length', $from, $to, $lowerTimeBound, $upperTimeBound)." sessionTable - RIGHT JOIN machine ON sessionTable.machineuuid = machine.machineuuid - LEFT JOIN location ON machine.locationid = location.locationid - GROUP BY machine.locationid - ) t1 - RIGHT JOIN ( - SELECT IFNULL(location.locationname, '$notassigned') AS 'locName', location.locationid AS 'locId', SUM(CAST(offlineTable.length AS UNSIGNED)) AS 'offlineSum' - FROM ".self::getBoundedTableQueryString('~offline-length', $from, $to, $lowerTimeBound, $upperTimeBound)." offlineTable - RIGHT JOIN machine ON offlineTable.machineuuid = machine.machineuuid - LEFT JOIN location ON machine.locationid = location.locationid - GROUP BY machine.locationid - ) t2 - ON t1.locId = t2.locId", array("salt" => GetData::$salt)); - return $res; + public static function getLocationStatistics($from, $to, $lowerTimeBound = 0, $upperTimeBound = 24) + { + $res = Database::simpleQuery("SELECT m.machineuuid, m.hostname, m.clientip, + m.locationid, m.firstseen -- , m.lastboot, m.logintime, m.state + FROM machine m WHERE firstseen <= $to"); // " WHERE lastseen >= :from", compact('from')); + $machines = self::getStats3($res, $from, $to, $lowerTimeBound, $upperTimeBound); + $locations = []; + $keys = ['locationid', 'totalTime', 'totalOffTime', 'totalSessionTime', 'totalStandbyTime', 'totalIdleTime', 'totalIdleTime', 'longSessions', 'shortSessions', 'sessions']; + while ($machine = array_pop($machines)) { + if (!isset($locations[$machine['locationid']])) { + self::keepKeys($machine, $keys); + $locations[$machine['locationid']] = $machine; + } else { + $l =& $locations[$machine['locationid']]; + $l['totalTime'] += $machine['totalTime']; + $l['totalOffTime'] += $machine['totalOffTime']; + $l['totalSessionTime'] += $machine['totalSessionTime']; + $l['totalStandbyTime'] += $machine['totalStandbyTime']; + $l['totalIdleTime'] += $machine['totalIdleTime']; + $l['longSessions'] += $machine['longSessions']; + $l['shortSessions'] += $machine['shortSessions']; + $l['sessions'] = array_merge($l['sessions'], $machine['sessions']); + } + } + foreach ($locations as &$location) { + $location['medianSessionLength'] = self::calcMedian($location['sessions']); + unset($location['sessions']); + } + return $locations; } - // User Data: Name, Name(anonymized), Number of Logins - public static function getUserStatistics($from, $to, $lowerTimeBound = 0, $upperTimeBound = 24) { - $res = Database::simpleQuery("SELECT username AS name, IF(username = 'anonymous', 'anonymous', md5(CONCAT(username, :salt))) AS userHash, COUNT(*) AS 'count' - FROM statistic - WHERE typeid='.vmchooser-session-name' AND dateline >= $from and dateline <= $to - AND FROM_UNIXTIME(dateline, '%H') >= $lowerTimeBound AND FROM_UNIXTIME(dateline, '%H') < $upperTimeBound - GROUP BY username - ORDER BY 2 DESC", array("salt" => GetData::$salt)); - return $res; + public static function getOverallStatistics($from, $to, $lowerTimeBound = 0, $upperTimeBound = 24) + { + $res = Database::simpleQuery("SELECT m.machineuuid, m.hostname, m.clientip, + m.locationid, m.firstseen -- , m.lastboot, m.logintime, m.state + FROM machine m WHERE firstseen <= $to"); // " WHERE lastseen >= :from", compact('from')); + $machines = self::getStats3($res, $from, $to, $lowerTimeBound, $upperTimeBound); + $total = false; + $keys = ['totalTime', 'totalOffTime', 'totalSessionTime', 'totalStandbyTime', 'totalIdleTime', 'totalIdleTime', 'longSessions', 'shortSessions', 'sessions']; + while ($machine = array_pop($machines)) { + if ($total === false) { + self::keepKeys($machine, $keys); + $total = $machine; + } else { + $total['totalTime'] += $machine['totalTime']; + $total['totalOffTime'] += $machine['totalOffTime']; + $total['totalSessionTime'] += $machine['totalSessionTime']; + $total['totalStandbyTime'] += $machine['totalStandbyTime']; + $total['totalIdleTime'] += $machine['totalIdleTime']; + $total['longSessions'] += $machine['longSessions']; + $total['shortSessions'] += $machine['shortSessions']; + $total['sessions'] = array_merge($total['sessions'], $machine['sessions']); + } + } + $total['medianSessionLength'] = self::calcMedian($total['sessions']); + unset($total['sessions']); + return $total; } - // Virtual Machine Data: Name, Number of Usages - public static function getVMStatistics($from, $to, $lowerTimeBound = 0, $upperTimeBound = 24) { - $res = Database::simpleQuery("SELECT data AS name, MD5(CONCAT(data, :salt)) AS vmHash, COUNT(*) AS 'count' - FROM statistic - WHERE typeid='.vmchooser-session-name' AND dateline >= $from and dateline <= $to - AND FROM_UNIXTIME(dateline, '%H') >= $lowerTimeBound AND FROM_UNIXTIME(dateline, '%H') < $upperTimeBound - GROUP BY data - ORDER BY 2 DESC", array("salt" => GetData::$salt)); - return $res; + /** + * @param \PDOStatement $res + * @param int $from + * @param int $to + * @param int $lowerTimeBound + * @param int $upperTimeBound + * @return array + */ + private static function getStats3($res, $from, $to, $lowerTimeBound, $upperTimeBound) + { + //$debug = false; + if ($lowerTimeBound === 0 && $upperTimeBound === 24 || $upperTimeBound <= $lowerTimeBound) { + $bounds = false; + } else { + $bounds = [$lowerTimeBound, $upperTimeBound]; + } + $machines = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $row['firstseen'] = max($row['firstseen'], $from); + $row += array( + 'totalTime' => self::timeDiff($row['firstseen'], $to, $bounds), + 'totalOffTime' => 0, + 'totalSessionTime' => 0, + 'totalStandbyTime' => 0, + 'sessions' => [], + 'lastStart' => 0, + 'lastLogout' => 0, + 'longSessions' => 0, + 'shortSessions' => 0, + 'active' => false, + ); + $machines[$row['machineuuid']] = $row; + } + // Don't filter by typeid in the query, still faster by being able to use the machineuuid/dateline index and filtering later + $last = $from - 86400; // Start 24h early to catch sessions already in progress + $dups = []; + // Fetch in batches of 1000 rows (for current 50 machines) + do { + $res = Database::simpleQuery("SELECT logid, dateline, typeid, machineuuid, data + FROM statistic WHERE dateline >= :last AND dateline <= :to AND machineuuid IS NOT NULL + ORDER BY dateline ASC LIMIT 1000", compact('last', 'to')); + $last = false; + $count = 0; + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $count += 1; // Update count first, as we use it as a condition in outer loop. No continue before this + settype($row['logid'], 'int'); + // Update for next query + $last = $row['dateline']; + // Ignore dups, we query >= last dateline as we can have multiple events at the same second, but + // only some of them got returned because of LIMIT. Skip here because excluding in query directly + // would make the query itself rather inefficient. We also cannot use logid > X because the logid + // is not strictly ascending with time, as dateline gets backdated to event start on insert + if ($count === 150) { + $dups = []; + } elseif ($count > 900) { + $dups[] = $row['logid']; + } elseif ($count < 150 && array_key_exists($row['logid'], $dups)) { + continue; + } + if (!isset($machines[$row['machineuuid']])) + continue; + if ($row['typeid'] !== '~offline-length' && $row['typeid'] !== '~suspend-length' && $row['typeid'] !== '~session-length') + continue; + settype($row['dateline'], 'int'); + settype($row['data'], 'int'); + if ($row['data'] <= 0) + continue; + // Clamp to $from and $to + if ($row['dateline'] < $from) { + $diff = $row['dateline'] + $row['data'] - $from; + if ($diff <= 0) + continue; + $row['dateline'] += $diff; + $row['data'] -= $diff; + } + if ($row['dateline'] + $row['data'] > $to) { + $row['data'] = $to - $row['dateline']; + if ($row['data'] < 0) + continue; + } + $machine =& $machines[$row['machineuuid']]; + // Process event if applicable + if ($row['typeid'] === '~session-length') { // SESSION timespan + $row['typeid'] = 'totalSessionTime'; + $machine['lastLogout'] = $row['dateline'] + $row['data']; + } elseif ($row['typeid'] === '~offline-length') { // OFFLINE timespan + $row['typeid'] = 'totalOffTime'; + $machine['lastStart'] = $row['dateline'] + $row['data']; + } else { // STANDBY timespan + $row['typeid'] = 'totalStandbyTime'; + } + self::addTime($machine, $row, $bounds); + } + $dups = array_flip($dups); + } while ($last !== false && $count === 1000); // Check if we need to fetch more rows for current batch + foreach ($machines as &$machine) { + if (!$machine['active']) { + $machine['totalOffTime'] = $machine['totalTime']; + } + $machine['totalIdleTime'] = $machine['totalTime'] - ($machine['totalOffTime'] + $machine['totalStandbyTime'] + $machine['totalSessionTime']); + } + return $machines; } - //Total Data: Time Online, Median Time Online, Number of Sessions > 60Sec, Number of Sessions < 60Sec - public static function getOverallStatistics ($from, $to, $lowerTimeBound = 0, $upperTimeBound = 24) { - Database::exec("SET SESSION group_concat_max_len = 1000000000"); - $res = Database::simpleQuery("SELECT SUM(CAST(sessionTable.length AS UNSIGNED)) AS sum, GROUP_CONCAT(sessionTable.length) AS median, SUM(sessionTable.length >= 60) AS longSessions, SUM(sessionTable.length < 60) AS shortSessions - FROM ".self::getBoundedTableQueryString('~session-length', $from, $to, $lowerTimeBound, $upperTimeBound)." sessionTable"); - return $res; + private static function addTime(&$machine, $row, $bounds) + { + // First event, handle difference + if (!$machine['active'] && $row['dateline'] + $row['data'] >= $machine['firstseen']) { + if ($row['dateline'] > $machine['firstseen']) { + $s = $machine['firstseen']; + $e = $row['dateline']; + /* + if ($debug) { + error_log('Initial offline time += ' . self::timeDiff($s, $e, $bounds, true)); + } + */ + $machine['totalOffTime'] += self::timeDiff($s, $e, $bounds); + $machine['active'] = true; + if ($machine['lastStart'] < $row['dateline']) { + $machine['lastStart'] = $row['dateline']; + } + } else { + // Not offline at beginning of period, do nothing + $machine['active'] = true; + } + } + // Current row + if ($bounds === false) { + // Simple case: No bounds + $machine[$row['typeid']] += $row['data']; + } else { + $start = $row['dateline']; + $end = $row['dateline'] + $row['data']; + /* + if ($debug) { + error_log('Adding ' . $row['typeid'] . ' += ' . self::timeDiff($start, $end, $bounds, true)); + } + */ + $machine[$row['typeid']] += self::timeDiff($start, $end, $bounds); + $sh = date('G', $start); + } + if ($row['typeid'] === 'totalSessionTime' && ($bounds === false || ($sh >= $bounds[0] && $sh < $bounds[1]))) { + if ($row['data'] >= 60) { + $machine['longSessions'] += 1; + $machine['sessions'][] = $row['data']; + } else { + $machine['shortSessions'] += 1; + } + } } - // Total Data(2): Time Offline - public static function getTotalOfflineStatistics($from, $to, $lowerTimeBound = 0, $upperTimeBound = 24) { - $res = Database::simpleQuery("SELECT SUM(CAST(offlineTable.length AS UNSIGNED)) AS timeOff - FROM ".self::getBoundedTableQueryString('~offline-length', $from, $to, $lowerTimeBound, $upperTimeBound)." offlineTable"); - return $res; + private static function timeDiff($start, $end, $bounds) + { + // Put given timespan into bounds + /* + if ($debug) { + $os = $start; + $oe = $end; + } + */ + if ($bounds !== false) { + // Put start time into bounds + if ($start !== null) { + $sh = date('G', $start); + if ($sh < $bounds[0]) { + $start = strtotime($bounds[0] . ':00:00', $start); + } elseif ($sh >= $bounds[1]) { + $start = strtotime($bounds[0] . ':00:00 +1day', $start); + } + } + // Put end time into bounds + if ($end !== null && $end > $start) { + $eh = date('G', $end); + if ($eh < $bounds[0]) { + $end = strtotime($bounds[1] . ':00:00 -1day', $end); + } elseif ($eh >= $bounds[1]) { + $end = strtotime($bounds[1] . ':00:00', $end); + } + } + } + if ($end !== null && $start !== null && $end < $start) { + $end = $start; + } + /* + if ($debug) { + if ($start >= $end) { + error_log('END < START: ' . date('d.m.Y H:i:s', $start) . ' - ' . date('d.m.Y H:i:s', $end)); + } else { + if ($os != $start) { + error_log('Corrected start: ' . date('d.m.Y H:i:s', $os) . ' to ' . date('d.m.Y H:i:s', $start)); + } + if ($oe != $end) { + error_log('Corrected end : ' . date('d.m.Y H:i:s', $oe) . ' to ' . date('d.m.Y H:i:s', $end)); + } + } + } + */ + // Calc time excluding out of range hours + return ($end - $start) - self::getIgnoredTime($start, $end, $bounds); } - // query string which provides table with time-cutoff and time-bounds - private static function getBoundedTableQueryString($typeid, $from, $to, $lowerTimeBound, $upperTimeBound) + private static function getIgnoredTime($start, $end, $bounds) { - // get Clients that are currently oflfine (the offline time is not yet recorded in the statistic table) - $union = $typeid == '~offline-length' ? - "union - select CAST(IF(lastseen < $from, $from, lastseen) as UNSIGNED) as start, $to as end, - '~offline-length' as typeid, machineuuid, 'machine' - from machine where lastseen <= $to and UNIX_TIMESTAMP() - lastseen >= 600" : ""; + if ($bounds === false || $start >= $end) + return 0; + $end = strtotime('00:00:00', $end); + if ($start >= $end) + return 0; + /* + if ($debug) { + error_log('From ' . date('d.m.Y H:i:s', $start) . ' to ' . date('d.m.Y H:i:s', $end) . ' = ' . ceil(($end - $start) / 86400) * (24 - ($bounds[1] - $bounds[0]))); + } + */ + return (int)ceil(($end - $start) / 86400) * (24 - ($bounds[1] - $bounds[0])) * 3600; + } + + /** + * Get median of array. + * @param int[] list of values + * @return int The median + */ + private static function calcMedian($array) { + if (empty($array)) + return 0; + sort($array, SORT_NUMERIC); + $count = count($array); //total numbers in array + $middleval = (int)floor(($count-1) / 2); // find the middle value, or the lowest middle value + if($count % 2 === 1) { // odd number, middle is the median + return (int)$array[$middleval]; + } + // even number, calculate avg of 2 medians + $low = $array[$middleval]; + $high = $array[$middleval+1]; + return (int)round(($low+$high) / 2); + } + // User Data: Name, Name(anonymized), Number of Logins + public static function getUserStatistics($from, $to, $lowerTimeBound = 0, $upperTimeBound = 24) { + $res = Database::simpleQuery("SELECT username AS name, COUNT(*) AS 'count' + FROM statistic + WHERE typeid='.vmchooser-session-name' AND dateline >= :from and dateline <= :to + AND FROM_UNIXTIME(dateline, '%H') >= :lowerTimeBound AND FROM_UNIXTIME(dateline, '%H') < :upperTimeBound + GROUP BY username", compact('from', 'to', 'lowerTimeBound', 'upperTimeBound')); + return $res; + } - $lowerFormat = "'%y-%m-%d $lowerTimeBound:00:00'"; - $upperFormat = "'%y-%m-%d ".($upperTimeBound-1).":59:59'"; - $queryString = " - select - - # The whole length of the session/offline time. - (end-start - - # Now the time that is not within the daily time bounds is subtracted. - # This includes the time before the first daily bound, the time after the last daily bound - # and the time between the daily bounds (if a session/offline time spans multiple days) - - # Time before the first daily bound is subtracted. - - IF( - start > startUpper, - UNIX_TIMESTAMP(FROM_UNIXTIME(start, $lowerFormat) + INTERVAL 1 DAY) - start, - IF( - start < startLower, - startLower - start, - 0 - ) - ) - - # Time after the last daily bound is subtracted. - - IF( - end > endUpper, - end - (endUpper + 1), - IF( - end < endLower, - end - (UNIX_TIMESTAMP(FROM_UNIXTIME(end, $upperFormat) - INTERVAL 1 DAY) + 1), - 0 - ) - ) - - # Time between the daily bounds is subtracted. - - ( daysDiff - 2 - + IF(start <= startUpper, 1, 0) - + IF(end >= endLower, 1, 0) - ) * ((24 - ($upperTimeBound - $lowerTimeBound)) * 3600) - - # If the session crossed a clock change (to/from daylight saving time), the last subtraction may have subtracted - # one hour too much or too little. This IF will correct this. - - IF( - innerStart < innerEnd, - IF( - timeDiff = 1 AND ($lowerTimeBound >= 2 OR $upperTimeBound <= 2), - 3600, - IF(timeDiff = -1 AND ($lowerTimeBound >= 3 OR $upperTimeBound <= 3), -3600, 0) - ), - 0 - ) - - ) as 'length', - - IF(end < endUpper AND end > endLower AND end < $to, end, 0) as endInBound, - - machineuuid - - - # These nested selects are necessary because some things need to be calculated before others. - # (e.g. start is needed to calculate startLower) - from ( - select - *, - - # timeDiff is the clock change between innerStart and innerEnd. ( 0 = no clock change) - ((CAST(date_format(from_unixtime(innerStart), '%H') as SIGNED) - - CAST(date_format(convert_tz(from_unixtime(innerStart), @@session.time_zone, '+00:00'), '%H') as SIGNED) + 24) % 24 - - - (CAST(date_format(from_unixtime(innerEnd), '%H') as SIGNED) - - CAST(date_format(convert_tz(from_unixtime(innerEnd), @@session.time_zone, '+00:00'), '%H') as SIGNED) + 24) % 24) as timeDiff - from ( - select - *, - - # innerStart and innerEnd are start and end but excluding the time before the first daily upper bound and after the last daily lower bound. - CAST(IF(start <= startUpper, startUpper, UNIX_TIMESTAMP(FROM_UNIXTIME(start, $upperFormat) + INTERVAL 1 DAY)) as UNSIGNED) as innerStart, - CAST(IF(end >= endLower, endLower, UNIX_TIMESTAMP(FROM_UNIXTIME(end, $lowerFormat) - INTERVAL 1 DAY)) as UNSIGNED) as innerEnd - from ( - select - *, - - # daysDiff = how many different days the start and end are apart (0 = start and end on the same day) - (TO_DAYS(FROM_UNIXTIME(end, '%y-%m-%d')) - TO_DAYS(FROM_UNIXTIME(start, '%y-%m-%d'))) as daysDiff, - - # startLower = lower daily time bound on the starting day - CAST(UNIX_TIMESTAMP(FROM_UNIXTIME(start, $lowerFormat)) as UNSIGNED) as startLower, - # startUpper = upper daily time bound on the starting day - CAST(UNIX_TIMESTAMP(FROM_UNIXTIME(start, $upperFormat)) as UNSIGNED) as startUpper, - # endLower = lower daily time bound on the ending day - CAST(UNIX_TIMESTAMP(FROM_UNIXTIME(end, $lowerFormat)) as UNSIGNED) as endLower, - # endUpper = upper daily time bound on the ending day - CAST(UNIX_TIMESTAMP(FROM_UNIXTIME(end, $upperFormat)) as UNSIGNED) as endUpper - from ( - # Statistic logs (combined with currently offline machines if offline times are requested) . - select CAST(IF(dateline < $from, $from, dateline) as UNSIGNED) as start, - CAST(IF(dateline+data > $to, $to, dateline+data) as UNSIGNED) as end, - typeid, machineuuid, 'statistic' - from statistic where dateline+data >= $from and dateline <= $to and typeid = '$typeid' - $union - ) t - ) t - ) t - ) t - - - # Filter out the session that are at least overlapping with the time bounds. - where ( - (daysDiff = 0 and (start <= UNIX_TIMESTAMP(FROM_UNIXTIME(start, $upperFormat)) and end >= UNIX_TIMESTAMP(FROM_UNIXTIME(end, $lowerFormat)))) - or - (daysDiff = 1 and (start <= UNIX_TIMESTAMP(FROM_UNIXTIME(start, $upperFormat)) or end >= UNIX_TIMESTAMP(FROM_UNIXTIME(end, $lowerFormat)))) - or - daysDiff >= 2 - ) - "; - return "(".$queryString.")"; + // Virtual Machine Data: Name, Number of Usages + public static function getVMStatistics($from, $to, $lowerTimeBound = 0, $upperTimeBound = 24) { + $res = Database::simpleQuery("SELECT data AS name, COUNT(*) AS 'count' + FROM statistic + WHERE typeid='.vmchooser-session-name' AND dateline >= :from and dateline <= :to + AND FROM_UNIXTIME(dateline, '%H') >= :lowerTimeBound AND FROM_UNIXTIME(dateline, '%H') < :upperTimeBound + GROUP BY data", compact('from', 'to', 'lowerTimeBound', 'upperTimeBound')); + return $res; } public static function getDozmodStats($from, $to) diff --git a/modules-available/statistics_reporting/page.inc.php b/modules-available/statistics_reporting/page.inc.php index 863715d4..b30b5cab 100644 --- a/modules-available/statistics_reporting/page.inc.php +++ b/modules-available/statistics_reporting/page.inc.php @@ -24,8 +24,8 @@ class Page_Statistics_Reporting extends Page /** * @var array Names of columns that are being used by the various tables */ - private $COLUMNS = array('location', 'totalTime', 'medianSessionLength', 'sessions', 'longSessions', 'shortSessions', - 'totalOffTime', 'lastLogout', 'lastStart'); + private $COLUMNS = array('locationname', 'totalTime', 'medianSessionLength', 'sessions', 'longSessions', 'shortSessions', + 'totalOffTime', 'totalStandbyTime', 'totalSessionTime', 'totalIdleTime', 'lastLogout', 'lastStart'); /** * @var array Names of the tables we can display @@ -56,10 +56,16 @@ class Page_Statistics_Reporting extends Page } // timespan you want to see. default = last 7 days - GetData::$from = strtotime("- " . ($this->days - 1) . " days 00:00:00"); + GetData::$from = strtotime("-" . ($this->days - 1) . " days 00:00:00"); GetData::$to = time(); GetData::$lowerTimeBound = $this->lower; GetData::$upperTimeBound = $this->upper; + /* + GetData::$from = strtotime("2017-12-01 00:00:00"); + GetData::$to = strtotime("2017-12-15 00:00:00"); + GetData::$lowerTimeBound = 1; + GetData::$upperTimeBound = 2; + */ // Export - handle in doPreprocess so we don't render the menu etc. if ($this->action === 'export') { @@ -193,20 +199,20 @@ class Page_Statistics_Reporting extends Page if (Request::get('col_' . $column, 'delete', 'string') === 'delete') { foreach ($res as &$row) { unset($row[$column], $row[$column . '_s']); - if ($column === 'location') { - unset($row['locationId']); + if ($column === 'locationname') { + unset($row['locationid']); } } } elseif ($printable && isset($row[0][$column . '_s'])) { foreach ($res as &$row) { unset($row[$column]); } - } elseif ($column === 'location' && (isset($res[0]['location']) || isset($res[0]['locationId']))) { + } elseif ($column === 'locationname' && (isset($res[0]['locationname']) || isset($res[0]['locationid']))) { foreach ($res as &$row) { if ($printable) { - unset($row['locationId']); + unset($row['locationid']); } else { - unset($row['location']); + unset($row['locationname']); } } } @@ -285,7 +291,7 @@ class Page_Statistics_Reporting extends Page $highlight = Request::get('location', false, 'int'); if ($highlight !== false) { foreach ($data as &$row) { - if ($row['locationId'] == $highlight) { + if ($row['locationid'] == $highlight) { $row['highlight'] = true; } } @@ -293,7 +299,7 @@ class Page_Statistics_Reporting extends Page // only show locations which you have permission for $filterLocs = User::getAllowedLocations("table.view.location"); foreach ($data as $key => $row) { - if (!in_array($row['locationId'], $filterLocs)) { + if (!in_array($row['locationid'], $filterLocs)) { unset($data[$key]); } } @@ -301,11 +307,11 @@ class Page_Statistics_Reporting extends Page $data = array_values($data); return $data; case 'client': - $data = GetData::perClient($flags); + $data = GetData::perClient($flags, Request::any('new', false, 'string')); // only show clients from locations which you have permission for $filterLocs = User::getAllowedLocations("table.view.location"); foreach ($data as $key => $row) { - if (!in_array($row['locationId'], $filterLocs)) { + if (!in_array($row['locationid'], $filterLocs)) { unset($data[$key]); } } diff --git a/modules-available/statistics_reporting/style.css b/modules-available/statistics_reporting/style.css index 3cd6653f..c732099d 100644 --- a/modules-available/statistics_reporting/style.css +++ b/modules-available/statistics_reporting/style.css @@ -35,4 +35,13 @@ margin-left: -1.5em; text-align: center; line-height: 1.6em; +} + +.table-nowrap td { + white-space: nowrap; +} + +td.p-addon { + padding: 5px 5px 5px 0 !important; + text-align: right; } \ No newline at end of file diff --git a/modules-available/statistics_reporting/templates/table-client.html b/modules-available/statistics_reporting/templates/table-client.html index 59153e01..a23c2f89 100644 --- a/modules-available/statistics_reporting/templates/table-client.html +++ b/modules-available/statistics_reporting/templates/table-client.html @@ -1,29 +1,43 @@ - +
- - - - - - - - - + + + + + + + + + + + + + + + + {{#data}} - - - - - - - - + + + + + + + + + + + + + + + {{/data}} diff --git a/modules-available/statistics_reporting/templates/table-location.html b/modules-available/statistics_reporting/templates/table-location.html index a0867208..4e470d1e 100644 --- a/modules-available/statistics_reporting/templates/table-location.html +++ b/modules-available/statistics_reporting/templates/table-location.html @@ -1,23 +1,37 @@ -
{{lang_hostname}}{{lang_location}}{{lang_totalTime}}{{lang_medianSessionLength}}{{lang_longSessions}}{{lang_shortSessions}}{{lang_totalOffTime}}{{lang_lastLogout}}{{lang_lastStart}}{{lang_hostname}}{{lang_location}}{{lang_totalTime}}{{lang_medianSessionLength}}{{lang_longSessions}}{{lang_shortSessions}}{{lang_totalOffTime}}(%){{lang_totalStandbyTime}}(%){{lang_totalSessionTime}}(%){{lang_totalIdleTime}}(%){{lang_lastLogout}}{{lang_lastStart}}
{{hostname}}{{location}}{{totalTime_s}}{{medianSessionLength_s}}{{longSessions}}{{shortSessions}}{{totalOffTime_s}}{{lastLogout_s}}{{lastStart_s}}{{locationname}}{{totalTime_s}}{{medianSessionLength_s}}{{longSessions}}{{shortSessions}}{{totalOffTime_s}}{{totalOffTime_p}} %{{totalStandbyTime_s}}{{totalStandbyTime_p}} %{{totalSessionTime_s}}{{totalSessionTime_p}} %{{totalIdleTime_s}}{{totalIdleTime_p}} %{{lastLogout_s}}{{lastStart_s}}
+
- - - - - - + + + + + + + + + + + + + {{#data}} - - - - - - + + + + + + + + + + + + + {{/data}} diff --git a/modules-available/statistics_reporting/templates/table-total.html b/modules-available/statistics_reporting/templates/table-total.html index 8d5d7571..83078714 100644 --- a/modules-available/statistics_reporting/templates/table-total.html +++ b/modules-available/statistics_reporting/templates/table-total.html @@ -1,22 +1,36 @@ -
{{lang_location}}{{lang_totalTime}}{{lang_medianSessionLength}}{{lang_longSessions}}{{lang_shortSessions}}{{lang_totalOffTime}}{{lang_location}}{{lang_totalTime}}{{lang_medianSessionLength}}{{lang_longSessions}}{{lang_shortSessions}}{{lang_totalOffTime}}(%){{lang_totalStandbyTime}}(%){{lang_totalSessionTime}}(%){{lang_totalIdleTime}}(%)
{{location}}{{totalTime_s}}{{medianSessionLength_s}}{{longSessions}}{{shortSessions}}{{totalOffTime_s}}{{locationname}}{{totalTime_s}}{{medianSessionLength_s}}{{longSessions}}{{shortSessions}}{{totalOffTime_s}}{{totalOffTime_p}} %{{totalStandbyTime_s}}{{totalStandbyTime_p}} %{{totalSessionTime_s}}{{totalSessionTime_p}} %{{totalIdleTime_s}}{{totalIdleTime_p}} %
+
- - - - - - + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + +
{{lang_totalTime}}{{lang_medianSessionLength}}{{lang_longSessions}}{{lang_shortSessions}}{{lang_totalOffTime}}{{lang_totalTime}}{{lang_medianSessionLength}}{{lang_longSessions}}{{lang_shortSessions}}{{lang_totalOffTime}}(%){{lang_totalStandbyTime}}(%){{lang_totalSessionTime}}(%){{lang_totalIdleTime}}(%)
{{lang_total}}{{data.totalTime_s}}{{data.medianSessionLength_s}}{{data.longSessions}}{{data.shortSessions}}{{data.totalOffTime_s}}{{lang_total}}{{data.totalTime_s}}{{data.medianSessionLength_s}}{{data.longSessions}}{{data.shortSessions}}{{data.totalOffTime_s}}{{data.totalOffTime_p}} %{{data.totalStandbyTime_s}}{{data.totalStandbyTime_p}} %{{data.totalSessionTime_s}}{{data.totalSessionTime_p}} %{{data.totalIdleTime_s}}{{data.totalIdleTime_p}} %
-- cgit v1.2.3-55-g7522 From aab6b6b40519bbbe907919c4e82ab49c76f83974 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 8 Jan 2018 12:49:32 +0100 Subject: [statistics_reporting] Don't leak locationid in remote report --- modules-available/statistics_reporting/inc/remotereport.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules-available/statistics_reporting/inc/remotereport.inc.php b/modules-available/statistics_reporting/inc/remotereport.inc.php index 98af8888..fa84e7e5 100644 --- a/modules-available/statistics_reporting/inc/remotereport.inc.php +++ b/modules-available/statistics_reporting/inc/remotereport.inc.php @@ -83,7 +83,7 @@ class RemoteReport GetData::$from = $from; GetData::$to = $to; $data = array('total' => GetData::total(GETDATA_ANONYMOUS)); - $data['perLocation'] = GetData::perLocation(GETDATA_ANONYMOUS); + $data['perLocation'] = array_values(GetData::perLocation(GETDATA_ANONYMOUS)); $data['perVM'] = GetData::perVM(GETDATA_ANONYMOUS); $data['tsFrom'] = $from; $data['tsTo'] = $to; -- cgit v1.2.3-55-g7522 From 0d4d09f6fac5e79a75e8305c0c6c4df1620b6eb0 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 8 Jan 2018 13:47:34 +0100 Subject: [statistics] Add filters for uptime and hostname Closes #3278 --- modules-available/statistics/inc/filter.inc.php | 44 +++++++++++++++++++--- .../statistics/lang/de/template-tags.json | 1 + .../statistics/lang/en/template-tags.json | 1 + modules-available/statistics/page.inc.php | 12 +++++- .../statistics/templates/filterbox.html | 4 +- 5 files changed, 55 insertions(+), 7 deletions(-) diff --git a/modules-available/statistics/inc/filter.inc.php b/modules-available/statistics/inc/filter.inc.php index be6df752..1686f328 100644 --- a/modules-available/statistics/inc/filter.inc.php +++ b/modules-available/statistics/inc/filter.inc.php @@ -88,15 +88,17 @@ class Filter $lhs = trim(substr($q, 0, $pos)); $rhs = trim(substr($q, $pos + strlen($operator))); - if ($lhs == 'gbram') { + if ($lhs === 'gbram') { $filters[] = new RamGbFilter($operator, $rhs); - } elseif ($lhs == 'state') { + } elseif ($lhs === 'runtime') { + $filters[] = new RuntimeFilter($operator, $rhs); + } elseif ($lhs === 'state') { $filters[] = new StateFilter($operator, $rhs); - } elseif ($lhs == 'hddgb') { + } elseif ($lhs === 'hddgb') { $filters[] = new Id44Filter($operator, $rhs); - } elseif ($lhs == 'location') { + } elseif ($lhs === 'location') { $filters[] = new LocationFilter($operator, $rhs); - } elseif ($lhs == 'subnet') { + } elseif ($lhs === 'subnet') { $filters[] = new SubnetFilter($operator, $rhs); } else { if (array_key_exists($lhs, Page_Statistics::$columns) && Page_Statistics::$columns[$lhs]['column']) { @@ -143,6 +145,38 @@ class RamGbFilter extends Filter } } +class RuntimeFilter extends Filter +{ + public function __construct($operator, $argument) + { + parent::__construct('lastboot', $operator, $argument); + } + + public function whereClause(&$args, &$joins) + { + global $SIZE_RAM; + $lower = time() + (int)$this->argument * 3600; + $upper = $lower + 3600; + $common = "state IN ('OCCUPIED', 'IDLE', 'STANDBY') AND"; + if ($this->operator == '=') { + return "$common ({$this->column} BETWEEN $lower AND $upper)"; + } elseif ($this->operator == '<') { + return "$common {$this->column} < $lower"; + } elseif ($this->operator == '<=') { + return "$common {$this->column} < $upper"; + } elseif ($this->operator == '>') { + return "$common {$this->column} > $upper"; + } elseif ($this->operator == '>=') { + return "$common {$this->column} > $lower"; + } elseif ($this->operator == '!=') { + return "$common ({$this->column} < $lower OR {$this->column} > $upper)"; + } else { + error_log("unimplemented operator in RuntimeFilter: $this->operator"); + return ' 1'; + } + } +} + class Id44Filter extends Filter { public function __construct($operator, $argument) diff --git a/modules-available/statistics/lang/de/template-tags.json b/modules-available/statistics/lang/de/template-tags.json index 3cdde813..b8cf0bb1 100644 --- a/modules-available/statistics/lang/de/template-tags.json +++ b/modules-available/statistics/lang/de/template-tags.json @@ -68,6 +68,7 @@ "lang_reallocatedSectors": "Defekte Sektoren", "lang_runMode": "Betriebsmodus", "lang_runmodeMachines": "Mit besonderem Betriebsmodus", + "lang_runtimeHours": "Laufzeit (Stunden)", "lang_screens": "Bildschirme", "lang_serialNo": "Serien-Nr", "lang_showList": "Liste", diff --git a/modules-available/statistics/lang/en/template-tags.json b/modules-available/statistics/lang/en/template-tags.json index 35c4e68a..3529b7d0 100644 --- a/modules-available/statistics/lang/en/template-tags.json +++ b/modules-available/statistics/lang/en/template-tags.json @@ -68,6 +68,7 @@ "lang_reallocatedSectors": "Bad sectors", "lang_runMode": "Mode of operation", "lang_runmodeMachines": "With special mode of operation", + "lang_runtimeHours": "Runtime (hours)", "lang_screens": "Screens", "lang_serialNo": "Serial no", "lang_showList": "List", diff --git a/modules-available/statistics/page.inc.php b/modules-available/statistics/page.inc.php index 77b52e0d..09359342 100644 --- a/modules-available/statistics/page.inc.php +++ b/modules-available/statistics/page.inc.php @@ -104,6 +104,11 @@ class Page_Statistics extends Page 'type' => 'string', 'column' => true ], + 'hostname' => [ + 'op' => Page_Statistics::$op_stringcmp, + 'type' => 'string', + 'column' => true + ], 'subnet' => [ 'op' => Page_Statistics::$op_nominal, 'type' => 'string', @@ -119,7 +124,12 @@ class Page_Statistics extends Page 'type' => 'enum', 'column' => true, 'values' => ['occupied', 'on', 'off', 'idle', 'standby'] - ] + ], + 'runtime' => [ + 'op' => Page_Statistics::$op_ordinal, + 'type' => 'int', + 'column' => true + ], ]; if (Module::isAvailable('locations')) { Page_Statistics::$columns['location'] = [ diff --git a/modules-available/statistics/templates/filterbox.html b/modules-available/statistics/templates/filterbox.html index 758bc287..58b66a75 100644 --- a/modules-available/statistics/templates/filterbox.html +++ b/modules-available/statistics/templates/filterbox.html @@ -99,7 +99,9 @@ var slxFilterNames = { state: '{{lang_usageState}}', location: '{{lang_location}}', currentuser: '{{lang_currentUser}}', - subnet: '{{lang_subnet}}' + subnet: '{{lang_subnet}}', + runtime: '{{lang_runtimeHours}}', + hostname: '{{lang_hostname}}' }; slxLocations = {{{locations}}}; -- cgit v1.2.3-55-g7522 From f3dc28794882b197a5799bba1bbc87b3a0078614 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 8 Jan 2018 13:50:32 +0100 Subject: Update translations --- modules-available/dozmod/lang/de/messages.json | 4 +++- modules-available/dozmod/lang/en/messages.json | 4 +++- modules-available/statistics_reporting/lang/de/template-tags.json | 8 +++++--- modules-available/statistics_reporting/lang/en/template-tags.json | 8 +++++--- .../statistics_reporting/templates/table-client.html | 2 +- .../statistics_reporting/templates/table-location.html | 2 +- 6 files changed, 18 insertions(+), 10 deletions(-) diff --git a/modules-available/dozmod/lang/de/messages.json b/modules-available/dozmod/lang/de/messages.json index 47580bcb..60c37927 100644 --- a/modules-available/dozmod/lang/de/messages.json +++ b/modules-available/dozmod/lang/de/messages.json @@ -8,5 +8,7 @@ "nothing-submitted": "Es wurde nichts \u00fcbermittelt", "runtimelimits-config-saved": "Einstellungen gespeichert", "templates-saved": "Templates wurden gespeichert", - "timeout": "Zeit\u00fcberschreitung" + "timeout": "Zeit\u00fcberschreitung", + "unknown-targetid": "Target {{0}} nicht bekannt", + "unknown-userid": "Unbekannter Nutzer, {{0}}" } \ No newline at end of file diff --git a/modules-available/dozmod/lang/en/messages.json b/modules-available/dozmod/lang/en/messages.json index a17eae37..6d7ea0ac 100644 --- a/modules-available/dozmod/lang/en/messages.json +++ b/modules-available/dozmod/lang/en/messages.json @@ -8,5 +8,7 @@ "nothing-submitted": "There was nothing submitted", "runtimelimits-config-saved": "Configuration saved successfully", "templates-saved": "Templates saved successfully", - "timeout": "Timeout" + "timeout": "Timeout", + "unknown-targetid": "Unknown target id {{0}}", + "unknown-userid": "Unknown user id {{0}}" } \ No newline at end of file diff --git a/modules-available/statistics_reporting/lang/de/template-tags.json b/modules-available/statistics_reporting/lang/de/template-tags.json index f8829b79..397d93de 100644 --- a/modules-available/statistics_reporting/lang/de/template-tags.json +++ b/modules-available/statistics_reporting/lang/de/template-tags.json @@ -1,5 +1,4 @@ { - "lang_apply": "Anwenden", "lang_displayColumns": "Auswahl angezeigter Spalten", "lang_displaySelection": "Anzeigemodus, Auswahl Zeitfenster", "lang_downloadReport": "Report herunterladen", @@ -7,7 +6,7 @@ "lang_hostname": "Hostname", "lang_lastLogout": "Letzter Logout", "lang_lastStart": "Letzter Boot", - "lang_location": "Ort", + "lang_locationname": "Ort", "lang_longSessions": "Sitzungen \u2265 60s", "lang_medianSessionLength": "Sitzungsdauer Median", "lang_moduleName": "Statistikauswertung", @@ -18,7 +17,10 @@ "lang_shortSessions": "Sitzungen < 60s", "lang_show": "Anzeigen", "lang_total": "Gesamt", - "lang_totalOffTime": "Gesamtzeit offline", + "lang_totalIdleTime": "Ungenutzt", + "lang_totalOffTime": "Offline", + "lang_totalSessionTime": "Belegt", + "lang_totalStandbyTime": "Standby", "lang_totalTime": "Gesamtzeit", "lang_user": "Nutzer", "lang_vm": "Veranstaltung" diff --git a/modules-available/statistics_reporting/lang/en/template-tags.json b/modules-available/statistics_reporting/lang/en/template-tags.json index 73c21112..a4d19222 100644 --- a/modules-available/statistics_reporting/lang/en/template-tags.json +++ b/modules-available/statistics_reporting/lang/en/template-tags.json @@ -1,5 +1,4 @@ { - "lang_apply": "Apply", "lang_displayColumns": "Select columns to display", "lang_displaySelection": "Select display mode and specify time span", "lang_downloadReport": "Download report", @@ -7,7 +6,7 @@ "lang_hostname": "Hostname", "lang_lastLogout": "Last logout", "lang_lastStart": "Last boot", - "lang_location": "Location", + "lang_locationname": "Location", "lang_longSessions": "Sessions \u2265 60s", "lang_medianSessionLength": "Median Session Length", "lang_moduleName": "Statistics Reporting", @@ -18,7 +17,10 @@ "lang_shortSessions": "Sessions < 60s", "lang_show": "Show", "lang_total": "Total", - "lang_totalOffTime": "Total Time Offline", + "lang_totalIdleTime": "Idle", + "lang_totalOffTime": "Offline", + "lang_totalSessionTime": "Occupied", + "lang_totalStandbyTime": "Standby", "lang_totalTime": "Total Time", "lang_user": "User", "lang_vm": "Lecture" diff --git a/modules-available/statistics_reporting/templates/table-client.html b/modules-available/statistics_reporting/templates/table-client.html index a23c2f89..7bcf3ecf 100644 --- a/modules-available/statistics_reporting/templates/table-client.html +++ b/modules-available/statistics_reporting/templates/table-client.html @@ -2,7 +2,7 @@ {{lang_hostname}} - {{lang_location}} + {{lang_locationname}} {{lang_totalTime}} {{lang_medianSessionLength}} {{lang_longSessions}} diff --git a/modules-available/statistics_reporting/templates/table-location.html b/modules-available/statistics_reporting/templates/table-location.html index 4e470d1e..e7a0c84d 100644 --- a/modules-available/statistics_reporting/templates/table-location.html +++ b/modules-available/statistics_reporting/templates/table-location.html @@ -1,7 +1,7 @@ - + -- cgit v1.2.3-55-g7522 From eaeb9f966eb37d540c26f59e1edb5a9039581585 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 11 Jan 2018 11:04:53 +0100 Subject: [translations] Guess using a VCS isn't enough? --- modules-available/translation/templates/edit.html | 87 +---------------------- 1 file changed, 2 insertions(+), 85 deletions(-) diff --git a/modules-available/translation/templates/edit.html b/modules-available/translation/templates/edit.html index 3c66aef6..993768ca 100644 --- a/modules-available/translation/templates/edit.html +++ b/modules-available/translation/templates/edit.html @@ -5,7 +5,7 @@ -
{{lang_location}}{{lang_locationname}} {{lang_totalTime}} {{lang_medianSessionLength}} {{lang_longSessions}}
+
@@ -77,90 +77,6 @@
- - -- cgit v1.2.3-55-g7522 From 807485b0b13ea8d585cca042bb9847f63a377d9c Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 11 Jan 2018 11:18:07 +0100 Subject: [translations] Focus first untranslated tag --- modules-available/translation/templates/edit.html | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules-available/translation/templates/edit.html b/modules-available/translation/templates/edit.html index 993768ca..7a41d9b4 100644 --- a/modules-available/translation/templates/edit.html +++ b/modules-available/translation/templates/edit.html @@ -35,10 +35,10 @@ @@ -121,4 +121,8 @@ old.replaceWith(ta); } + document.addEventListener('DOMContentLoaded', function () { + $('.txt-empty').first().focus(); + }); + -- cgit v1.2.3-55-g7522 From 4537b9b7c9eb63bf3b2d5066d6c50e68f7de4956 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 11 Jan 2018 11:19:14 +0100 Subject: [statistics] Add "replace machines" feature (not linked to anywhere yet) --- .../dnbd3/hooks/statistics-machine-replace.inc.php | 6 ++ .../hooks/statistics-machine-replace.inc.php | 7 ++ .../hooks/statistics-machine-replace.inc.php | 6 ++ modules-available/statistics/lang/de/messages.json | 6 +- .../statistics/lang/de/template-tags.json | 6 ++ modules-available/statistics/lang/en/messages.json | 6 +- .../statistics/lang/en/template-tags.json | 6 ++ modules-available/statistics/page.inc.php | 6 +- modules-available/statistics/pages/replace.inc.php | 119 +++++++++++++++++++++ .../statistics/templates/page-replace.html | 4 + .../hooks/statistics-machine-replace.inc.php | 5 + 11 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 modules-available/dnbd3/hooks/statistics-machine-replace.inc.php create mode 100644 modules-available/roomplanner/hooks/statistics-machine-replace.inc.php create mode 100644 modules-available/runmode/hooks/statistics-machine-replace.inc.php create mode 100644 modules-available/statistics/pages/replace.inc.php create mode 100644 modules-available/syslog/hooks/statistics-machine-replace.inc.php diff --git a/modules-available/dnbd3/hooks/statistics-machine-replace.inc.php b/modules-available/dnbd3/hooks/statistics-machine-replace.inc.php new file mode 100644 index 00000000..5e4c4e75 --- /dev/null +++ b/modules-available/dnbd3/hooks/statistics-machine-replace.inc.php @@ -0,0 +1,6 @@ + $cat, 'id' => $id)); } diff --git a/modules-available/statistics/pages/replace.inc.php b/modules-available/statistics/pages/replace.inc.php new file mode 100644 index 00000000..80bbf0ce --- /dev/null +++ b/modules-available/statistics/pages/replace.inc.php @@ -0,0 +1,119 @@ + $split[0], 'new' => $split[1]]; + $old = Database::queryFirst('SELECT lastseen FROM machine WHERE machineuuid = :old', + ['old' => $entry['old']]); + if ($old === false) { + Message::addError('unknown-machine', $entry['old']); + continue; + } + $new = Database::queryFirst('SELECT firstseen FROM machine WHERE machineuuid = :new', + ['new' => $entry['new']]); + if ($new === false) { + Message::addError('unknown-machine', $entry['new']); + continue; + } + if ($old['lastseen'] - 86400*7 > $new['firstseen']) { + Message::addWarning('ignored-both-in-use', $entry['old'], $entry['new']); + continue; + } + $entry['datelimit'] = min($new['firstseen'], $old['lastseen']); + $list[] = $entry; + } + if (empty($list)) { + Message::addError('main.parameter-empty', 'replace'); + return; + } + + // First handle module internal tables + foreach ($list as $entry) { + Database::exec('UPDATE statistic SET machineuuid = :new WHERE machineuuid = :old AND dateline < :datelimit', $entry); + } + + // Let other modules do their thing + $fun = function($file, $list) { + include $file; + }; + foreach (Hook::load('statistics-machine-replace') as $hook) { + $fun($hook->file, $list); + } + + // Finalize by updating machine table + foreach ($list as $entry) { + unset($entry['datelimit']); + Database::exec('UPDATE machine old, machine new SET + new.fixedlocationid = old.fixedlocationid, + new.position = old.position, + old.position = NULL, + new.notes = old.notes, + old.notes = NULL, + old.lastseen = new.firstseen + WHERE old.machineuuid = :old AND new.machineuuid = :new', $entry); + } + Message::addSuccess('x-machines-replaced', count($list)); + } + + public static function doRender() + { + self::listSuggestions(); + } + + private static function listSuggestions() + { + if (Request::get('debug', false) !== false) { + $oldCutoff = time() - 86400 * 180; + $newCutoff = time() - 86400 * 180; + } else { + $oldCutoff = time() - 86400 * 90; + $newCutoff = time() - 86400 * 30; + } + $res = Database::simpleQuery("SELECT + old.machineuuid AS olduuid, old.locationid AS oldlid, old.hostname AS oldhost, + old.clientip AS oldip, old.macaddr AS oldmac, old.lastseen AS oldlastseen, old.systemmodel AS oldmodel, + new.machineuuid AS newuuid, new.locationid AS newlid, new.hostname AS newhost, + new.clientip AS newip, new.macaddr AS newmac, new.firstseen AS newfirstseen, new.systemmodel AS newmodel + FROM machine old INNER JOIN machine new ON (old.clientip = new.clientip AND old.lastseen < new.firstseen AND old.lastseen > $oldCutoff AND new.firstseen > $newCutoff) + ORDER BY oldhost ASC, oldip ASC"); + $list = []; + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $row['oldlastseen_s'] = Util::prettyTime($row['oldlastseen']); + $row['newfirstseen_s'] = Util::prettyTime($row['newfirstseen']); + $list[] = $row; + } + $data = array('pairs' => $list); + Render::addTemplate('page-replace', $data); + if (empty($list)) { + Message::addInfo('no-replacement-matches'); + } + } + +} + diff --git a/modules-available/statistics/templates/page-replace.html b/modules-available/statistics/templates/page-replace.html index f87610a2..d0e9f766 100644 --- a/modules-available/statistics/templates/page-replace.html +++ b/modules-available/statistics/templates/page-replace.html @@ -17,6 +17,10 @@ } +

+ {{lang_replaceInstructions}} +

+
{{lang_tag}} {{^big}} - + {{/big}} {{#big}} - + {{/big}}
diff --git a/modules-available/syslog/hooks/statistics-machine-replace.inc.php b/modules-available/syslog/hooks/statistics-machine-replace.inc.php new file mode 100644 index 00000000..6be0dd76 --- /dev/null +++ b/modules-available/syslog/hooks/statistics-machine-replace.inc.php @@ -0,0 +1,5 @@ + Request::post('url', 'https://www.bwlehrpool.de/', 'string'), 'insecure-ssl' => Request::post('insecure-ssl', 0, 'int'), + 'reload-minutes' => max(0, Request::post('reloadminutes', 0, 'int')), ); return array('config' => $conf, 'locationids' => []); } @@ -887,6 +888,7 @@ class Page_LocationInfo extends Page 'panelname' => $panel['panelname'], 'url' => $config['url'], 'ssl_checked' => $config['insecure-ssl'] ? 'checked' : '', + 'reloadminutes' => (int)$config['reload-minutes'], )); } else { Render::addTemplate('page-config-panel-summary', array( diff --git a/modules-available/locationinfo/templates/page-config-panel-url.html b/modules-available/locationinfo/templates/page-config-panel-url.html index 401214bd..cca81509 100644 --- a/modules-available/locationinfo/templates/page-config-panel-url.html +++ b/modules-available/locationinfo/templates/page-config-panel-url.html @@ -55,7 +55,10 @@
- +
+ + +
@@ -64,6 +67,23 @@
+ +
+
+
+ +
+
+ +
+
+
+
+ -- cgit v1.2.3-55-g7522 From 3d1bfecc21d392e35553c989e24a1cfd532579fb Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 11 Jan 2018 15:15:30 +0100 Subject: Update translations + add global tags lang_username, lang_user and lang_password are now global tags --- modules-available/adduser/lang/de/template-tags.json | 6 ++---- modules-available/adduser/lang/en/template-tags.json | 6 ++---- modules-available/adduser/lang/pt/template-tags.json | 6 ++---- modules-available/dozmod/lang/de/template-tags.json | 4 +--- modules-available/dozmod/lang/en/template-tags.json | 4 +--- modules-available/locationinfo/lang/de/template-tags.json | 2 ++ modules-available/locationinfo/lang/en/template-tags.json | 2 ++ modules-available/main/lang/de/global-tags.json | 3 +++ modules-available/main/lang/en/global-tags.json | 3 +++ modules-available/main/lang/pt/global-tags.json | 3 +++ modules-available/session/lang/de/template-tags.json | 6 ++---- modules-available/session/lang/en/template-tags.json | 6 ++---- modules-available/session/lang/pt/template-tags.json | 6 ++---- modules-available/sysconfig/lang/de/template-tags.json | 3 +-- modules-available/sysconfig/lang/en/template-tags.json | 3 +-- modules-available/sysconfig/lang/pt/template-tags.json | 3 +-- modules-available/usermanagement/lang/en/template-tags.json | 6 ++---- modules-available/usermanagement/lang/pt/template-tags.json | 6 ++---- modules-available/vmstore/lang/de/template-tags.json | 4 +--- modules-available/vmstore/lang/en/template-tags.json | 4 +--- modules-available/vmstore/lang/pt/template-tags.json | 4 +--- 21 files changed, 37 insertions(+), 53 deletions(-) diff --git a/modules-available/adduser/lang/de/template-tags.json b/modules-available/adduser/lang/de/template-tags.json index 0f446025..99d17947 100644 --- a/modules-available/adduser/lang/de/template-tags.json +++ b/modules-available/adduser/lang/de/template-tags.json @@ -2,7 +2,5 @@ "lang_confirmation": "Wiederholen", "lang_createUser": "Benutzer anlegen", "lang_fullName": "Vollst\u00e4ndiger Name", - "lang_password": "Passwort", - "lang_telephone": "Telefon", - "lang_username": "Benutzerkennung" -} \ No newline at end of file + "lang_telephone": "Telefon" +} diff --git a/modules-available/adduser/lang/en/template-tags.json b/modules-available/adduser/lang/en/template-tags.json index 42bae6dc..24f8cd42 100644 --- a/modules-available/adduser/lang/en/template-tags.json +++ b/modules-available/adduser/lang/en/template-tags.json @@ -2,7 +2,5 @@ "lang_confirmation": "Confirm Password", "lang_createUser": "Create User", "lang_fullName": "Full Name", - "lang_password": "Password", - "lang_telephone": "Telephone", - "lang_username": "Username" -} \ No newline at end of file + "lang_telephone": "Telephone" +} diff --git a/modules-available/adduser/lang/pt/template-tags.json b/modules-available/adduser/lang/pt/template-tags.json index 524f3dd5..ba204937 100644 --- a/modules-available/adduser/lang/pt/template-tags.json +++ b/modules-available/adduser/lang/pt/template-tags.json @@ -2,7 +2,5 @@ "lang_confirmation": "Confirmar Senha", "lang_createUser": "Criar Usu\u00e1rio", "lang_fullName": "Nome Completo", - "lang_password": "Senha", - "lang_telephone": "Telefone", - "lang_username": "Nome de Usu\u00e1rio" -} \ No newline at end of file + "lang_telephone": "Telefone" +} diff --git a/modules-available/dozmod/lang/de/template-tags.json b/modules-available/dozmod/lang/de/template-tags.json index 4b49579a..a1c23d2e 100644 --- a/modules-available/dozmod/lang/de/template-tags.json +++ b/modules-available/dozmod/lang/de/template-tags.json @@ -54,7 +54,6 @@ "lang_organizationListHeader": "Nutzungsrechte f\u00fcr den Satelliten festlegen", "lang_os": "Betriebssystem", "lang_owner": "Besitzer", - "lang_password": "Passwort", "lang_passwordplaceholder": "SMTP Passwort", "lang_placeholders": "Platzhalter", "lang_port": "Port", @@ -87,8 +86,7 @@ "lang_userList": "Benutzerliste", "lang_userListDescription": "Hier k\u00f6nnen Sie individuelle Nutzer zu \"Super-Usern\" machen. Diese haben in der bwLehrpool-Suite auf alle Veranstaltungen und VMs Vollzugriff, unabh\u00e4ngig von den gesetzten Berechtigungen. Au\u00dferdem k\u00f6nnen Sie hier Benutzer vom Zugriff mittels der bwLehrpool-Suite ausschlie\u00dfen.", "lang_userListHeader": "Dem Satelliten bekannte Benutzer", - "lang_username": "Benutzername", "lang_usernameplaceholder": "SMTP Benutzername", "lang_version": "Version vom", "lang_when": "Wann" -} \ No newline at end of file +} diff --git a/modules-available/dozmod/lang/en/template-tags.json b/modules-available/dozmod/lang/en/template-tags.json index ed8f3465..f12e4ab8 100644 --- a/modules-available/dozmod/lang/en/template-tags.json +++ b/modules-available/dozmod/lang/en/template-tags.json @@ -54,7 +54,6 @@ "lang_organizationListHeader": "Set access permissions for organizations", "lang_os": "Operating System", "lang_owner": "Owner", - "lang_password": "Password", "lang_passwordplaceholder": "SMTP Password", "lang_placeholders": "Placeholders", "lang_port": "Port", @@ -87,8 +86,7 @@ "lang_userList": "User List", "lang_userListDescription": "Here you can promote \"super users\", which will have all permissions in the bwLehrpool-Suite. You can also ban users from accessing this server via the bwLehrpool-Suite.", "lang_userListHeader": "Users known to this satellite", - "lang_username": "Username", "lang_usernameplaceholder": "SMTP Username", "lang_version": "Version timestamp", "lang_when": "When" -} \ No newline at end of file +} diff --git a/modules-available/locationinfo/lang/de/template-tags.json b/modules-available/locationinfo/lang/de/template-tags.json index b305f800..bcdf7148 100644 --- a/modules-available/locationinfo/lang/de/template-tags.json +++ b/modules-available/locationinfo/lang/de/template-tags.json @@ -71,6 +71,8 @@ "lang_prettytimeTooltip": "Verwende ein anderes Anzeigeformat f\u00fcr die Uhrzeit", "lang_recursiveServerSet": "Auch f\u00fcr alle untergeordneten R\u00e4ume setzen", "lang_recursiveSetTooltip": "Wenn aktiviert, wird der Backend-Server auch f\u00fcr alle untergeordneten R\u00e4ume auf den hier gew\u00e4hlten Wert gesetzt", + "lang_reloadIntervalMins": "Neuladen alle X Minuten", + "lang_reloadIntervalTooltip": "Setzen Sie dieses Feld auf einen Wert > 0 (in Minuten), um die Seite auf den Clients regelm\u00e4\u00dfig neu zu laden. Feld auf 0 setzen oder leer lassen deaktiviert diese Funktion.", "lang_remoteSchedule": "Abruf Belegungsplan", "lang_room": "Raum", "lang_roomId": "Raum ID", diff --git a/modules-available/locationinfo/lang/en/template-tags.json b/modules-available/locationinfo/lang/en/template-tags.json index 5679e8b8..558ddff0 100644 --- a/modules-available/locationinfo/lang/en/template-tags.json +++ b/modules-available/locationinfo/lang/en/template-tags.json @@ -71,6 +71,8 @@ "lang_prettytimeTooltip": "Use a different display format for the time", "lang_recursiveServerSet": "Also set for all child locations", "lang_recursiveSetTooltip": "If checked, all direct and indirect child locations will be configured to use the backend server selected above", + "lang_reloadIntervalMins": "Reload every X minutes", + "lang_reloadIntervalTooltip": "Set this field to a value > 0 (in minutes) to reload the page periodically. Set to 0 or leave blank to disable.", "lang_remoteSchedule": "Time table retrieval", "lang_room": "Room", "lang_roomId": "Room ID", diff --git a/modules-available/main/lang/de/global-tags.json b/modules-available/main/lang/de/global-tags.json index 451e016e..de6ee798 100644 --- a/modules-available/main/lang/de/global-tags.json +++ b/modules-available/main/lang/de/global-tags.json @@ -9,9 +9,12 @@ "lang_hours": "Stunde(n)", "lang_next": "Weiter", "lang_no": "Nein", + "lang_password": "Passwort", "lang_reset": "Zur\u00fccksetzen", "lang_save": "Speichern", "lang_today": "Heute", + "lang_user": "Benutzer", + "lang_username": "Benutzername", "lang_yes": "Ja", "lang_yesterday": "Gestern" } \ No newline at end of file diff --git a/modules-available/main/lang/en/global-tags.json b/modules-available/main/lang/en/global-tags.json index bfadf2f2..a915a625 100644 --- a/modules-available/main/lang/en/global-tags.json +++ b/modules-available/main/lang/en/global-tags.json @@ -9,9 +9,12 @@ "lang_hours": "hour(s)", "lang_next": "Next", "lang_no": "No", + "lang_password": "Password", "lang_reset": "Reset", "lang_save": "Save", "lang_today": "Today", + "lang_user": "User", + "lang_username": "Username", "lang_yes": "Yes", "lang_yesterday": "Yesterday" } \ No newline at end of file diff --git a/modules-available/main/lang/pt/global-tags.json b/modules-available/main/lang/pt/global-tags.json index 11e032e2..9029d936 100644 --- a/modules-available/main/lang/pt/global-tags.json +++ b/modules-available/main/lang/pt/global-tags.json @@ -7,8 +7,11 @@ "lang_edit": "Editar", "lang_hours": "Hora(s)", "lang_next": "Pr\u00f3ximo", + "lang_password": "Senha", "lang_reset": "Limpar", "lang_save": "Salvar", "lang_today": "Hoje", + "lang_user": "User", + "lang_username": "Nome do Usu\u00e1rio", "lang_yesterday": "Ontem" } \ No newline at end of file diff --git a/modules-available/session/lang/de/template-tags.json b/modules-available/session/lang/de/template-tags.json index 20f44be0..c7b6d881 100644 --- a/modules-available/session/lang/de/template-tags.json +++ b/modules-available/session/lang/de/template-tags.json @@ -4,9 +4,7 @@ "lang_enter": "Anmeldung", "lang_login": "Anmelden", "lang_newPassword": "Neues Passwort", - "lang_password": "Passwort", "lang_register": "Registrieren", "lang_rememberID": "Angemeldet bleiben", - "lang_repeatPassword": "Passwort wiederholen", - "lang_username": "Benutzerkennung" -} \ No newline at end of file + "lang_repeatPassword": "Passwort wiederholen" +} diff --git a/modules-available/session/lang/en/template-tags.json b/modules-available/session/lang/en/template-tags.json index 663354a9..f9e0b393 100644 --- a/modules-available/session/lang/en/template-tags.json +++ b/modules-available/session/lang/en/template-tags.json @@ -4,9 +4,7 @@ "lang_enter": "Enter", "lang_login": "Login", "lang_newPassword": "New password", - "lang_password": "Password", "lang_register": "Register", "lang_rememberID": "Remember ID", - "lang_repeatPassword": "Repeat password", - "lang_username": "Username" -} \ No newline at end of file + "lang_repeatPassword": "Repeat password" +} diff --git a/modules-available/session/lang/pt/template-tags.json b/modules-available/session/lang/pt/template-tags.json index 3d1e19eb..3a4b9478 100644 --- a/modules-available/session/lang/pt/template-tags.json +++ b/modules-available/session/lang/pt/template-tags.json @@ -1,8 +1,6 @@ { "lang_enter": "Entrar", "lang_login": "Entrar", - "lang_password": "Senha", "lang_register": "Registrar", - "lang_rememberID": "Lembrar Usu\u00e1rio", - "lang_username": "Nome de Usu\u00e1rio" -} \ No newline at end of file + "lang_rememberID": "Lembrar Usu\u00e1rio" +} diff --git a/modules-available/sysconfig/lang/de/template-tags.json b/modules-available/sysconfig/lang/de/template-tags.json index 9ad29e90..7f8511e6 100644 --- a/modules-available/sysconfig/lang/de/template-tags.json +++ b/modules-available/sysconfig/lang/de/template-tags.json @@ -82,7 +82,6 @@ "lang_noValidCert": "Der Server besitzt kein oder ein nicht valides Zertifikat.", "lang_onProblemSearchBase": "Werden keine Benutzer gefunden, dann \u00fcberpr\u00fcfen Sie bitte die Suchbasis", "lang_or": "oder", - "lang_password": "Passwort", "lang_rebuild": "Neu generieren", "lang_rebuildLong": "Modul oder Konfiguration neu generieren. Das entsprechende Modul bzw. Konfiguration ist aktuell und sollte nicht neu generiert werden m\u00fcssen.", "lang_rebuildOutdatedLong": "Modul oder Konfiguration neu generieren. Das entsprechende Modul bzw. Konfiguration ist veraltet oder nicht vorhanden.", @@ -125,4 +124,4 @@ "lang_userDirectoryInfo1": "Optionale Angabe: Wenn die Clients f\u00fcr die Benutzer ein eigenes Verzeichnis (Homeverzeichnis, Benutzerverzeichnis) von einem Server einbinden sollen, geben Sie bitte hier das Format in UNC-Notation an, also z.B.", "lang_userDirectoryInfo2": "%s ist dabei ein Platzhalter f\u00fcr den Login-Namen des Benutzers.", "lang_userDirectoryInfo3": "Das Verzeichnis wird mit den gleichen Zugangsdaten eingebunden, die der Benutzer beim Login angibt. (D.h. kein Kerberos Support o.\u00e4.)" -} \ No newline at end of file +} diff --git a/modules-available/sysconfig/lang/en/template-tags.json b/modules-available/sysconfig/lang/en/template-tags.json index e2cfd114..5a73c254 100644 --- a/modules-available/sysconfig/lang/en/template-tags.json +++ b/modules-available/sysconfig/lang/en/template-tags.json @@ -82,7 +82,6 @@ "lang_noValidCert": "The server did not supply a certificate, or the certificate is invalid.", "lang_onProblemSearchBase": "If no users are found, please check the search base", "lang_or": "or", - "lang_password": "Password", "lang_rebuild": "Rebuild", "lang_rebuildLong": "Rebuild module or configuration.", "lang_rebuildOutdatedLong": "Rebuild module or configuration. The module\/configuration is outdated or missing and should be regenerated.", @@ -125,4 +124,4 @@ "lang_userDirectoryInfo1": "Optional: If the clients should embed a separate directory (home directory, user directory) from a server for the user, please enter here the format in UNC notation, eg", "lang_userDirectoryInfo2": "%s is a placeholder for the user's login name.", "lang_userDirectoryInfo3": "The directory is loaded with the same credentials that the user specifies when login. (That is no Kerberos support, etc.)" -} \ No newline at end of file +} diff --git a/modules-available/sysconfig/lang/pt/template-tags.json b/modules-available/sysconfig/lang/pt/template-tags.json index 2384a891..abf8e075 100644 --- a/modules-available/sysconfig/lang/pt/template-tags.json +++ b/modules-available/sysconfig/lang/pt/template-tags.json @@ -17,7 +17,6 @@ "lang_newConfiguration": "Nova Configura\u00e7\u00e3o", "lang_newModule": "Novo M\u00f3dulo", "lang_noContent": "Sem conte\u00fado!", - "lang_password": "Senha", "lang_searchBase": "Base de Pesquisa", "lang_show": "Mostrar", "lang_systemConfiguration": "Confgura\u00e7\u00e3o do Sistema", @@ -27,4 +26,4 @@ "lang_userDirectoryInfo1": "Opcional: Se os clientes devem incorporar um diret\u00f3rio separado (diret\u00f3rio home, diret\u00f3rio de usu\u00e1rio) de um servidor para o usu\u00e1rio, digite aqui o formato em nota\u00e7\u00e3o UNC, por exemplo,", "lang_userDirectoryInfo2": "%s \u00e9 um marcador para o nome de login do usu\u00e1rio.", "lang_userDirectoryInfo3": "O diret\u00f3rio \u00e9 carregado com as mesmas credenciais que o usu\u00e1rio especifica quando entra. (Isto \u00e9, n\u00e3o h\u00e1 suporte Kerberos, etc)" -} \ No newline at end of file +} diff --git a/modules-available/usermanagement/lang/en/template-tags.json b/modules-available/usermanagement/lang/en/template-tags.json index 66b30c6a..35497fc9 100644 --- a/modules-available/usermanagement/lang/en/template-tags.json +++ b/modules-available/usermanagement/lang/en/template-tags.json @@ -5,11 +5,9 @@ "lang_email": "Email", "lang_login": "Login", "lang_operations": "Operation", - "lang_password": "Password", "lang_remove": "Remove", "lang_telephone": "Telephone", "lang_userAdmin": "Administrator", "lang_userInfo": "On this section, you will be able to create website users, besides editing or removing existing users.", - "lang_userPage": "Users", - "lang_username": "Username" -} \ No newline at end of file + "lang_userPage": "Users" +} diff --git a/modules-available/usermanagement/lang/pt/template-tags.json b/modules-available/usermanagement/lang/pt/template-tags.json index ad84126a..fefb441d 100644 --- a/modules-available/usermanagement/lang/pt/template-tags.json +++ b/modules-available/usermanagement/lang/pt/template-tags.json @@ -5,11 +5,9 @@ "lang_email": "Email", "lang_login": "Login", "lang_operations": "Opera\u00e7\u00f5es", - "lang_password": "Senha", "lang_remove": "Remover", "lang_telephone": "Telefone", "lang_userAdmin": "Administrador", "lang_userInfo": "Nesta se\u00e7\u00e3o voc\u00ea poder\u00e1 criar usu\u00e1rios para o site, al\u00e9m de editar as informa\u00e7\u00f5es ou remover usu\u00e1rios existentes.", - "lang_userPage": "Usu\u00e1rios", - "lang_username": "Nome do Usu\u00e1rio" -} \ No newline at end of file + "lang_userPage": "Usu\u00e1rios" +} diff --git a/modules-available/vmstore/lang/de/template-tags.json b/modules-available/vmstore/lang/de/template-tags.json index d434566a..0b56d84f 100644 --- a/modules-available/vmstore/lang/de/template-tags.json +++ b/modules-available/vmstore/lang/de/template-tags.json @@ -9,11 +9,9 @@ "lang_nfsHelp3": "Die erste Zeile erlaubt den Lese- und Schreibzugriff des\r\nSatellitenservers. Die zweite Zeile erteilt allen anderen Rechnern\r\nausschlie\u00dflich Lesezugriff. Sie k\u00f6nnen dies nat\u00fcrlich auch auf\r\nspezielle Subnetze oder IP-Bereiche beschr\u00e4nken.", "lang_nfsHelp4": "Wenn exklusiv DNBD3 verwendet wird, kann die zweite Zeile ausgelassen\r\nwerden. Dies erh\u00f6ht die Sicherheit.", "lang_noAdditionalInformation": "Keine weitere Konfiguration notwendig", - "lang_password": "Passwort", "lang_path": "Pfad", "lang_readOnly": "Nur-Lese-Zugangsdaten", "lang_readWrite": "Lese\/Schreib-Zugangsdaten", - "lang_username": "Benutzerkennung", "lang_vmLocation": "VM Speicherort", "lang_vmLocationChoose": "Bitte w\u00e4hlen Sie, wo die Images der Virtuellen Maschinen gespeichert werden sollen.", "lang_vmLocationConfiguration": "VM Speicherort wird konfiguriert", @@ -21,4 +19,4 @@ "lang_vmLocationHelp2": "Im Produktivbetrieb bietet es sich an, hierf\u00fcr einen performanten\r\nNetzwerkspeicher zu benutzen. Dieser Netzwerkspeicher kann per NFS oder\r\nCIFS\/SMB eingebunden werden. In jedem Fall muss sichergestellt werden,\r\ndass der Satellitenserver zum Hinzuf\u00fcgen neuer Virtueller Maschinen\r\nSchreibzugriff auf diesen Netzwerkspeicher hat. Bei der Nutzung von\r\nNFSv3 kann dies IP-Basiert eingerichtet werden, f\u00fcr die Nutzung von\r\nCIFS\/SMB k\u00f6nnen Sie Zugangsdaten angeben, die zum Schreiben\r\nberechtigen.", "lang_vmLocationHelp3": "Im Fall von NFS und CIFS ben\u00f6tigen die bwLehrpool-Clients\r\nausschlie\u00dflich Lesezugriff auf den Netzwerkspeicher (und sollten aus\r\nSicherheitsgr\u00fcnden auch wirklich nur lesen k\u00f6nnen). Wenn Sie exklusiv\r\nDNBD3 verwenden, sind f\u00fcr die Clients keine Freigaben oder\r\nBerechtigungen notwendig, da der Zugriff \u00fcber den Sallitenserver\r\nstattfindet.", "lang_vmLocationHelp4": "Sie k\u00f6nnen DNBD3 entweder exklusiv oder mit Fallback auf NFS\/CIFS verwenden. Im exklusiven Modus wird der Zugriff der Clients auf den kompletten VM-Speicher verhindert bzw. erschwert. Die Clients ben\u00f6tigen keinerlei Berechtigungen auf dem konfigurierten Share. Wenn Sie den Fallback Modus nutzen, werden f\u00fcr die Clients weiterhin Leseberechtigungen ben\u00f6tigt." -} \ No newline at end of file +} diff --git a/modules-available/vmstore/lang/en/template-tags.json b/modules-available/vmstore/lang/en/template-tags.json index d78877b9..1e712b13 100644 --- a/modules-available/vmstore/lang/en/template-tags.json +++ b/modules-available/vmstore/lang/en/template-tags.json @@ -9,11 +9,9 @@ "lang_nfsHelp3": "The first line allows read\/write access for the satellite server. The second line grants read-only access for every other IP address. You could limit the second line to specific IP ranges only if desired.", "lang_nfsHelp4": "If using DNBD3 in exclusive mode, you can remove the second line completely, so only the satellite server has access to the NFS store.", "lang_noAdditionalInformation": "No additional cofiguration required", - "lang_password": "Password", "lang_path": "Path", "lang_readOnly": "Read-only Access", "lang_readWrite": "Read\/Write Access", - "lang_username": "Username", "lang_vmLocation": "VM Storage Location", "lang_vmLocationChoose": "Please choose where the images of virtual machines will be stored.", "lang_vmLocationConfiguration": "VM location is configured", @@ -21,4 +19,4 @@ "lang_vmLocationHelp2": "In productive operation, it makes sense for this to use a high-performance network storage. This network storage can be integrated via NFS or CIFS \/ SMB. In any case, it must be ensured that the satellite server has write access to this network storage to add a new Virtual Machine . When using NFSv3 this can be set up IP-based, for the use of CIFS \/ SMB, you can access data disclosures that would entitle them to write.", "lang_vmLocationHelp3": "The bwLehrpool clients only need read access to the network storage (and for security reasons, really can only read). In CIFS \/ SMB You can do this most easily by allowing passwordless guest access with read access to the share.", "lang_vmLocationHelp4": "You can use DNBD3 exclusively or with NFS\/CIFS as fallback. In exclusive mode, you can deny direct access to the NFS\/CIFS store for clients, to prevent anyone from browsing the VM store directly. In fallback mode, the clients first try to use DNBD3 to run a VM and if that fails, they use NFS\/CIFS directly." -} \ No newline at end of file +} diff --git a/modules-available/vmstore/lang/pt/template-tags.json b/modules-available/vmstore/lang/pt/template-tags.json index 90ae64ad..8e0e4267 100644 --- a/modules-available/vmstore/lang/pt/template-tags.json +++ b/modules-available/vmstore/lang/pt/template-tags.json @@ -6,15 +6,13 @@ "lang_nfsHelp1": "\u00c9 necess\u00e1rio um NFSv3-Share. Ele deve poder ser lido por todas as esta\u00e7\u00f5es de trabalho, e poder ser escrito pelo server. Um exemplo, assumindo que o server possui endere\u00e7o ip 1.2.3.4:", "lang_nfsHelp2": "Configura\u00e7\u00e3o alternativa usando all_squash. O usu\u00e1rio com uid 1234 deve possuir ( e poder escrever em ) o diret\u00f3rio exportado.", "lang_noAdditionalInformation": "Nenhuma configura\u00e7\u00e3o adicional necess\u00e1ria", - "lang_password": "Senha", "lang_readOnly": "Acesso Somente Leitura", "lang_readWrite": "Acesso Leitura\/Escrita", "lang_save": "Salvar", - "lang_username": "Nome de Usu\u00e1rio", "lang_vmLocation": "Localiza\u00e7\u00e3o da VM", "lang_vmLocationChoose": "Por favor, escolha aonde as imagens das m\u00e1quinas virtuais ser\u00e3o armazenadas.", "lang_vmLocationConfiguration": "Localiza\u00e7\u00e3o da VM \u00e9 configurada", "lang_vmLocationHelp1": "Para fins de teste, as VMs podem ser armazenados diretamente no servidor sat\u00e9lite. No entanto, se voc\u00ea operar o vmdk do sat\u00e9lite entregue por favor lembre-se que voc\u00ea tem apenas cerca de 100 GB de mem\u00f3ria.", "lang_vmLocationHelp2": "Em opera\u00e7\u00e3o, faz sentido para este usar um armazenamento de rede de alto desempenho. Este armazenamento de rede pode ser integrado atrav\u00e9s de NFS ou CIFS \/ SMB. Em qualquer caso, deve-se assegurar de que o servidor de sat\u00e9lite tenha acesso de grava\u00e7\u00e3o para este armazenamento de rede para poder adicionar uma nova m\u00e1quina virtual. Ao utilizar NFSv3 este pode ser configurado com base em IP, para o uso de CIFS \/ SMB, voc\u00ea pode acessar as divulga\u00e7\u00f5es de dados que lhe permitiria escrever.", "lang_vmLocationHelp3": "Os clientes bwLehrpool s\u00f3 precisam ter acesso de leitura ao armazenamento de rede (e por raz\u00f5es de seguran\u00e7a, realmente s\u00f3 pode ler). Em CIFS \/ SMB Voc\u00ea pode fazer isso mais facilmente, permitindo o acesso a visitantes sem senha com acesso de leitura." -} \ No newline at end of file +} -- cgit v1.2.3-55-g7522 From dfe2d7225191c87905ed6487cd810d54ec8cb14a Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 11 Jan 2018 15:23:19 +0100 Subject: [permissionmanager] Sanitize language tag names --- .../permissionmanager/lang/de/template-tags.json | 20 ++++++++++---------- .../permissionmanager/lang/en/template-tags.json | 20 ++++++++++---------- modules-available/permissionmanager/page.inc.php | 4 ++-- .../permissionmanager/templates/_page.html | 6 +++--- .../permissionmanager/templates/locationstable.html | 4 ++-- .../permissionmanager/templates/roleeditor.html | 10 +++++----- .../permissionmanager/templates/rolestable.html | 10 +++++----- .../permissionmanager/templates/userstable.html | 14 +++++++------- 8 files changed, 44 insertions(+), 44 deletions(-) diff --git a/modules-available/permissionmanager/lang/de/template-tags.json b/modules-available/permissionmanager/lang/de/template-tags.json index 88652152..71bd4075 100644 --- a/modules-available/permissionmanager/lang/de/template-tags.json +++ b/modules-available/permissionmanager/lang/de/template-tags.json @@ -1,22 +1,22 @@ { - "lang_Roles": "Rollen", - "lang_Users": "Nutzer", - "lang_Locations": "Räume", + "lang_roles": "Rollen", + "lang_users": "Nutzer", + "lang_locations": "Räume", "lang_addRole": "Rollen erteilen", "lang_removeRole": "Rollen entziehen", "lang_newRole": "Rolle anlegen", - "lang_Selected": "Ausgewählt", - "lang_Edit": "Bearbeiten", - "lang_Delete": "Löschen", + "lang_selected": "Ausgewählt", + "lang_edit": "Bearbeiten", + "lang_delete": "Löschen", "lang_removeCheck": "Sind Sie sich sicher, dass Sie diese Rolle entfernen wollen?", "lang_deleteCheck": "Sind Sie sich sicher, dass Sie diese Rolle löschen wollen?", "lang_emptyNameWarning": "Der Name der Rolle darf nicht leer sein!", - "lang_Name": "Name", - "lang_Cancel": "Abbrechen", - "lang_Save": "Speichern", + "lang_name": "Name", + "lang_cancel": "Abbrechen", + "lang_save": "Speichern", "lang_all": "alle", "lang_selected": "ausgewählte", - "lang_Permissions": "Rechte", + "lang_permissions": "Rechte", "lang_selectizePlaceholder": "Nach Rollen filtern...", "lang_searchPlaceholder": "Nach Rollen suchen...", "lang_moduleName": "Rechtemanager", diff --git a/modules-available/permissionmanager/lang/en/template-tags.json b/modules-available/permissionmanager/lang/en/template-tags.json index 08769f27..2d31b294 100644 --- a/modules-available/permissionmanager/lang/en/template-tags.json +++ b/modules-available/permissionmanager/lang/en/template-tags.json @@ -1,22 +1,22 @@ { - "lang_Roles": "Roles", - "lang_Users": "Users", - "lang_Locations": "Locations", + "lang_roles": "Roles", + "lang_users": "Users", + "lang_locations": "Locations", "lang_addRole": "Grant Roles", "lang_removeRole": "Revoke Roles", "lang_newRole": "New Role", - "lang_Selected": "Selected", - "lang_Edit": "Edit", - "lang_Delete": "Delete", + "lang_selected": "Selected", + "lang_edit": "Edit", + "lang_delete": "Delete", "lang_removeCheck": "Are you sure you want to remove this role?", "lang_deleteCheck": "Are you sure you want to delete this role?", "lang_emptyNameWarning": "Role name can not be empty!", - "lang_Name": "Name", - "lang_Cancel": "Cancel", - "lang_Save": "Save", + "lang_name": "Name", + "lang_cancel": "Cancel", + "lang_save": "Save", "lang_all": "all", "lang_selected": "selected", - "lang_Permissions": "Permissions", + "lang_permissions": "Permissions", "lang_selectizePlaceholder": "Filter for roles...", "lang_searchPlaceholder": "Search for roles...", "lang_moduleName": "Permission Manager", diff --git a/modules-available/permissionmanager/page.inc.php b/modules-available/permissionmanager/page.inc.php index eeed9c02..13d81c6a 100644 --- a/modules-available/permissionmanager/page.inc.php +++ b/modules-available/permissionmanager/page.inc.php @@ -116,7 +116,7 @@ class Page_PermissionManager extends Page if ($toplevel) { $res = Render::parse("treepanel", array("id" => "*", - "name" => Dictionary::translateFile("template-tags", "lang_Permissions"), + "name" => Dictionary::translateFile("template-tags", "lang_permissions"), "checkboxname" => "permissions", "selected" => $selectAll, "HTML" => $res)); @@ -151,7 +151,7 @@ class Page_PermissionManager extends Page if ($toplevel) { $res = Render::parse("treepanel", array("id" => 0, - "name" => Dictionary::translateFile("template-tags", "lang_Locations"), + "name" => Dictionary::translateFile("template-tags", "lang_locations"), "checkboxname" => "locations", "selected" => $selectAll, "HTML" => $res)); diff --git a/modules-available/permissionmanager/templates/_page.html b/modules-available/permissionmanager/templates/_page.html index 405462f7..4140ce78 100644 --- a/modules-available/permissionmanager/templates/_page.html +++ b/modules-available/permissionmanager/templates/_page.html @@ -8,17 +8,17 @@
diff --git a/modules-available/permissionmanager/templates/locationstable.html b/modules-available/permissionmanager/templates/locationstable.html index b910e3f3..153258fe 100644 --- a/modules-available/permissionmanager/templates/locationstable.html +++ b/modules-available/permissionmanager/templates/locationstable.html @@ -15,8 +15,8 @@
- - + + diff --git a/modules-available/permissionmanager/templates/roleeditor.html b/modules-available/permissionmanager/templates/roleeditor.html index ddf6ace9..871fd0cc 100644 --- a/modules-available/permissionmanager/templates/roleeditor.html +++ b/modules-available/permissionmanager/templates/roleeditor.html @@ -7,15 +7,15 @@
diff --git a/modules-available/permissionmanager/templates/rolestable.html b/modules-available/permissionmanager/templates/rolestable.html index 7152a1dd..b121a9e0 100644 --- a/modules-available/permissionmanager/templates/rolestable.html +++ b/modules-available/permissionmanager/templates/rolestable.html @@ -17,9 +17,9 @@
{{lang_Locations}}{{lang_Roles}}{{lang_locations}}{{lang_roles}}
- - - + + + @@ -47,7 +47,7 @@ diff --git a/modules-available/permissionmanager/templates/userstable.html b/modules-available/permissionmanager/templates/userstable.html index 749ae03d..bb0e228e 100644 --- a/modules-available/permissionmanager/templates/userstable.html +++ b/modules-available/permissionmanager/templates/userstable.html @@ -23,9 +23,9 @@
{{lang_Roles}}{{lang_Edit}}{{lang_Delete}}{{lang_roles}}{{lang_edit}}{{lang_delete}}
- - - + + + @@ -65,8 +65,8 @@
{{lang_Users}}{{lang_Roles}}{{lang_Selected}}{{lang_users}}{{lang_roles}}{{lang_selected}}
- - + + @@ -108,8 +108,8 @@
{{lang_Roles}}{{lang_Selected}}{{lang_roles}}{{lang_selected}}
- - + + -- cgit v1.2.3-55-g7522 From dee6052ceddea13eee45121b0305d7845f9e6114 Mon Sep 17 00:00:00 2001 From: Steffen Ritter Date: Thu, 11 Jan 2018 17:22:22 +0100 Subject: [inc/User] Removed unecessary logging line --- inc/user.inc.php | 1 - 1 file changed, 1 deletion(-) diff --git a/inc/user.inc.php b/inc/user.inc.php index 95680e65..81091e1b 100644 --- a/inc/user.inc.php +++ b/inc/user.inc.php @@ -109,7 +109,6 @@ class User public static function logout() { - error_log("in logout"); Session::delete(); Header('Location: ?do=Main&fromlogout'); exit(0); -- cgit v1.2.3-55-g7522 From f29bfb7c32a3a968cd46940612e877aa18528c55 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 12 Jan 2018 12:38:05 +0100 Subject: [statistics] Fix display of machine usage history bar --- modules-available/statistics/page.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules-available/statistics/page.inc.php b/modules-available/statistics/page.inc.php index 877a90f2..ac103a41 100644 --- a/modules-available/statistics/page.inc.php +++ b/modules-available/statistics/page.inc.php @@ -947,9 +947,9 @@ class Page_Statistics extends Page // Not seen in last two weeks $spans['graph'] .= '
 
'; } - if (isset($client['state_occupied'])) { + if ($client['state'] === 'OCCUPIED') { $spans['graph'] .= '
 
'; - } elseif (isset($client['state_off'])) { + } elseif ($client['state'] === 'OFFLINE') { $spans['graph'] .= '
 
'; } $t = explode('-', date('Y-n-j-G', $cutoff)); -- cgit v1.2.3-55-g7522 From 328744cad82f06ab736f3faf75667fa8a96d9d2a Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 15 Jan 2018 11:38:43 +0100 Subject: [statistics] Fix "filter by cores" button in client list Closes #3284 --- modules-available/statistics/templates/clientlist.html | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules-available/statistics/templates/clientlist.html b/modules-available/statistics/templates/clientlist.html index 3d3e66a4..799c9c95 100644 --- a/modules-available/statistics/templates/clientlist.html +++ b/modules-available/statistics/templates/clientlist.html @@ -11,27 +11,27 @@ -- cgit v1.2.3-55-g7522 From e7e7a3ead773298256f6b6639deadefd37396ecc Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 15 Jan 2018 11:54:48 +0100 Subject: [statistics] Fix typo in last commit --- modules-available/statistics/templates/clientlist.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules-available/statistics/templates/clientlist.html b/modules-available/statistics/templates/clientlist.html index 799c9c95..0ddd98c8 100644 --- a/modules-available/statistics/templates/clientlist.html +++ b/modules-available/statistics/templates/clientlist.html @@ -30,7 +30,7 @@ -- cgit v1.2.3-55-g7522 From d0fec47b6d956ee60cc77222588864b8efcefa6c Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 15 Jan 2018 16:56:08 +0100 Subject: [statistics] Fix runtime filter (had math backwards) --- modules-available/statistics/inc/filter.inc.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules-available/statistics/inc/filter.inc.php b/modules-available/statistics/inc/filter.inc.php index 1686f328..f6765059 100644 --- a/modules-available/statistics/inc/filter.inc.php +++ b/modules-available/statistics/inc/filter.inc.php @@ -155,19 +155,19 @@ class RuntimeFilter extends Filter public function whereClause(&$args, &$joins) { global $SIZE_RAM; - $lower = time() + (int)$this->argument * 3600; - $upper = $lower + 3600; + $upper = time() - (int)$this->argument * 3600; + $lower = $upper - 3600; $common = "state IN ('OCCUPIED', 'IDLE', 'STANDBY') AND"; if ($this->operator == '=') { return "$common ({$this->column} BETWEEN $lower AND $upper)"; } elseif ($this->operator == '<') { - return "$common {$this->column} < $lower"; + return "$common {$this->column} > $upper"; } elseif ($this->operator == '<=') { - return "$common {$this->column} < $upper"; + return "$common {$this->column} > $lower"; } elseif ($this->operator == '>') { - return "$common {$this->column} > $upper"; + return "$common {$this->column} < $lower"; } elseif ($this->operator == '>=') { - return "$common {$this->column} > $lower"; + return "$common {$this->column} < $upper"; } elseif ($this->operator == '!=') { return "$common ({$this->column} < $lower OR {$this->column} > $upper)"; } else { -- cgit v1.2.3-55-g7522 From 9fdf21f602de38ebcd9cb0ccb03c709a06cd2d06 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 15 Jan 2018 17:19:56 +0100 Subject: [runmode] Do not allow re-assigning clients to new runmode if old mode doesn't support the generic editor Doing so might leave some stale data in the old module, so we better prevent it so the user has to manually remove the client from the old runmode using the non-generic way (module specific) first. --- modules-available/dnbd3/hooks/runmode/config.json | 4 +++- modules-available/runmode/inc/runmode.inc.php | 2 +- modules-available/runmode/lang/de/messages.json | 1 + modules-available/runmode/lang/en/messages.json | 1 + modules-available/runmode/page.inc.php | 24 ++++++++++++++++------ .../runmode/templates/module-machine-list.html | 4 ++-- 6 files changed, 26 insertions(+), 10 deletions(-) diff --git a/modules-available/dnbd3/hooks/runmode/config.json b/modules-available/dnbd3/hooks/runmode/config.json index 095cb42f..5db53f0b 100644 --- a/modules-available/dnbd3/hooks/runmode/config.json +++ b/modules-available/dnbd3/hooks/runmode/config.json @@ -2,5 +2,7 @@ "isClient": false, "configHook": "Dnbd3Util::runmodeConfigHook", "noSysconfig": true, - "systemdDefaultTarget": "dnbd3-proxy" + "systemdDefaultTarget": "dnbd3-proxy", + "allowGenericEditor": false, + "deleteUrlSnippet": "dummyparam=" } \ No newline at end of file diff --git a/modules-available/runmode/inc/runmode.inc.php b/modules-available/runmode/inc/runmode.inc.php index ad1f52bf..2c8083ca 100644 --- a/modules-available/runmode/inc/runmode.inc.php +++ b/modules-available/runmode/inc/runmode.inc.php @@ -72,7 +72,7 @@ class RunMode * @param string $machineuuid * @param int $returnData bitfield of data to return * @return false|array {'machineuuid', 'isclient', 'module', 'modeid', 'modedata', - * <'hostname', 'clientip', 'macaddr', 'locationid', 'lastseen'>} + * ('hostname', 'clientip', 'macaddr', 'locationid', 'lastseen'), ('moduleName', 'modeName')} */ public static function getRunMode($machineuuid, $returnData = self::DATA_MACHINE_DATA) { diff --git a/modules-available/runmode/lang/de/messages.json b/modules-available/runmode/lang/de/messages.json index 21b4b6ae..911d48d4 100644 --- a/modules-available/runmode/lang/de/messages.json +++ b/modules-available/runmode/lang/de/messages.json @@ -5,5 +5,6 @@ "machine-not-found": "Rechner {{0}} nicht gefunden", "machine-not-runmode": "Rechner {{0}} hatte keinen speziellen Betriebsmodus aktiviert", "machine-removed": "Rechner {{0}} entfernt", + "machine-still-assigned": "Rechner {{0}} ist noch im Betriebsmodus {{1}}; ignoriert.", "module-hasnt-runmode": "Modul {{0}} bietet keine speziellen Betriebsmodi" } \ No newline at end of file diff --git a/modules-available/runmode/lang/en/messages.json b/modules-available/runmode/lang/en/messages.json index 1985ca66..6d890428 100644 --- a/modules-available/runmode/lang/en/messages.json +++ b/modules-available/runmode/lang/en/messages.json @@ -5,5 +5,6 @@ "machine-not-found": "Client {{0}} not found", "machine-not-runmode": "No special mode of operation configured for client {{0}}", "machine-removed": "Removed client {{0}}", + "machine-still-assigned": "Client {{0}} still set to mode {{1}}, not assigning new mode.", "module-hasnt-runmode": "Module {{0}} doesn't supply any special mode of operation" } \ No newline at end of file diff --git a/modules-available/runmode/page.inc.php b/modules-available/runmode/page.inc.php index e26950d0..b94b8a31 100644 --- a/modules-available/runmode/page.inc.php +++ b/modules-available/runmode/page.inc.php @@ -42,6 +42,14 @@ class Page_RunMode extends Page } $active = 0; foreach ($machines as $machine) { + $oldMode = RunMode::getRunMode($machine, 0); + if ($oldMode !== false) { + $oldModule = RunMode::getModuleConfig($oldMode['module']); + if ($oldModule !== false && (!$oldModule->allowGenericEditor || $oldModule->deleteUrlSnippet !== false)) { + Message::addError('runmode.machine-still-assigned', $machine, $oldMode['module']); + continue; + } + } $ret = RunMode::setRunMode($machine, $module, $modeId, null, null); if ($ret) { $active++; @@ -105,10 +113,6 @@ class Page_RunMode extends Page Message::addError('module-hasnt-runmode', $moduleId); Util::redirect('?do=runmode'); } - if (!$config->allowGenericEditor) { - Message::addError('runmode.cannot-edit-module', $moduleId); - return; - } // Given modeId? $modeId = Request::get('modeid', false, 'string'); if ($modeId !== false) { @@ -170,9 +174,17 @@ class Page_RunMode extends Page { $moduleId = $module->getIdentifier(); $modeName = RunMode::getModeName($moduleId, $modeId); + $redirect = Request::get('redirect', '', 'string'); + if (empty($redirect)) { + $redirect = '?do=runmode'; + } if ($modeName === false) { Message::addError('invalid-modeid', $moduleId, $modeId); - Util::redirect('?do=runmode'); + Util::redirect($redirect); + } + if (!RunMode::getModuleConfig($moduleId)->allowGenericEditor) { + Message::addError('runmode.cannot-edit-module', $module); + Util::redirect($redirect); } Render::addTemplate('machine-selector', [ 'module' => $moduleId, @@ -180,7 +192,7 @@ class Page_RunMode extends Page 'moduleName' => $module->getDisplayName(), 'modeName' => $modeName, 'machines' => json_encode(RunMode::getForMode($module, $modeId, true)), - 'redirect' => Request::get('redirect', '', 'string'), + 'redirect' => $redirect, ]); } diff --git a/modules-available/runmode/templates/module-machine-list.html b/modules-available/runmode/templates/module-machine-list.html index 61bbbad9..283fb393 100644 --- a/modules-available/runmode/templates/module-machine-list.html +++ b/modules-available/runmode/templates/module-machine-list.html @@ -41,8 +41,8 @@ {{/canedit}} {{#deleteUrl}} - - + + {{/deleteUrl}} -- cgit v1.2.3-55-g7522 From 9b8295a02aa5b8e864c1f42ec52ead4fe0dd3f2f Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 15 Jan 2018 17:21:18 +0100 Subject: [statistics] Properly display runmode name in client list --- modules-available/statistics/page.inc.php | 7 +++++++ modules-available/statistics/templates/clientlist.html | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/modules-available/statistics/page.inc.php b/modules-available/statistics/page.inc.php index ac103a41..5fe4ebfa 100644 --- a/modules-available/statistics/page.inc.php +++ b/modules-available/statistics/page.inc.php @@ -661,6 +661,13 @@ class Page_Statistics extends Page } } $row['cpumodel'] = preg_replace('/\(R\)|\(TM\)|\bintel\b|\bamd\b|\bcpu\b|dual-core|\bdual\s+core\b|\bdual\b|\bprocessor\b/i', ' ', $row['cpumodel']); + if (!empty($row['rmmodule'])) { + $data = RunMode::getRunMode($row['machineuuid'], RunMode::DATA_STRINGS); + if ($data !== false) { + $row['moduleName'] = $data['moduleName']; + $row['modeName'] = $data['modeName']; + } + } $rows[] = $row; } if ($singleMachine !== false && $singleMachine !== 'none') { diff --git a/modules-available/statistics/templates/clientlist.html b/modules-available/statistics/templates/clientlist.html index 0ddd98c8..d06eb4f7 100644 --- a/modules-available/statistics/templates/clientlist.html +++ b/modules-available/statistics/templates/clientlist.html @@ -72,7 +72,11 @@ {{/state_STANDBY}} {{hostname}}
{{machineuuid}}
- {{#rmmodule}}
{{lang_runMode}}: {{rmmodule}}
{{/rmmodule}} + {{#rmmodule}} +
{{lang_runMode}}: + {{moduleName}} / {{modeName}} +
+ {{/rmmodule}} -- cgit v1.2.3-55-g7522 From de8c8f6ba176855e5a461f0de1edd73793c74f8f Mon Sep 17 00:00:00 2001 From: Steffen Ritter Date: Tue, 16 Jan 2018 13:44:20 +0100 Subject: [syslog] Make client ip clickable, linking to statistics --- modules-available/syslog/page.inc.php | 4 ++-- modules-available/syslog/templates/page-syslog.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules-available/syslog/page.inc.php b/modules-available/syslog/page.inc.php index c679877a..153b591f 100644 --- a/modules-available/syslog/page.inc.php +++ b/modules-available/syslog/page.inc.php @@ -55,10 +55,10 @@ class Page_SysLog extends Page else $whereClause .= ' AND '; - $whereClause .= "machineuuid='" . preg_replace('/[^0-9a-zA-Z\-]/', '', Request::get('machineuuid', '', 'string')) . "'"; + $whereClause .= "machineuuid='" . preg_replace('/[^0-9a-zA-Z\-]/', '', Request::get('machineuuid', '', 'string')) . "'"; } $lines = array(); - $paginate = new Paginate("SELECT logid, dateline, logtypeid, clientip, description, extra FROM clientlog $whereClause ORDER BY logid DESC", 50); + $paginate = new Paginate("SELECT logid, dateline, logtypeid, clientip, machineuuid, description, extra FROM clientlog $whereClause ORDER BY logid DESC", 50); $res = $paginate->exec(); while ($row = $res->fetch(PDO::FETCH_ASSOC)) { $row['date'] = Util::prettyTime($row['dateline']); diff --git a/modules-available/syslog/templates/page-syslog.html b/modules-available/syslog/templates/page-syslog.html index 8b590038..d4709456 100644 --- a/modules-available/syslog/templates/page-syslog.html +++ b/modules-available/syslog/templates/page-syslog.html @@ -45,7 +45,7 @@ - +
{{lang_Roles}}{{lang_Selected}}{{lang_roles}}{{lang_selected}}
-
- {{subnet}}{{lastoctet}}
{{macaddr}}
{{lastseen}}
{{date}}{{clientip}}{{clientip}} {{description}} {{#extra}} file, $list); } diff --git a/modules-available/syslog/hooks/statistics-machine-replace.inc.php b/modules-available/syslog/hooks/statistics-machine-replace.inc.php deleted file mode 100644 index 6be0dd76..00000000 --- a/modules-available/syslog/hooks/statistics-machine-replace.inc.php +++ /dev/null @@ -1,5 +0,0 @@ - @@ -82,7 +85,7 @@
@@ -137,9 +137,9 @@
@@ -170,7 +170,7 @@ setTimepicker($('#settings-outer').find('.timepicker2')); - $('a.helptext').tooltip(); + $('p.helptext').tooltip(); $('#new-openingtime').click(function (e) { e.preventDefault(); diff --git a/modules-available/locationinfo/templates/ajax-config-server.html b/modules-available/locationinfo/templates/ajax-config-server.html index 940bc55a..8c2cb3ba 100644 --- a/modules-available/locationinfo/templates/ajax-config-server.html +++ b/modules-available/locationinfo/templates/ajax-config-server.html @@ -12,9 +12,9 @@ form="form-{{currentbackend}}"> @@ -34,9 +34,9 @@ @@ -92,7 +92,7 @@ currentBackend = value; } - $('a.btn[title]').tooltip(); + $('p.btn[title]').tooltip(); $('#myModalSubmitButton').attr('form', 'form-' + currentBackend); $('.settings-bs-switch').bootstrapSwitch({size:'small'}); diff --git a/modules-available/locationinfo/templates/page-config-panel-default.html b/modules-available/locationinfo/templates/page-config-panel-default.html index b55e3d4d..41a8fd00 100644 --- a/modules-available/locationinfo/templates/page-config-panel-default.html +++ b/modules-available/locationinfo/templates/page-config-panel-default.html @@ -28,9 +28,9 @@ @@ -48,9 +48,9 @@ @@ -69,9 +69,9 @@ @@ -85,9 +85,9 @@ @@ -101,9 +101,9 @@ @@ -128,9 +128,9 @@ max="1440" value="{{calupdate}}" required> @@ -145,9 +145,9 @@ max="86400" value="{{roomupdate}}" required> @@ -177,9 +177,9 @@ @@ -193,9 +193,9 @@ @@ -217,9 +217,9 @@ @@ -238,9 +238,9 @@ @@ -255,9 +255,9 @@ @@ -272,9 +272,9 @@ @@ -338,7 +338,7 @@ document.addEventListener("DOMContentLoaded", function () { var $locInput = $('#locationids'); // Initialize fancy tooltips - $('a.helptext').tooltip(); + $('p.helptext').tooltip(); // Add listener to range sliders so their label can be updated $('input[type="range"]').change(function () { $(this).siblings().find('.range-display').text($(this).val()); diff --git a/modules-available/locationinfo/templates/page-config-panel-summary.html b/modules-available/locationinfo/templates/page-config-panel-summary.html index 2a968fc2..3dc93680 100644 --- a/modules-available/locationinfo/templates/page-config-panel-summary.html +++ b/modules-available/locationinfo/templates/page-config-panel-summary.html @@ -28,9 +28,9 @@ @@ -48,9 +48,9 @@ @@ -64,9 +64,9 @@ @@ -151,7 +151,7 @@ document.addEventListener("DOMContentLoaded", function () { var $locInput = $('#locationids'); // Initialize fancy tooltips - $('a.helptext').tooltip(); + $('p.helptext').tooltip(); // Add listener to range sliders so their label can be updated $('input[type="range"]').change(function () { $(this).siblings().find('.range-display').text($(this).val()); diff --git a/modules-available/locationinfo/templates/page-config-panel-url.html b/modules-available/locationinfo/templates/page-config-panel-url.html index cca81509..798ff55d 100644 --- a/modules-available/locationinfo/templates/page-config-panel-url.html +++ b/modules-available/locationinfo/templates/page-config-panel-url.html @@ -25,9 +25,9 @@ @@ -42,9 +42,9 @@ placeholder="http://www.bwlehrpool.de/" pattern=".*://.*" required> @@ -61,9 +61,9 @@ @@ -77,9 +77,9 @@ @@ -95,6 +95,8 @@ \ No newline at end of file +//--> diff --git a/modules-available/locationinfo/templates/page-servers.html b/modules-available/locationinfo/templates/page-servers.html index eefb1ed5..dbf18b5f 100644 --- a/modules-available/locationinfo/templates/page-servers.html +++ b/modules-available/locationinfo/templates/page-servers.html @@ -60,7 +60,7 @@ diff --git a/modules-available/locationinfo/templates/server-prop-bool.html b/modules-available/locationinfo/templates/server-prop-bool.html index f430d02c..bd9dcc64 100644 --- a/modules-available/locationinfo/templates/server-prop-bool.html +++ b/modules-available/locationinfo/templates/server-prop-bool.html @@ -7,10 +7,10 @@
{{#helptext}} - +

- +

{{/helptext}}
- \ No newline at end of file + diff --git a/modules-available/locationinfo/templates/server-prop-dropdown.html b/modules-available/locationinfo/templates/server-prop-dropdown.html index 80667766..d1351551 100644 --- a/modules-available/locationinfo/templates/server-prop-dropdown.html +++ b/modules-available/locationinfo/templates/server-prop-dropdown.html @@ -10,10 +10,10 @@
{{#helptext}} - +

- +

{{/helptext}}
- \ No newline at end of file + diff --git a/modules-available/locationinfo/templates/server-prop-generic.html b/modules-available/locationinfo/templates/server-prop-generic.html index 9e94c23d..23ff1e4e 100644 --- a/modules-available/locationinfo/templates/server-prop-generic.html +++ b/modules-available/locationinfo/templates/server-prop-generic.html @@ -7,10 +7,10 @@
{{#helptext}} - +

- +

{{/helptext}}
- \ No newline at end of file + -- cgit v1.2.3-55-g7522 From 91cfd8710023456e4bf8928a6147e5ad5229040a Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 7 Feb 2018 14:30:28 +0100 Subject: [runmode] Fix error message if generic editor is not allowed, allow dnbd3 editor --- modules-available/dnbd3/hooks/runmode/config.json | 2 +- modules-available/runmode/page.inc.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules-available/dnbd3/hooks/runmode/config.json b/modules-available/dnbd3/hooks/runmode/config.json index 5db53f0b..a3f6d01f 100644 --- a/modules-available/dnbd3/hooks/runmode/config.json +++ b/modules-available/dnbd3/hooks/runmode/config.json @@ -3,6 +3,6 @@ "configHook": "Dnbd3Util::runmodeConfigHook", "noSysconfig": true, "systemdDefaultTarget": "dnbd3-proxy", - "allowGenericEditor": false, + "allowGenericEditor": true, "deleteUrlSnippet": "dummyparam=" } \ No newline at end of file diff --git a/modules-available/runmode/page.inc.php b/modules-available/runmode/page.inc.php index b94b8a31..8feb097e 100644 --- a/modules-available/runmode/page.inc.php +++ b/modules-available/runmode/page.inc.php @@ -183,7 +183,7 @@ class Page_RunMode extends Page Util::redirect($redirect); } if (!RunMode::getModuleConfig($moduleId)->allowGenericEditor) { - Message::addError('runmode.cannot-edit-module', $module); + Message::addError('runmode.cannot-edit-module', $moduleId); Util::redirect($redirect); } Render::addTemplate('machine-selector', [ -- cgit v1.2.3-55-g7522 From 798ff78db897fa44fa5d22847f6fec51069871ad Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 8 Feb 2018 12:16:55 +0100 Subject: [syslog] Add option to anonymize log entries after X days Closes #3301 --- modules-available/syslog/hooks/cron.inc.php | 21 +++++++++++++++++ modules-available/syslog/page.inc.php | 13 +++++++++++ .../syslog/templates/page-syslog.html | 26 ++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/modules-available/syslog/hooks/cron.inc.php b/modules-available/syslog/hooks/cron.inc.php index bae882a9..62516648 100644 --- a/modules-available/syslog/hooks/cron.inc.php +++ b/modules-available/syslog/hooks/cron.inc.php @@ -1,7 +1,28 @@ dateline"); + // Anonymize if requested + $days = Property::get('syslog.anon-days', 0); + if ($days > 0) { + $cutoff = time() - ($days * 86400); + Database::exec("UPDATE clientlog SET description = '[root] User logged in' + WHERE $cutoff > dateline AND logtypeid = 'session-open' AND description NOT LIKE '[root] User %'"); + Database::exec("UPDATE clientlog SET description = '[root] User logged out' + WHERE $cutoff > dateline AND logtypeid = 'session-close' AND description NOT LIKE '[root] User %'"); + Database::exec("UPDATE clientlog SET description = '-', extra = '' + WHERE $cutoff > dateline AND description NOT LIKE '-' + AND logtypeid NOT IN ('session-open', 'session-close', 'idleaction-busy', 'partition-temp', + 'partition-swap', 'smartctl-realloc', 'vmware-netifup', 'vmware-insmod', 'firewall-script-apply', + 'mount-vm-tmp-fail')"); + if (Module::get('statistics') !== false) { + Database::exec("UPDATE statistic SET username = 'anonymous' + WHERE $cutoff > dateline AND username NOT LIKE 'anonymous' AND username NOT LIKE ''"); + Database::exec("UPDATE machine SET currentuser = NULL + WHERE $cutoff > lastseen AND currentuser IS NOT NULL"); + } + } if (mt_rand(1, 100) === 1) { Database::exec("OPTIMIZE TABLE clientlog"); } diff --git a/modules-available/syslog/page.inc.php b/modules-available/syslog/page.inc.php index 153b591f..e63ada85 100644 --- a/modules-available/syslog/page.inc.php +++ b/modules-available/syslog/page.inc.php @@ -3,6 +3,9 @@ class Page_SysLog extends Page { + const PROP_ANON_DAYS = 'syslog.anon-days'; // Copy in cronjob + + protected function doPreprocess() { User::load(); @@ -11,6 +14,15 @@ class Page_SysLog extends Page Message::addError('main.no-permission'); Util::redirect('?do=Main'); } + if (($days = Request::post('anondays', false, 'int')) !== false) { + if ($days < 0 || $days > 180) { + Message::addError('anon-days-out-of-range', $days); + } else { + Property::set(self::PROP_ANON_DAYS, $days); + Message::addSuccess('anon-days-saved'); + } + Util::redirect('?do=syslog'); + } } protected function doRender() @@ -72,6 +84,7 @@ class Page_SysLog extends Page 'list' => $lines, 'types' => json_encode(array_values($types)), 'machineuuid' => Request::get('machineuuid'), + 'anondays' => Property::get(self::PROP_ANON_DAYS, 0), )); } diff --git a/modules-available/syslog/templates/page-syslog.html b/modules-available/syslog/templates/page-syslog.html index d4709456..585aa310 100644 --- a/modules-available/syslog/templates/page-syslog.html +++ b/modules-available/syslog/templates/page-syslog.html @@ -1,3 +1,6 @@ +

{{lang_clientLog}}