summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.idea/codeStyleSettings.xml1
-rw-r--r--.idea/php.xml9
-rw-r--r--inc/database.inc.php14
-rw-r--r--index.php4
-rw-r--r--modules-available/baseconfig/lang/de/template-tags.json4
-rw-r--r--modules-available/baseconfig/lang/en/template-tags.json4
-rw-r--r--modules-available/baseconfig/page.inc.php65
-rw-r--r--modules-available/baseconfig/templates/_page.html16
-rw-r--r--modules-available/baseconfig_bwlp/baseconfig/settings.json6
-rw-r--r--modules-available/baseconfig_bwlp/lang/de/config-variables.json1
-rw-r--r--modules-available/baseconfig_bwlp/lang/en/config-variables.json1
-rw-r--r--modules-available/dozmod/page.inc.php61
-rw-r--r--modules-available/locations/baseconfig/hook.json3
-rw-r--r--modules-available/locations/inc/location.inc.php16
-rw-r--r--modules-available/statistics_reporting/hooks/cron.inc.php3
-rw-r--r--modules-available/statistics_reporting/inc/getdata.inc.php1
-rw-r--r--modules-available/statistics_reporting/inc/queries.inc.php63
-rw-r--r--modules-available/statistics_reporting/inc/remotereport.inc.php62
-rw-r--r--modules-available/statistics_reporting/page.inc.php2
19 files changed, 261 insertions, 75 deletions
diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
index 9237b675..851e676d 100644
--- a/.idea/codeStyleSettings.xml
+++ b/.idea/codeStyleSettings.xml
@@ -47,6 +47,7 @@
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
<option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="true" />
+ <option name="ARRAY_INITIALIZER_WRAP" value="5" />
<option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
diff --git a/.idea/php.xml b/.idea/php.xml
deleted file mode 100644
index 2a5958c5..00000000
--- a/.idea/php.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="PhpProjectSharedConfiguration" php_language_level="5.4.0" />
- <component name="PhpUnit">
- <phpunit_settings>
- <PhpUnitSettings load_method="CUSTOM_LOADER" />
- </phpunit_settings>
- </component>
-</project> \ No newline at end of file
diff --git a/inc/database.inc.php b/inc/database.inc.php
index f3a90fe7..9153c688 100644
--- a/inc/database.inc.php
+++ b/inc/database.inc.php
@@ -53,6 +53,20 @@ class Database
return $res->fetch(PDO::FETCH_ASSOC);
}
+ /**
+ * If you need all rows for a query as plain array you can use this.
+ * Don't use this if you want to do further processing of the data, to save some
+ * memory.
+ *
+ * @return array|bool List of associative arrays representing rows, or false on error
+ */
+ public static function queryAll($query, $args = array(), $ignoreError = false)
+ {
+ $res = self::simpleQuery($query, $args, $ignoreError);
+ if ($res === false)
+ return false;
+ return $res->fetchAll(PDO::FETCH_ASSOC);
+ }
/**
* Execute the given query and return the number of rows affected.
diff --git a/index.php b/index.php
index 20049335..6f547418 100644
--- a/index.php
+++ b/index.php
@@ -123,9 +123,7 @@ if(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
}
}
Header('Expires: Wed, 29 Mar 2007 09:56:28 GMT');
-Header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
-Header("Cache-Control: post-check=0, pre-check=0", false);
-Header("Pragma: no-cache");
+Header("Cache-Control: max-age=0");
// Now determine which module to run
Page::init();
diff --git a/modules-available/baseconfig/lang/de/template-tags.json b/modules-available/baseconfig/lang/de/template-tags.json
index cdd54f6a..7d6da790 100644
--- a/modules-available/baseconfig/lang/de/template-tags.json
+++ b/modules-available/baseconfig/lang/de/template-tags.json
@@ -1,7 +1,9 @@
{
"lang_basicConfiguration": "Basiskonfiguration",
"lang_clientRelatedConfig": "Die Optionen auf dieser Seite beziehen sich auf das Verhalten der bwLehrpool-Clients.",
+ "lang_defaultValue": "Standard",
"lang_editOverrideNotice": "Sie bearbeiten die Einstellungen f\u00fcr einen Unterbereich",
"lang_enableOverride": "\u00dcberschreiben",
- "lang_settingActive": "Einstellung aktiv"
+ "lang_inheritSource": "Geerbt von",
+ "lang_settingActive": "Einstellung aktivieren"
} \ No newline at end of file
diff --git a/modules-available/baseconfig/lang/en/template-tags.json b/modules-available/baseconfig/lang/en/template-tags.json
index 8e75e5ac..1a32cb0d 100644
--- a/modules-available/baseconfig/lang/en/template-tags.json
+++ b/modules-available/baseconfig/lang/en/template-tags.json
@@ -1,7 +1,9 @@
{
"lang_basicConfiguration": "Basic Configuration",
"lang_clientRelatedConfig": "The options on this page are related to the bwLehrpool client machines.",
+ "lang_defaultValue": "Default",
"lang_editOverrideNotice": "You're editing the settings of a sub-section",
"lang_enableOverride": "Override",
- "lang_settingActive": "Setting active"
+ "lang_inheritSource": "Inherited from",
+ "lang_settingActive": "Enable setting"
} \ No newline at end of file
diff --git a/modules-available/baseconfig/page.inc.php b/modules-available/baseconfig/page.inc.php
index 5e99f2a0..bd9d6683 100644
--- a/modules-available/baseconfig/page.inc.php
+++ b/modules-available/baseconfig/page.inc.php
@@ -124,9 +124,6 @@ class Page_BaseConfig extends Page
Util::redirect('?do=BaseConfig');
}
}
- // List config options
- $settings = array();
- $vars = BaseConfigUtil::getVariables();
// Get stuff that's set in DB already
if ($this->targetModule === false) {
$fields = ', enabled';
@@ -141,19 +138,28 @@ class Page_BaseConfig extends Page
$where = '';
$params = array();
}
+ // List config options
+ $settings = array();
+ $vars = BaseConfigUtil::getVariables();
+ // Remember missing variables
+ $missing = $vars;
// Populate structure with existing config from db
- $res = Database::simpleQuery("SELECT setting, value, displayvalue $fields FROM {$this->qry_extra['table']} "
- . " {$where} ORDER BY setting ASC", $params);
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- if (!isset($vars[$row['setting']]) || !is_array($vars[$row['setting']])) {
- $unknown[] = $row['setting'];
- continue;
+ $this->fillSettings($vars, $settings, $missing, $this->qry_extra['table'], $fields, $where, $params, false);
+ if (isset($this->qry_extra['getfallback']) && !empty($missing)) {
+ $method = explode('::', $this->qry_extra['getfallback']);
+ $fieldValue = $this->qry_extra['field_value'];
+ $tries = 0;
+ while (++$tries < 100 && !empty($missing)) {
+ $ret = call_user_func($method, $fieldValue);
+ if ($ret === false)
+ break;
+ $fieldValue = $ret['value'];
+ $params = array('field_value' => $fieldValue);
+ $this->fillSettings($vars, $settings, $missing, $this->qry_extra['table'], $fields, $where, $params, $ret['display']);
}
- $row += $vars[$row['setting']];
- if (!isset($row['catid'])) {
- $row['catid'] = 'unknown';
- }
- $settings[$row['catid']]['settings'][$row['setting']] = $row;
+ }
+ if ($this->targetModule !== false && !empty($missing)) {
+ $this->fillSettings($vars, $settings, $missing, 'setting_global', '', '', array(), 'Global');
}
// Add entries that weren't in the db (global), setup override checkbox (module specific)
foreach ($vars as $key => $var) {
@@ -162,10 +168,7 @@ class Page_BaseConfig extends Page
if (!isset($settings[$var['catid']]['settings'][$key]['enabled']) || $settings[$var['catid']]['settings'][$key]['enabled'] == 1) {
$settings[$var['catid']]['settings'][$key]['checked'] = 'checked';
}
- } elseif (isset($settings[$var['catid']]['settings'][$key])) {
- // Module specific - value is set in DB
- $settings[$var['catid']]['settings'][$key]['checked'] = 'checked';
- } else {
+ } elseif (!isset($settings[$var['catid']]['settings'][$key])) {
// Module specific - value is not set in DB
$settings[$var['catid']]['settings'][$key] = $var + array(
'setting' => $key
@@ -216,6 +219,32 @@ class Page_BaseConfig extends Page
Module::isAvailable('bootstrap_switch');
}
+ private function fillSettings($vars, &$settings, &$missing, $table, $fields, $where, $params, $sourceName)
+ {
+ $res = Database::simpleQuery("SELECT setting, value, displayvalue $fields FROM $table "
+ . " {$where} ORDER BY setting ASC", $params);
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ if (!isset($missing[$row['setting']]))
+ continue;
+ if (!isset($vars[$row['setting']]) || !is_array($vars[$row['setting']])) {
+ $unknown[] = $row['setting'];
+ continue;
+ }
+ unset($missing[$row['setting']]);
+ if ($sourceName !== false) {
+ $row['defaultvalue'] = '';
+ $row['defaultsource'] = $sourceName;
+ } elseif ($this->targetModule !== false) {
+ $row['checked'] = 'checked';
+ }
+ $row += $vars[$row['setting']];
+ if (!isset($row['catid'])) {
+ $row['catid'] = 'unknown';
+ }
+ $settings[$row['catid']]['settings'][$row['setting']] = $row;
+ }
+ }
+
private function getCurrentModuleName()
{
if (isset($this->qry_extra['tostring'])) {
diff --git a/modules-available/baseconfig/templates/_page.html b/modules-available/baseconfig/templates/_page.html
index 7f380495..e0be35bc 100644
--- a/modules-available/baseconfig/templates/_page.html
+++ b/modules-available/baseconfig/templates/_page.html
@@ -25,18 +25,22 @@
<div class="row">
<div class="col-md-5 slx-cfg-toggle">
<div>{{setting}}</div>
- {{^override}}
<div class="slx-default">
+ {{#defaultvalue}}{{lang_defaultValue}}:{{/defaultvalue}}
{{defaultvalue}}
</div>
- <input class="bs-switch" name="override[{{setting}}]" id="CB_{{setting}}" type="checkbox" {{checked}}> <label for="CB_{{setting}}">{{lang_settingActive}}</label>
- {{/override}}
- {{#override}}
- <input class="bs-switch" name="override[{{setting}}]" id="CB_{{setting}}" type="checkbox" {{checked}}> <label for="CB_{{setting}}">{{lang_enableOverride}}</label>
- {{/override}}
+ <input class="bs-switch" name="override[{{setting}}]" id="CB_{{setting}}" type="checkbox" {{checked}}>
+ <label for="CB_{{setting}}">
+ {{#override}}{{lang_enableOverride}}{{/override}}
+ {{^override}}{{lang_settingActive}}{{/override}}
+ </label>
</div>
<div class="col-md-5">
{{{item}}}
+ <div class="slx-default">
+ {{#defaultsource}}{{lang_inheritSource}}:{{/defaultsource}}
+ {{defaultsource}}
+ </div>
</div>
<div class="col-md-2">
<a class="btn btn-default" data-toggle="modal" data-target="#help-{{setting}}"><span class="glyphicon glyphicon-question-sign"></span></a>
diff --git a/modules-available/baseconfig_bwlp/baseconfig/settings.json b/modules-available/baseconfig_bwlp/baseconfig/settings.json
index e9a0a894..3eebcc1f 100644
--- a/modules-available/baseconfig_bwlp/baseconfig/settings.json
+++ b/modules-available/baseconfig_bwlp/baseconfig/settings.json
@@ -132,5 +132,11 @@
"defaultvalue": "",
"permissions": "2",
"validator": ""
+ },
+ "SLX_AUTOSTART_UUID": {
+ "catid": "vmchooser",
+ "defaultvalue": "",
+ "permissions": "2",
+ "validator": "regex:\/^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|)$\/i"
}
}
diff --git a/modules-available/baseconfig_bwlp/lang/de/config-variables.json b/modules-available/baseconfig_bwlp/lang/de/config-variables.json
index 63ddf280..a19c89ac 100644
--- a/modules-available/baseconfig_bwlp/lang/de/config-variables.json
+++ b/modules-available/baseconfig_bwlp/lang/de/config-variables.json
@@ -1,5 +1,6 @@
{
"SLX_ADDONS": "Zu ladende Addons. Zur Zeit steht nur *vmware* zur Verf\u00fcgung.",
+ "SLX_AUTOSTART_UUID": "ID einer Veranstaltung die automatisch gestartet werden soll. Die Veranstaltungs-ID finden Sie im Detailfenster innerhalb der bwLehrpool-Suite.\r\n\r\n*Hinweis: Diese Option ist eine tempor\u00e4re \u00dcbergangsl\u00f6sung. In sp\u00e4teren Versionen wird die Funktionalit\u00e4t einfacher erreichbar sein.*",
"SLX_BIOS_CLOCK": "Legt fest, ob und wie die interne Uhr des Rechners im Bezug auf die Systemzeit des \/MiniLinux\/ gesetzt werden soll.\r\n*off* = Die interne Uhr des Rechners wird nicht ver\u00e4ndert.\r\n*local* = Die interne Uhr wird auf die Lokalzeit gesetzt. Bevorzugt wenn z.B. noch eine native Windows-Installation auf dem PC vorhanden ist.\r\n*utc* = Die interne Uhr wird auf die \/Koordinierte Weltzeit\/ gesetzt. Dies ist die g\u00e4ngige Einstellung in einem reinen Linux-Umfeld.",
"SLX_DEMO_PASS": "Passwort f\u00fcr den eingebauten *demo*-Account. Leer lassen, um das Einloggen zu verbieten.\r\nDas Passwort wird wie das root-Passwort nur gehasht an den Client \u00fcbertragen.",
"SLX_LOGOUT_TIMEOUT": "Zeit \/in Sekunden\/, die eine Benutzersitzung ohne Aktion sein darf, bevor sie beendet wird.Feld leer lassen, um die Funktion zu deaktivieren.",
diff --git a/modules-available/baseconfig_bwlp/lang/en/config-variables.json b/modules-available/baseconfig_bwlp/lang/en/config-variables.json
index ad1601c3..64788fee 100644
--- a/modules-available/baseconfig_bwlp/lang/en/config-variables.json
+++ b/modules-available/baseconfig_bwlp/lang/en/config-variables.json
@@ -1,5 +1,6 @@
{
"SLX_ADDONS": "Addons to load. Currently, only *vmware* is available.",
+ "SLX_AUTOSTART_UUID": "ID of a lecture which is automatically started. The lecture-ID is found in the detail window of a lecture in the bwLehrpool-Suite. \r\n\r\n*This solution is only temporary. In later versions this feature will probably be moved to another section*",
"SLX_BIOS_CLOCK": "Specifies whether and how the internal clock of the computer should be set in relation to the system time of the \/MiniLinux\/.\r\n*off* = The internal clock of the computer is not changed.\r\n*local* = The internal clock is set to local time. Preferably if, for example, there is still a native Windows installation available on the PC.\r\n*utc* = The internal clock is set to the \/Coordinated Universal Time\/. This is the most common setup in a pure Linux environment.",
"SLX_DEMO_PASS": "Password for the *demo* account. Leave empty to disallow logging in as the demo user.\r\nLike the root password, the demo user's password will be sent to the client in its hashed form.",
"SLX_LOGOUT_TIMEOUT": "Time \/in seconds\/, in which a user session may remain without action before it is terminated.Leave field blank to disable the function.",
diff --git a/modules-available/dozmod/page.inc.php b/modules-available/dozmod/page.inc.php
index 7f1e6ee3..9635aef1 100644
--- a/modules-available/dozmod/page.inc.php
+++ b/modules-available/dozmod/page.inc.php
@@ -32,7 +32,25 @@ class Page_DozMod extends Page
Util::redirect('?do=Main');
}
+ /* execute actions */
+ $action = Request::post('action', false, 'string');
+
+ if ($action === 'mail') {
+ $this->mailHandler();
+ } elseif ($action === 'runtime') {
+ $this->runtimeHandler();
+ } elseif ($action === 'delimages') {
+ $result = $this->handleDeleteImages();
+ if (!empty($result)) {
+ Message::addInfo('delete-images', $result);
+ }
+ Util::redirect('?do=DozMod');
+ } elseif ($action !== false) {
+ Util::traceError('Invalid action: ' . $action);
+ }
+
/* add sub-menus */
+ Dashboard::addSubmenu('?do=dozmod&section=expiredimages', Dictionary::translate('submenu_expiredimages', true));
Dashboard::addSubmenu('?do=dozmod&section=mailconfig', Dictionary::translate('submenu_mailconfig', true));
Dashboard::addSubmenu('?do=dozmod&section=templates', Dictionary::translate('submenu_templates', true));
Dashboard::addSubmenu('?do=dozmod&section=runtimeconfig', Dictionary::translate('submenu_runtime', true));
@@ -44,37 +62,34 @@ class Page_DozMod extends Page
$this->subPage->doPreprocess();
return;
}
-
- /* execute actions */
- $action = Request::post('action');
-
- if ($action === 'mail') {
- $this->mailHandler();
- }
- if ($action === 'runtime') {
- $this->runtimeHandler();
- }
- if ($action === 'delimages') {
- $result = $this->handleDeleteImages();
- if (!empty($result)) {
- Message::addInfo('delete-images', $result);
- }
- Util::redirect('?do=DozMod');
- }
}
protected function doRender()
{
- $this->listDeletePendingImages();
-
/* different pages for different sections */
if ($this->subPage !== false) {
$this->subPage->doRender();
return;
}
- $section = Request::get('section', 'mailconfig', 'string');
+ $section = Request::get('section', false, 'string');
+
+ if ($section === false || $section === 'expiredimages') {
+ $expiredImages = $this->loadExpiredImages();
+ if ($section === false && empty($expiredImages)) {
+ $section = 'mailconfig';
+ } else {
+ $section = 'expiredimages';
+ }
+ }
+ if ($section === 'expiredimages') {
+ if (empty($expiredImages)) {
+ Message::addSuccess('no-expired-images');
+ } else {
+ Render::addTemplate('images-delete', array('images' => $expiredImages));
+ }
+ }
if ($section === 'mailconfig') {
// Mail config
$mailConf = Database::queryFirst('SELECT value FROM sat.configuration WHERE parameter = :param', array('param' => 'mailconfig'));
@@ -140,7 +155,7 @@ class Page_DozMod extends Page
Render::addTemplate('blockstats', $data);
}
- private function listDeletePendingImages()
+ private function loadExpiredImages()
{
$res = Database::simpleQuery("SELECT b.displayname,"
. " own.firstname, own.lastname, own.email,"
@@ -168,9 +183,7 @@ class Page_DozMod extends Page
$row['filesize'] = Util::readableFileSize($row['filesize']);
$rows[] = $row;
}
- if (empty($rows))
- return;
- Render::addTemplate('images-delete', array('images' => $rows));
+ return $rows;
}
private function cleanMailArray()
diff --git a/modules-available/locations/baseconfig/hook.json b/modules-available/locations/baseconfig/hook.json
index c295e0f6..b7b3581b 100644
--- a/modules-available/locations/baseconfig/hook.json
+++ b/modules-available/locations/baseconfig/hook.json
@@ -1,5 +1,6 @@
{
"table": "setting_location",
"field": "locationid",
- "tostring": "Location::getName"
+ "tostring": "Location::getName",
+ "getfallback": "Location::getBaseconfigParent"
} \ No newline at end of file
diff --git a/modules-available/locations/inc/location.inc.php b/modules-available/locations/inc/location.inc.php
index 7ac76b3e..8f3447da 100644
--- a/modules-available/locations/inc/location.inc.php
+++ b/modules-available/locations/inc/location.inc.php
@@ -286,6 +286,22 @@ class Location
}
/**
+ * @param $locationId
+ * @return bool|array ('value' => x, 'display' => y), false if no parent or unknown id
+ */
+ public static function getBaseconfigParent($locationId)
+ {
+ settype($locationId, 'integer');
+ $locations = Location::getLocationsAssoc();
+ if (!isset($locations[$locationId]))
+ return false;
+ $locationId = (int)$locations[$locationId]['parentlocationid'];
+ if (!isset($locations[$locationId]))
+ return false;
+ return array('value' => $locationId, 'display' => $locations[$locationId]['locationname']);
+ }
+
+ /**
* @return array list of subnets as numeric array
*/
public static function getSubnets()
diff --git a/modules-available/statistics_reporting/hooks/cron.inc.php b/modules-available/statistics_reporting/hooks/cron.inc.php
index afb18a23..14597f7d 100644
--- a/modules-available/statistics_reporting/hooks/cron.inc.php
+++ b/modules-available/statistics_reporting/hooks/cron.inc.php
@@ -7,10 +7,9 @@ if (RemoteReport::isReportingEnabled()) {
while ($nextReporting <= time()) {
RemoteReport::writeNextReportingTimestamp();
- $from = strtotime("-7 days", $nextReporting);
$to = $nextReporting;
- $statisticsReport = json_encode(RemoteReport::generateReport($from, $to));
+ $statisticsReport = json_encode(RemoteReport::generateReport($to));
$params = array("action" => "statistics", "data" => $statisticsReport);
diff --git a/modules-available/statistics_reporting/inc/getdata.inc.php b/modules-available/statistics_reporting/inc/getdata.inc.php
index da3a9a26..ae4d5aa4 100644
--- a/modules-available/statistics_reporting/inc/getdata.inc.php
+++ b/modules-available/statistics_reporting/inc/getdata.inc.php
@@ -29,6 +29,7 @@ class GetData
$data["medianSessionLength_s"] = self::formatSeconds($data["medianSessionLength"]);
$data["totalOffTime_s"] = self::formatSeconds($data["totalOffTime"]);
}
+ $data['uniqueUsers'] = Queries::getUniqueUserCount(self::$from, self::$to);
return $data;
}
diff --git a/modules-available/statistics_reporting/inc/queries.inc.php b/modules-available/statistics_reporting/inc/queries.inc.php
index 2269e764..1a125c9e 100644
--- a/modules-available/statistics_reporting/inc/queries.inc.php
+++ b/modules-available/statistics_reporting/inc/queries.inc.php
@@ -213,5 +213,68 @@ class Queries
";
return "(".$queryString.")";
}
+
+ public static function getDozmodStats($from, $to)
+ {
+ if (!Module::isAvailable('dozmod'))
+ return array('disabled' => true);
+
+ $return = array();
+ $return['vms'] = Database::queryFirst("SELECT Count(*) AS `total`, Sum(If(createtime >= $from, 1, 0)) AS `new`,
+ Sum(If(updatetime >= $from, 1, 0)) AS `updated`, Sum(If(latestversionid IS NOT NULL, 1, 0)) AS `valid`
+ FROM sat.imagebase
+ WHERE createtime <= $to");
+ $return['lectures'] = Database::queryFirst("SELECT Count(*) AS `total`, Sum(If(createtime >= $from, 1, 0)) AS `new`,
+ Sum(If(updatetime >= $from, 1, 0)) AS `updated`,
+ Sum(If((($from BETWEEN starttime AND endtime) OR ($to BETWEEN starttime AND endtime)) AND isenabled <> 0, 1, 0)) AS `valid`
+ FROM sat.lecture
+ WHERE createtime <= $to");
+ $return['users'] = Database::queryFirst("SELECT Count(*) AS `total`, Count(DISTINCT organizationid) AS `organizations`
+ FROM sat.user
+ WHERE lastlogin >= $from");
+ return $return;
+ }
+
+ public static function getAggregatedMachineStats($from)
+ {
+ $return = array();
+ $return['location'] = Database::queryAll("SELECT MD5(CONCAT(locationid, :salt)) AS `location`, Count(*) AS `count`
+ FROM machine
+ WHERE lastseen >= $from
+ GROUP BY locationid",
+ array('salt' => GetData::$salt));
+ $prev = 0;
+ $str = ' ';
+ foreach (array(0.5, 1, 1.5, 2, 3, 4, 6, 8, 10, 12, 16, 20, 24, 28, 32, 40, 48, 64, 72, 80, 88, 96, 128, 192, 256) as $val) {
+ $str .= 'WHEN mbram < ' . round(($val + $prev) * 512) . " THEN '" . $prev . "' ";
+ $prev = $val;
+ }
+ $return['ram'] = Database::queryAll("SELECT CASE $str ELSE 'OVER 9000' END AS `gbram`, Count(*) AS `total`
+ FROM machine
+ WHERE lastseen >= $from
+ GROUP BY gbram");
+ foreach (array('cpumodel', 'systemmodel', 'realcores', 'kvmstate') as $key) {
+ $return[$key] = Database::queryAll("SELECT $key, Count(*) AS `total`
+ FROM machine
+ WHERE lastseen >= $from
+ GROUP BY $key");
+ }
+ return $return;
+ }
+
+ /**
+ * @param int $from start timestamp
+ * @param int $to end timestamp
+ * @return int count of user active in timespan
+ */
+ public static function getUniqueUserCount($from, $to)
+ {
+ $res = Database::queryFirst("SELECT Count(DISTINCT username) as `total`
+ FROM statistic
+ WHERE (dateline BETWEEN $from AND $to) AND typeid = '.vmchooser-session-name'
+ GROUP BY username");
+ return (int)$res['total'];
+ }
+
}
diff --git a/modules-available/statistics_reporting/inc/remotereport.inc.php b/modules-available/statistics_reporting/inc/remotereport.inc.php
index 4c5f604b..68a3e95e 100644
--- a/modules-available/statistics_reporting/inc/remotereport.inc.php
+++ b/modules-available/statistics_reporting/inc/remotereport.inc.php
@@ -63,19 +63,63 @@ class RemoteReport
* Generate the multi-dimensional array containing the anonymized
* (weekly) statistics to report.
*
- * @param int $from start timestamp
* @param int $to end timestamp
+ * @param int[] $days list of days to generate aggregated stats for
* @return array wrapped up statistics, ready for reporting
*/
- public static function generateReport($from, $to) {
- GetData::$from = $from;
- GetData::$to = $to;
+ public static function generateReport($to, $days = false) {
+ if ($days === false) {
+ $days = [7, 30, 90];
+ }
GetData::$salt = bin2hex(Util::randomBytes(20, false));
- $data = GetData::total(GETDATA_ANONYMOUS);
- $data['perLocation'] = GetData::perLocation(GETDATA_ANONYMOUS);
- $data['perVM'] = GetData::perVM(GETDATA_ANONYMOUS);
- $data['tsFrom'] = $from;
- $data['tsTo'] = $to;
+ GetData::$lowerTimeBound = 7;
+ GetData::$upperTimeBound = 20;
+ $result = array();
+ foreach ($days as $day) {
+ if (isset($result['days' . $day]))
+ continue;
+ $from = strtotime("-{$day} days", $to);
+ GetData::$from = $from;
+ GetData::$to = $to;
+ $data = array('total' => GetData::total(GETDATA_ANONYMOUS));
+ $data['perLocation'] = GetData::perLocation(GETDATA_ANONYMOUS);
+ $data['perVM'] = GetData::perVM(GETDATA_ANONYMOUS);
+ $data['tsFrom'] = $from;
+ $data['tsTo'] = $to;
+ $data['dozmod'] = Queries::getDozmodStats($from, $to);
+ $data['machines'] = Queries::getAggregatedMachineStats($from);
+ $result['days' . $day] = $data;
+ }
+ $result['server'] = self::getLocalHardware();
+ $result['version'] = CONFIG_FOOTER;
+ return $result;
+ }
+
+ private function getLocalHardware()
+ {
+ $cpuInfo = file_get_contents('/proc/cpuinfo');
+ $uptime = file_get_contents('/proc/uptime');
+ $memInfo = file_get_contents('/proc/meminfo');
+ preg_match_all('/\b(\w+):\s+(\d+)\s/s', $memInfo, $out, PREG_SET_ORDER);
+ $mem = array();
+ foreach ($out as $e) {
+ $mem[$e[1]] = $e[2];
+ }
+ //
+ $data = array();
+ $data['cpuCount'] = preg_match_all('/\bprocessor\s+:\s+(.*)$/m', $cpuInfo, $out);
+ if ($data['cpuCount'] > 0) {
+ $data['cpuModel'] = $out[1][0];
+ }
+ if (preg_match('/^(\d+)\D/', $uptime, $out)) {
+ $data['uptime'] = $out[1];
+ }
+ if (isset($mem['MemTotal']) && isset($mem['MemFree']) && isset($mem['SwapTotal'])) {
+ $data['memTotal'] = $mem['MemTotal'];
+ $data['memFree'] = ($mem['MemFree'] + $mem['Buffers'] + $mem['Cached']);
+ $data['swapTotal'] = $mem['SwapTotal'];
+ $data['swapUsed'] = ($mem['SwapTotal'] - $mem['SwapFree']);
+ }
return $data;
}
diff --git a/modules-available/statistics_reporting/page.inc.php b/modules-available/statistics_reporting/page.inc.php
index 6bd908a5..52accaea 100644
--- a/modules-available/statistics_reporting/page.inc.php
+++ b/modules-available/statistics_reporting/page.inc.php
@@ -58,7 +58,7 @@ class Page_Statistics_Reporting extends Page
// Get report - fetch data exactly the way it would automatically be reported
// so the user can know what is going on
if ($this->action === 'getreport') {
- $report = RemoteReport::generateReport(strtotime('-7 days'), time('now'));
+ $report = RemoteReport::generateReport(time());
Header('Content-Disposition: attachment; filename=remote-report.json');
Header('Content-Type: application/json; charset=utf-8');
die(json_encode($report));