diff options
Diffstat (limited to 'modules-available')
42 files changed, 320 insertions, 130 deletions
diff --git a/modules-available/baseconfig/lang/de/messages.json b/modules-available/baseconfig/lang/de/messages.json index 468c87b2..a0b8cdd4 100644 --- a/modules-available/baseconfig/lang/de/messages.json +++ b/modules-available/baseconfig/lang/de/messages.json @@ -1,3 +1,5 @@ { + "invalid-hook": "Ung\u00fcltiger Hook: {{0}}", + "no-module-hook": "Modul {{0}} hat keinen Hook", "settings-updated": "Einstellungen wurden aktualisiert" }
\ No newline at end of file diff --git a/modules-available/baseconfig/lang/en/messages.json b/modules-available/baseconfig/lang/en/messages.json index b388e627..0e2ac9fe 100644 --- a/modules-available/baseconfig/lang/en/messages.json +++ b/modules-available/baseconfig/lang/en/messages.json @@ -1,3 +1,5 @@ { + "invalid-hook": "Module {{0}} has an invalid baseconfig hook", + "no-module-hook": "Module {{0}} doesn't have a baseconfig hook", "settings-updated": "Settings have been updated" }
\ No newline at end of file diff --git a/modules-available/baseconfig_bwlp/config.json b/modules-available/baseconfig_bwlp/config.json new file mode 100644 index 00000000..af67a188 --- /dev/null +++ b/modules-available/baseconfig_bwlp/config.json @@ -0,0 +1,3 @@ +{ + "dependencies": ["baseconfig"] +} diff --git a/modules-available/baseconfig/hooks/translation.inc.php b/modules-available/baseconfig_bwlp/hooks/translation.inc.php index 7588fe38..7588fe38 100644 --- a/modules-available/baseconfig/hooks/translation.inc.php +++ b/modules-available/baseconfig_bwlp/hooks/translation.inc.php diff --git a/modules-available/baseconfig_bwlp/lang/de/config-variables.json b/modules-available/baseconfig_bwlp/lang/de/config-variables.json index af1007be..62c64da9 100644 --- a/modules-available/baseconfig_bwlp/lang/de/config-variables.json +++ b/modules-available/baseconfig_bwlp/lang/de/config-variables.json @@ -2,6 +2,7 @@ "SLX_ADDONS": "Zu ladende Addons. Zur Zeit steht nur *vmware* zur Verf\u00fcgung.", "SLX_BENCHMARK_VM": "Tragen Sie hier den exakten Namen einer Veranstaltung, wie sie im *vmchooser* auftaucht ein, um diese VM nach dem Booten automatisch zu starten. Dies ist n\u00fctzlich f\u00fcr Bootzeitmessungen. Feld leer lassen, um Funktion zu deaktivieren.", "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_BWIDM_AUTH": "Anmeldung am Client mittels bwIDM zulassen.\r\n\r\nWenn Sie diese Option aktivieren, k\u00f6nnen sich alle Nutzer, die Mitglieder einer Organisation im bwIDM-Verbund sind, an einem bwLehrpool-Rechner einloggen.", "SLX_COMMON_SHARE_AUTH": "Authentifizierungsmethode f\u00fcr das gemeinsame Netzlaufwerk. *guest* bedeutet, dass keine Authentifizierung notwendig ist, *user* bedeutet, dass die Credentials des angemeldeten Benutzers verwendet werden.", "SLX_COMMON_SHARE_PATH": "Netzwerkpfad des gemeinsamen Netzlaufwerks. Es werden NFS (keine Authentifizierung) und CIFS\/SMB (mit und ohne Authentifizierung) unterst\u00fctzt.", "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.", diff --git a/modules-available/baseconfig_bwlp/lang/en/config-variables.json b/modules-available/baseconfig_bwlp/lang/en/config-variables.json index 36ac6e8c..3d37c066 100644 --- a/modules-available/baseconfig_bwlp/lang/en/config-variables.json +++ b/modules-available/baseconfig_bwlp/lang/en/config-variables.json @@ -2,6 +2,7 @@ "SLX_ADDONS": "Addons to load. Currently, only *vmware* is available.", "SLX_BENCHMARK_VM": "If non-empty, this should be the exact display name of an entry in *vmchooser*, so it will be automatically started after bootup. Useful for benchmarking.", "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_BWIDM_AUTH": "Enable logging in on clients using bwIDM credentials.\r\n\r\nEnabling this setting means that all members of an organization in the bwIDM federation can log in to bwLehrpool machines.", "SLX_COMMON_SHARE_AUTH": "Athentication method for the common network share. *guest* means no authentication (public share), *user* means the user's credentials will be used.", "SLX_COMMON_SHARE_PATH": "Path of network share. Supported are NFS (no authentication only) and CIFS\/SMB (with and without authentication).", "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.", diff --git a/modules-available/exams/config.json b/modules-available/exams/config.json index c0077970..95d8aa3e 100644 --- a/modules-available/exams/config.json +++ b/modules-available/exams/config.json @@ -1,5 +1,5 @@ { "category":"main.content", - "dependencies": [ "locations", "visjs", "bootstrap_datepicker", "bootstrap_timepicker", "bootstrap_multiselect"], + "dependencies": [ "locations", "js_vis", "bootstrap_datepicker", "bootstrap_timepicker", "bootstrap_multiselect"], "permission": "0" } diff --git a/modules-available/exams/lang/en/module.json b/modules-available/exams/lang/en/module.json new file mode 100644 index 00000000..a066b3aa --- /dev/null +++ b/modules-available/exams/lang/en/module.json @@ -0,0 +1,6 @@ +{ + "module_name": "Exam mode", + "title_add-exam": "Add exam", + "title_edit-exam": "Edit exam", + "warning_lecture_is_not_enabled": "Warning: Lecture is not enabled by tutor" +}
\ No newline at end of file diff --git a/modules-available/exams/lang/pt/template-tags.json b/modules-available/exams/lang/pt/template-tags.json deleted file mode 100644 index 524f3dd5..00000000 --- a/modules-available/exams/lang/pt/template-tags.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "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 diff --git a/modules-available/imgmanagement/lang/de/module.json b/modules-available/imgmanagement/lang/de/module.json new file mode 100644 index 00000000..aff88855 --- /dev/null +++ b/modules-available/imgmanagement/lang/de/module.json @@ -0,0 +1,3 @@ +{ + "module_name": "Image-Verwaltung" +}
\ No newline at end of file diff --git a/modules-available/imgmanagement/lang/en/module.json b/modules-available/imgmanagement/lang/en/module.json new file mode 100644 index 00000000..0d1f4c24 --- /dev/null +++ b/modules-available/imgmanagement/lang/en/module.json @@ -0,0 +1,3 @@ +{ + "module_name": "Image management" +}
\ No newline at end of file diff --git a/modules-available/momentjs/clientscript.js b/modules-available/js_moment/clientscript.js index 4b3fe51a..4b3fe51a 100644 --- a/modules-available/momentjs/clientscript.js +++ b/modules-available/js_moment/clientscript.js diff --git a/modules-available/momentjs/config.json b/modules-available/js_moment/config.json index d1261653..d1261653 100644 --- a/modules-available/momentjs/config.json +++ b/modules-available/js_moment/config.json diff --git a/modules-available/visjs/clientscript.js b/modules-available/js_vis/clientscript.js index 92b8ed75..92b8ed75 100644 --- a/modules-available/visjs/clientscript.js +++ b/modules-available/js_vis/clientscript.js diff --git a/modules-available/js_vis/config.json b/modules-available/js_vis/config.json new file mode 100644 index 00000000..ccdf64b7 --- /dev/null +++ b/modules-available/js_vis/config.json @@ -0,0 +1,3 @@ +{ + "dependencies" : ["js_moment"] +} diff --git a/modules-available/visjs/style.css b/modules-available/js_vis/style.css index 40d182cf..40d182cf 100644 --- a/modules-available/visjs/style.css +++ b/modules-available/js_vis/style.css diff --git a/modules-available/locations/clientscript.js b/modules-available/locations/clientscript.js new file mode 100644 index 00000000..ad3e6c43 --- /dev/null +++ b/modules-available/locations/clientscript.js @@ -0,0 +1,66 @@ +function ip2long(IP) { + var i = 0; + IP = IP.match(/^([1-9]\d*|0[0-7]*|0x[\da-f]+)(?:\.([1-9]\d*|0[0-7]*|0x[\da-f]+))?(?:\.([1-9]\d*|0[0-7]*|0x[\da-f]+))?(?:\.([1-9]\d*|0[0-7]*|0x[\da-f]+))?$/i); + if (!IP) { + return false; + } + IP.push(0, 0, 0, 0); + for (i = 1; i < 5; i += 1) { + IP[i] = parseInt(IP[i]) || 0; + if (IP[i] < 0 || IP[i] > 255) + return false; + } + return IP[1] * 16777216 + IP[2] * 65536 + IP[3] * 256 + IP[4] * 1; +} + +function long2ip(a) { + return [ + a >>> 24, + 255 & a >>> 16, + 255 & a >>> 8, + 255 & a + ].join('.'); +} + +function cidrToRange(cidr) { + var range = [2]; + cidr = cidr.split('/'); + var cidr_1 = parseInt(cidr[1]); + if (cidr_1 <= 0 || cidr_1 > 32) + return false; + var param = ip2long(cidr[0]); + if (param === false) + return false; + range[0] = long2ip((param) & ((-1 << (32 - cidr_1)))); + var start = ip2long(range[0]); + range[1] = long2ip(start + Math.pow(2, (32 - cidr_1)) - 1); + return range; +} + +/** + * Add listener to start IP input; when it loses focus, see if we have a + * CIDR notation and fill out start+end field. + */ +function slxAttachCidr() { + $('.cidrmagic').each(function () { + var t = $(this); + var s = t.find('input.cidrstart'); + var e = t.find('input.cidrend'); + if (!s || !e) + return; + t.removeClass('cidrmagic'); + s.focusout(function () { + var val = s.val(); + if (val.match(/^[0-9]+\.[0-9]+(\.[0-9]+(\.[0-9]+)?)?\/[0-9]{2}$/)) { + var res = cidrToRange(val); + if (res === false) + return; + s.val(res[0]); + e.val(res[1]); + } + }); + }); +} + +// Attach +slxAttachCidr();
\ No newline at end of file diff --git a/modules-available/locations/page.inc.php b/modules-available/locations/page.inc.php index de724350..02f33bb3 100644 --- a/modules-available/locations/page.inc.php +++ b/modules-available/locations/page.inc.php @@ -21,8 +21,43 @@ class Page_Locations extends Page $this->updateLocation(); } elseif ($this->action === 'addlocations') { $this->addLocations(); + } elseif ($this->action === 'updatesubnets') { + $this->updateSubnets(); } } + + private function updateSubnets() + { + $count = 0; + $starts = Request::post('startaddr', false); + $ends = Request::post('endaddr', false); + $locs = Request::post('location', false); + if (!is_array($starts) || !is_array($ends) || !is_array($locs)) { + Message::addError('main.empty-field'); + Util::redirect('?do=Locations'); + } + $existingLocs = Location::getLocationsAssoc(); + $stmt = Database::prepare("UPDATE subnet SET startaddr = :startLong, endaddr = :endLong, locationid = :loc WHERE subnetid = :subnetid"); + foreach ($starts as $subnetid => $start) { + if (!isset($ends[$subnetid]) || !isset($locs[$subnetid])) + continue; + $loc = (int)$locs[$subnetid]; + $end = $ends[$subnetid]; + if (!isset($existingLocs[$loc])) { + Message::addError('main.value-invalid', 'locationid', $loc); + continue; + } + $range = $this->rangeToLongVerbose($start, $end); + if ($range === false) + continue; + list($startLong, $endLong) = $range; + if ($stmt->execute(compact('startLong', 'endLong', 'loc', 'subnetid'))) { + $count += $stmt->rowCount(); + } + } + Message::addSuccess('subnets-updated', $count); + Util::redirect('?do=Locations'); + } private function addLocations() { @@ -147,7 +182,7 @@ class Page_Locations extends Page Message::addSuccess('location-updated', $newName); } } - + private function updateLocationSubnets() { // Deletion first @@ -177,18 +212,10 @@ class Page_Locations extends Page foreach ($starts as $key => $start) { if (!isset($ends[$key]) || !is_numeric($key)) continue; $end = $ends[$key]; - list($startLong, $endLong) = $this->rangeToLong($start, $end); - if ($startLong === false) { - Message::addWarning('main.value-invalid', 'start addr', $start); - } - if ($endLong === false) { - Message::addWarning('main.value-invalid', 'end addr', $start); - } - if ($startLong === false || $endLong === false) continue; - if ($startLong > $endLong) { - Message::addWarning('main.value-invalid', 'range', $start . ' - ' . $end); + $range = $this->rangeToLongVerbose($start, $end); + if ($range === false) continue; - } + list($startLong, $endLong) = $range; if ($stmt->execute(array('id' => $key, 'start' => $startLong, 'end' => $endLong))) { $count += $stmt->rowCount(); } @@ -390,6 +417,7 @@ class Page_Locations extends Page . ' INNER JOIN sat.lecture_x_location ll ON (l.lectureid = ll.lectureid AND ll.locationid = :lid)', array('lid' => $locationId)); $data['lectures'] = $lectures['cnt']; + $data['haveDozmod'] = true; } // Get clients matching this location's subnet(s) $count = $online = $used = 0; @@ -407,6 +435,7 @@ class Page_Locations extends Page } } } + $data['haveStatistics'] = true; } $data['machines'] = $count; $data['machines_online'] = $online; @@ -432,4 +461,23 @@ class Page_Locations extends Page return array($startLong, $endLong); } + private function rangeToLongVerbose($start, $end) + { + $result = $this->rangeToLong($start, $end); + list($startLong, $endLong) = $result; + if ($startLong === false) { + Message::addWarning('main.value-invalid', 'start addr', $start); + } + if ($endLong === false) { + Message::addWarning('main.value-invalid', 'end addr', $start); + } + if ($startLong === false || $endLong === false) + return false; + if ($startLong > $endLong) { + Message::addWarning('main.value-invalid', 'range', $start . ' - ' . $end); + return false; + } + return $result; + } + } diff --git a/modules-available/locations/templates/location-subnets.html b/modules-available/locations/templates/location-subnets.html index b0353416..23035002 100644 --- a/modules-available/locations/templates/location-subnets.html +++ b/modules-available/locations/templates/location-subnets.html @@ -43,31 +43,35 @@ <th title="{{lang_deleteSubnet}}"><span class="glyphicon glyphicon-trash"></span></th> </tr> {{#list}} - <tr> + <tr class="cidrmagic"> <td>{{subnetid}}</td> - <td><input class="form-control" type="text" name="startaddr[{{subnetid}}]" value="{{startaddr}}" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"></td> - <td><input class="form-control" type="text" name="endaddr[{{subnetid}}]" value="{{endaddr}}" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"></td> + <td><input class="form-control cidrstart" type="text" name="startaddr[{{subnetid}}]" value="{{startaddr}}" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"></td> + <td><input class="form-control cidrend" type="text" name="endaddr[{{subnetid}}]" value="{{endaddr}}" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"></td> <td class="danger" align="center"><input type="checkbox" name="deletesubnet[{{subnetid}}]" value="on"></td> </tr> {{/list}} <tr id="loc-sub-{{locationid}}"> - <td colspan="2"> + <td colspan="4"> <button class="btn btn-success btn-sm" type="button" onclick="slxAddSubnetRow(this, {{locationid}})" title="{{lang_addNewSubnet}}"> <span class="glyphicon glyphicon-plus-sign"></span> {{lang_subnet}} </button> </td> - <td colspan="2" align="right"> - <button type="submit" class="btn btn-primary">{{lang_save}}</button> - </td> </tr> </table> + <br> + <div class="pull-right"> + <button type="submit" class="btn btn-primary">{{lang_save}}</button> + </div> + <div class="slx-bold">{{lang_locationInfo}}</div> + {{#haveDozmod}} + <div> + <span class="slx-ga2">{{lang_referencingLectures}}:</span> {{lectures}} + </div> + {{/haveDozmod}} + {{#haveStatistics}} + <div> + <span class="slx-ga2">{{lang_matchingMachines}}:</span> <a href="?do=Statistics&filter=location&argument={{locationid}}">{{machines}} / {{machines_online}} / {{machines_used}} ({{used_percent}}%)</a> + </div> + {{/haveStatistics}} </form> - <br> - <div class="slx-bold">{{lang_locationInfo}}</div> - <div> - <span class="slx-ga2">{{lang_referencingLectures}}:</span> {{lectures}} - </div> - <div> - <span class="slx-ga2">{{lang_matchingMachines}}:</span> <a href="?do=Statistics&filter=location&argument={{locationid}}">{{machines}} / {{machines_online}} / {{machines_used}} ({{used_percent}}%)</a> - </div> </div>
\ No newline at end of file diff --git a/modules-available/locations/templates/locations.html b/modules-available/locations/templates/locations.html index 2971105b..1fb60926 100644 --- a/modules-available/locations/templates/locations.html +++ b/modules-available/locations/templates/locations.html @@ -6,13 +6,15 @@ <table class="table table-condensed" style="margin-bottom:0px"> <tr> <th width="100%">{{lang_locationName}}</th> - <th>{{#havestatistics}}{{lang_machineCount}}{{/havestatistics}}</th> - <th class="slx-nowrap">{{lang_editConfigVariables}}</th> - {{#havesysconfig}} + <th> + {{#havestatistics}}{{lang_machineCount}}{{/havestatistics}} + </th> + <th class="slx-nowrap"> + {{#havebaseconfig}}{{lang_editConfigVariables}}{{/havebaseconfig}} + </th> <th class="slx-nowrap"> - {{#havebaseconfig}}{{lang_sysConfig}}{{/havebaseconfig}} + {{#havesysconfig}}{{lang_sysConfig}}{{/havesysconfig}} </th> - {{/havesysconfig}} </tr> {{#list}} <tr> @@ -37,13 +39,13 @@ {{/havebaseconfig}} </td> <td class="slx-nowrap"> + {{#havesysconfig}} <div class="pull-right"> <a class="btn btn-default btn-xs" href="?do=sysconfig&locationid={{locationid}}"><span class="glyphicon glyphicon-edit"></span></a> </div> <span class="{{configClass}}"> {{configName}}   </span> - {{#havesysconfig}} {{/havesysconfig}} </td> </tr> @@ -123,23 +125,26 @@ function slxOpenLocation(e, lid) { } return; } - var td = $('<td>').attr('colspan', '2').css('padding', '0px 0px 12px'); + var td = $('<td>').attr('colspan', '4').css('padding', '0px 0px 12px'); var tr = $('<tr>').attr('id', 'location-details-' + lid); tr.append(td); $(e).closest('tr').addClass('active slx-bold').after(tr); - td.load('?do=Locations&action=showlocation&locationid=' + lid); + td.load('?do=Locations&action=showlocation&locationid=' + lid, function() { + slxAttachCidr(); + }); slxLastLocation = tr; } function slxAddSubnetRow(e, lid) { var tr = $('#loc-sub-' + lid); - tr.before('<tr>\ + tr.before('<tr class="cidrmagic">\ <td>#</td>\ - <td><input class="form-control" type="text" name="newstartaddr[' + slxAddCounter + ']" pattern="\\d{1,3}\.\\d{1,3}\.\\d{1,3}\.\\d{1,3}"></td>\ - <td><input class="form-control" type="text" name="newendaddr[' + slxAddCounter + ']" pattern="\\d{1,3}\.\\d{1,3}\.\\d{1,3}\.\\d{1,3}"></td>\ + <td><input class="form-control cidrstart" type="text" name="newstartaddr[' + slxAddCounter + ']" pattern="\\d{1,3}\.\\d{1,3}\.\\d{1,3}\.\\d{1,3}"></td>\ + <td><input class="form-control cidrend" type="text" name="newendaddr[' + slxAddCounter + ']" pattern="\\d{1,3}\.\\d{1,3}\.\\d{1,3}\.\\d{1,3}"></td>\ <td></td>\ </tr>'); slxAddCounter++; + slxAttachCidr(); } function slxConfirm() { diff --git a/modules-available/locations/templates/subnets.html b/modules-available/locations/templates/subnets.html index 2294f42b..0320e333 100644 --- a/modules-available/locations/templates/subnets.html +++ b/modules-available/locations/templates/subnets.html @@ -14,10 +14,10 @@ <th>{{lang_location}}</th> </tr> {{#list}} - <tr> + <tr class="cidrmagic"> <td>{{subnetid}}</td> - <td><input class="form-control" type="text" name="startaddr[{{subnetid}}]" value="{{startaddr}}"></td> - <td><input class="form-control" type="text" name="endaddr[{{subnetid}}]" value="{{endaddr}}"></td> + <td><input class="form-control cidrstart" type="text" name="startaddr[{{subnetid}}]" value="{{startaddr}}"></td> + <td><input class="form-control cidrend" type="text" name="endaddr[{{subnetid}}]" value="{{endaddr}}"></td> <td> <select class="form-control" name="location[{{subnetid}}]"> {{#locations}} diff --git a/modules-available/main/lang/de/messages.json b/modules-available/main/lang/de/messages.json index 245d4871..fc73f891 100644 --- a/modules-available/main/lang/de/messages.json +++ b/modules-available/main/lang/de/messages.json @@ -3,6 +3,7 @@ "empty-field": "Ein Feld wurde nicht ausgef\u00fcllt", "error-read": "Fehler beim Lesen von {{0}}", "error-write": "Fehler beim Schreiben von {{0}}", + "module-missing-deps": "Modul {{0}} hat fehlende Abh\u00e4ngigkeiten", "no-permission": "Keine ausreichenden Rechte, um auf diese Seite zuzugreifen", "no-such-module": "Modul {{0}} existiert nicht oder ist nicht aktiv", "task-error": "Ausf\u00fchrung fehlgeschlagen: {{0}}", diff --git a/modules-available/main/lang/de/module.json b/modules-available/main/lang/de/module.json deleted file mode 100644 index b1f0ef93..00000000 --- a/modules-available/main/lang/de/module.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "module_name": "Dashboard", - "page_title": "Startseite" -}
\ No newline at end of file diff --git a/modules-available/main/lang/en/messages.json b/modules-available/main/lang/en/messages.json index f3e97b77..2b735eec 100644 --- a/modules-available/main/lang/en/messages.json +++ b/modules-available/main/lang/en/messages.json @@ -1,12 +1,14 @@ { - "no-permission": "No sufficient privileges to access this page", - "error-write": "Failed to write {{0}}", + "debug-mode": "The debug mode is active!", "empty-field": "A field was not filled", - "value-invalid": "The value {{1}} is invalid for option {{0}} and has been ignored", "error-read": "Error reading {{0}}", - "taskmanager-error": "Failed to connect to the Task Manager", + "error-write": "Failed to write {{0}}", + "module-missing-deps": "Module {{0}} has missing dependencies", + "no-permission": "No sufficient privileges to access this page", + "no-such-module": "Modul {{0}} existiert nicht", "task-error": "Execution failed: {{0}}", + "taskmanager-error": "Failed to connect to the Task Manager", "taskmanager-format": "Task Manager has returned invalid data", "token": "Invalid token. CSRF attack?", - "debug-mode": "The debug mode is active!" + "value-invalid": "The value {{1}} is invalid for option {{0}} and has been ignored" }
\ No newline at end of file diff --git a/modules-available/main/templates/main-menu.html b/modules-available/main/templates/main-menu.html index 8f32271d..57f0fa88 100644 --- a/modules-available/main/templates/main-menu.html +++ b/modules-available/main/templates/main-menu.html @@ -12,8 +12,8 @@ </div> </div> <div class="sidebar-bg"></div> -<nav class="navbar navbar-inverse sidebar" role="navigation"> - <div class="container-fluid"> +<nav class="navbar navbar-inverse sidebar"> + <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-sidebar-navbar-collapse-1"> @@ -73,22 +73,22 @@ </ul> <ul class="nav navbar-nav navbar-right visible-sm visible-md" style="margin-top:10px"> - {{#user}} - <ul class="btn-group"> - <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> - {{user}} - <span class="caret"></span> - </button> - <ul class="dropdown-menu"> - <!--<li><a href="#">Settings</a></li> - <li role="separator" class="divider"></li> --> - <li><a href="#" onclick="$('#logoutForm').submit();">{{lang_logout}}</a></li> - </ul> - </ul> - {{/user}} - {{^user}} - <a type="button" href="?do=Session&action=login" class="btn btn-default">{{lang_login}}</a> - {{/user}} + <li> + {{#user}} + <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> + {{user}} + <span class="caret"></span> + </button> + <ul class="dropdown-menu"> + <!--<li><a href="#">Settings</a></li> --> + <!--<li role="separator" class="divider"></li> --> + <li><a href="#" onclick="$('#logoutForm').submit();">{{lang_logout}}</a></li> + </ul> + {{/user}} + {{^user}} + <a type="button" href="?do=Session&action=login" class="btn btn-default">{{lang_login}}</a> + {{/user}} + </li> </ul> </div> </div> diff --git a/modules-available/news/api.inc.php b/modules-available/news/api.inc.php new file mode 100644 index 00000000..cbfaa82b --- /dev/null +++ b/modules-available/news/api.inc.php @@ -0,0 +1,29 @@ +<?php + +header('Content-Type: application/xml; charset=utf-8'); + +$type = Request::any('type', 'news', 'string'); + +// Fetch news from DB +$row = Database::queryFirst('SELECT title, content, dateline FROM vmchooser_pages' + . ' WHERE type = :type ORDER BY dateline DESC LIMIT 1', compact('type')); +if ($row !== false ) { + + echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n"; + echo "<news>" . "\n"; + echo "\t" . '<headline>' . "\n"; + echo "\t\t" . htmlspecialchars($row['title']) . "\n"; + echo "\t" . '</headline>' . "\n"; + echo "\t" . "<info>" . "\n"; + echo "\t\t" . htmlspecialchars(nl2br($row['content'])) . "\n"; + echo "\t" . '</info>' . "\n"; + echo "\t" . "<date>" . "\n"; + echo "\t\t" . $row['dateline'] . "\n"; + echo "\t" . "</date>" . "\n"; + echo "</news>"; + +} else { + // no news in DB, output a 'null' news xml + echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n"; + echo "<news>null</news>"; +} diff --git a/modules-available/news/install.inc.php b/modules-available/news/install.inc.php index 48e13a41..620a4580 100644 --- a/modules-available/news/install.inc.php +++ b/modules-available/news/install.inc.php @@ -5,32 +5,35 @@ $res = array(); if (tableExists('news')) { - /* rename news and add column "type" */ - tableRename('news', 'vmchooser_pages'); - Database::exec("ALTER TABLE `vmchooser_pages` ADD COLUMN type varchar(10)", []); - Database::exec("UPDATE `vmchooser_pages` set `type`='news` WHERE 1", []); - - finalResponse(UPDATE_DONE, 'Tables updated successfully'); - -} else { - $res[] = tableCreate('vmchooser_pages', " - `newsid` int(10) unsigned NOT NULL AUTO_INCREMENT, - `dateline` int(10) unsigned NOT NULL, - `title` varchar(200) DEFAULT NULL, - `content` text, - `type` varchar(10), - PRIMARY KEY (`newsid`), - KEY `dateline` (`dateline`) - "); + /* rename news and add column "type" */ + if (!tableRename('news', 'vmchooser_pages')) { + finalResponse(UPDATE_FAILED, "Could not rename news to vmchooser_pages: " . Database::lastError()); + } + $res[] = UPDATE_DONE; + if (false === Database::exec("ALTER TABLE `vmchooser_pages` ADD COLUMN type VARCHAR(10)")) { + EventLog::warning("Could not add type column to vmchooser_pages: " . Database::lastError()); + } + if (false === Database::exec("UPDATE `vmchooser_pages` SET `type` = 'news' WHERE 1")) { + EventLog::warning("News module update: Could not set default type to news: " . Database::lastError()); + } - // *crickets* +} - // Create response for browser +$res[] = tableCreate('vmchooser_pages', " + `newsid` int(10) unsigned NOT NULL AUTO_INCREMENT, + `dateline` int(10) unsigned NOT NULL, + `title` varchar(200) DEFAULT NULL, + `content` text, + `type` varchar(10), + PRIMARY KEY (`newsid`), + KEY `dateline` (`dateline`) +"); - if (in_array(UPDATE_DONE, $res)) { - finalResponse(UPDATE_DONE, 'Tables created successfully'); - } +// Create response for browser - finalResponse(UPDATE_NOOP, 'Everything already up to date'); +if (in_array(UPDATE_DONE, $res)) { + finalResponse(UPDATE_DONE, 'Tables created successfully'); } + +finalResponse(UPDATE_NOOP, 'Everything already up to date'); diff --git a/modules-available/news/style.css b/modules-available/news/style.css new file mode 100644 index 00000000..c11567ec --- /dev/null +++ b/modules-available/news/style.css @@ -0,0 +1,6 @@ +/* Make things look more like they will show up in vmchooser (Qt) */ + +.note-editor pre { + background: none; + border: none; +} diff --git a/modules-available/news/templates/page-news.html b/modules-available/news/templates/page-news.html index c698e408..7750137e 100644 --- a/modules-available/news/templates/page-news.html +++ b/modules-available/news/templates/page-news.html @@ -102,9 +102,3 @@ </div> </div> </div> -{{#hasSummernote}} -<script> -document.addEventListener("DOMContentLoaded", function () { -}); -</script> -{{/hasSummernote}} diff --git a/modules-available/statistics/page.inc.php b/modules-available/statistics/page.inc.php index 1e6f7400..de7f965b 100644 --- a/modules-available/statistics/page.inc.php +++ b/modules-available/statistics/page.inc.php @@ -452,7 +452,10 @@ class Page_Statistics extends Page $client['firstseen_s'] = date('d.m.Y H:i', $client['firstseen']); $client['lastseen_s'] = date('d.m.Y H:i', $client['lastseen']); $uptime = $NOW - $client['lastboot']; - $client['lastboot_s'] = date('d.m.Y H:i', $client['lastboot']) . ' (Up ' . floor($uptime / 86400) . 'd ' . gmdate('H:i', $uptime) . ')'; + $client['lastboot_s'] = date('d.m.Y H:i', $client['lastboot']); + if (!isset($client['state_off']) || !$client['state_off']) { + $client['lastboot_s'] .= ' (Up ' . floor($uptime / 86400) . 'd ' . gmdate('H:i', $uptime) . ')'; + } $client['logintime_s'] = date('d.m.Y H:i', $client['logintime']); $client['gbram'] = round(round($client['mbram'] / 500) / 2, 1); $client['gbtmp'] = round($client['id44mb'] / 1024); diff --git a/modules-available/statistics/templates/cpumodels.html b/modules-available/statistics/templates/cpumodels.html index 2f24cd92..d87118ef 100644 --- a/modules-available/statistics/templates/cpumodels.html +++ b/modules-available/statistics/templates/cpumodels.html @@ -33,13 +33,13 @@ animation: false, tooltipTemplate: "<%if (label){%><%=label%><%}%>", customTooltips: function(tooltip) { - if (sel !== false) sel.removeClass('info'); + if (sel !== false) sel.removeClass('slx-bold'); if (!tooltip) { sel = false; return; } sel = $('#' + tooltip.text); - sel.addClass('info'); + sel.addClass('slx-bold'); } }); }, false); diff --git a/modules-available/statistics/templates/id44.html b/modules-available/statistics/templates/id44.html index 730839b1..4eea9413 100644 --- a/modules-available/statistics/templates/id44.html +++ b/modules-available/statistics/templates/id44.html @@ -29,14 +29,14 @@ animation: false, tooltipTemplate: "<%if (label){%><%=label%><%}%>", customTooltips: function(tooltip) { - if (sel !== false) sel.removeClass('info'); + if (sel !== false) sel.removeClass('slx-bold'); if (!tooltip) { sel = false; return; } sel = $('#tmpid' + String(tooltip.text)); console.log('#tmpid' + String(tooltip.text)); - sel.addClass('info'); + sel.addClass('slx-bold'); } }); }, false); diff --git a/modules-available/statistics/templates/kvmstate.html b/modules-available/statistics/templates/kvmstate.html index 107a34f7..07ecd558 100644 --- a/modules-available/statistics/templates/kvmstate.html +++ b/modules-available/statistics/templates/kvmstate.html @@ -29,13 +29,13 @@ animation: false, tooltipTemplate: "<%if (label){%><%=label%><%}%>", customTooltips: function(tooltip) { - if (sel !== false) sel.removeClass('info'); + if (sel !== false) sel.removeClass('slx-bold'); if (!tooltip) { sel = false; return; } sel = $('#kvm' + tooltip.text); - sel.addClass('info'); + sel.addClass('slx-bold'); } }); }, false); diff --git a/modules-available/statistics/templates/memory.html b/modules-available/statistics/templates/memory.html index f4d2ad24..537ee3bd 100644 --- a/modules-available/statistics/templates/memory.html +++ b/modules-available/statistics/templates/memory.html @@ -29,13 +29,13 @@ animation: false, tooltipTemplate: "<%if (label){%><%=label%><%}%>", customTooltips: function(tooltip) { - if (sel !== false) sel.removeClass('info'); + if (sel !== false) sel.removeClass('slx-bold'); if (!tooltip) { sel = false; return; } sel = $('#ramid' + tooltip.text); - sel.addClass('info'); + sel.addClass('slx-bold'); } }); }, false); diff --git a/modules-available/summernote/clientscript.js b/modules-available/summernote/clientscript.js index 725db47d..69d7da93 100644 --- a/modules-available/summernote/clientscript.js +++ b/modules-available/summernote/clientscript.js @@ -14,13 +14,12 @@ $.getScript(filename, function () { toolbar: [ // [groupName, [list of button]] ['para', ['style']], - ['style', ['bold', 'italic', 'underline', 'strikethrough', 'clear']], - // ['fontsize', ['fontsize']], + ['style', ['bold', 'italic', 'underline', 'clear']], ['color', ['color']], - ['para', ['ul', 'ol', 'paragraph']], + ['para', ['ul', 'ol']], ['misc', ['codeview', 'fullscreen']] - //['height', ['height']] ], + styleTags: ['p', 'pre', 'h1', 'h2', 'h3'], lang: LANG, height: '300px', }); diff --git a/modules-available/translation/lang/de/messages.json b/modules-available/translation/lang/de/messages.json index dbbef6b8..e95c7750 100644 --- a/modules-available/translation/lang/de/messages.json +++ b/modules-available/translation/lang/de/messages.json @@ -1,6 +1,10 @@ { + "i18n-empty-tag": "Ein String wurde ohne Tag \u00fcbermittelt", "i18n-invalid-lang": "Ung\u00fcltige Sprache: {{0}}", + "invalid-custom-handler": "Ung\u00fcltiger \"custom handler\" {{0}}", + "invalid-section": "Ung\u00fcltige Auswahl", "invalid-template": "Ausgew\u00e4hlte Template ist nicht g\u00fcltig", - "i18n-empty-tag": "Ein String wurde ohne Tag \u00fcbermittelt", + "no-custom-handlers": "Modul hat keine \"custom handlers\"", + "no-module-given": "Kein Modul angegeben", "updated-tags": "Tags wurden aktualisiert" }
\ No newline at end of file diff --git a/modules-available/translation/lang/de/template-tags.json b/modules-available/translation/lang/de/template-tags.json index b8497bd9..3e5e9e02 100644 --- a/modules-available/translation/lang/de/template-tags.json +++ b/modules-available/translation/lang/de/template-tags.json @@ -5,6 +5,7 @@ "lang_menuCategories": "Men\u00fckategorien", "lang_messages": "Benachrichtigungen", "lang_missing": "Fehlend", + "lang_missingDeps": "Fehlende Abh\u00e4ngigkeiten", "lang_module": "Modul", "lang_otherStrings": "Andere Texte", "lang_sample": "Beispiel", diff --git a/modules-available/translation/lang/en/messages.json b/modules-available/translation/lang/en/messages.json index 84478fe9..b2389fee 100644 --- a/modules-available/translation/lang/en/messages.json +++ b/modules-available/translation/lang/en/messages.json @@ -1,6 +1,10 @@ { + "i18n-empty-tag": "A string without tag was submitted", "i18n-invalid-lang": "Invalid language: {{0}}", + "invalid-custom-handler": "Invalid custom handler {{0}}", + "invalid-section": "Invalid selection", "invalid-template": "Selected template is not valid", - "i18n-empty-tag": "A string without tag was submitted", + "no-custom-handlers": "Module has no custom handlers", + "no-module-given": "No module given", "updated-tags": "Tags have been updated" }
\ No newline at end of file diff --git a/modules-available/translation/lang/en/template-tags.json b/modules-available/translation/lang/en/template-tags.json index ec2a26a3..9f0795b1 100644 --- a/modules-available/translation/lang/en/template-tags.json +++ b/modules-available/translation/lang/en/template-tags.json @@ -5,6 +5,7 @@ "lang_menuCategories": "Menu categories", "lang_messages": "Messages", "lang_missing": "Missing", + "lang_missingDeps": "Missing dependencies", "lang_module": "Module", "lang_otherStrings": "Other strings", "lang_sample": "Sample", diff --git a/modules-available/translation/page.inc.php b/modules-available/translation/page.inc.php index 74cf27a8..563ffae0 100644 --- a/modules-available/translation/page.inc.php +++ b/modules-available/translation/page.inc.php @@ -593,20 +593,26 @@ class Page_Translation extends Page private function checkModuleTranslation($module) { - $tags = $this->loadUsedTemplateTags($module); + $templateTags = $this->loadUsedTemplateTags($module); + $messageTags = $this->loadUsedMessageTags($module); + $moduleTags = $this->loadUsedModuleTags($module); $msgs = ''; foreach (Dictionary::getLanguages() as $lang) { - list($missing, $unused) = $this->getModuleTemplateStatus($lang, $tags, $module); + list($m1, $u1) = $this->getModuleTemplateStatus($lang, $templateTags, $module); + list($m2, $u2) = $this->getModuleTranslationStatus($lang, 'messages', true, $messageTags, $module); + list($m3, $u3) = $this->getModuleTranslationStatus($lang, 'module', true, $moduleTags, $module); + $missing = $m1 + $m2 + $m3; + $unused = $u1 + $u2 + $u3; $msg = ""; if ($missing > 0) { - $msg .= " [$missing JSON tag(s) are missing] "; + $msg .= " [$missing missing] "; } if ($unused > 0) { - $msg .= " [$unused JSON tag(s) are not being used] "; + $msg .= " [$unused not being used] "; } if(!empty($msg)) { - $msgs .= "<div><div class='pull-left'><div class='badge'>$lang</div></div> $msg<div class='clearfix'></div></div>"; + $msgs .= '<div><div class="pull-left">' . Dictionary::getFlagHtml(false, $lang) . '</div>' . $msg . '<div class="clearfix"></div></div>'; } } if(empty($msgs)) { diff --git a/modules-available/translation/templates/module-list.html b/modules-available/translation/templates/module-list.html index 81dc741c..026e17e9 100644 --- a/modules-available/translation/templates/module-list.html +++ b/modules-available/translation/templates/module-list.html @@ -11,7 +11,12 @@ <tbody> {{#table}} <tr> - <td><a href="?do=Translation&module={{module}}">{{module}}</a></td> + <td> + {{#depfail}} + <div class="pull-right"><span class="red glyphicon glyphicon-exclamation-sign" title="{{lang_missingDeps}}"></span></div> + {{/depfail}} + <a href="?do=Translation&module={{module}}">{{module}}</a> + </td> <td>{{{status}}}</td> </tr> {{/table}} diff --git a/modules-available/visjs/config.json b/modules-available/visjs/config.json deleted file mode 100644 index 860b0c8b..00000000 --- a/modules-available/visjs/config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "dependencies" : ["momentjs"] -} |