diff --git a/source/ipmitool-plugin/usr/local/emhttp/plugins/ipmitool-plugin/css/ipmitool-plugin.css b/source/ipmitool-plugin/usr/local/emhttp/plugins/ipmitool-plugin/css/ipmitool-plugin.css new file mode 100644 index 00000000..6e083af5 --- /dev/null +++ b/source/ipmitool-plugin/usr/local/emhttp/plugins/ipmitool-plugin/css/ipmitool-plugin.css @@ -0,0 +1,4 @@ +/* header */ +.tablesorter { + margin-top:-21px; +} diff --git a/source/ipmitool-plugin/usr/local/emhttp/plugins/ipmitool-plugin/js/jquery.ipmitool-plugin.js b/source/ipmitool-plugin/usr/local/emhttp/plugins/ipmitool-plugin/js/jquery.ipmitool-plugin.js new file mode 100644 index 00000000..c3a6f5f6 --- /dev/null +++ b/source/ipmitool-plugin/usr/local/emhttp/plugins/ipmitool-plugin/js/jquery.ipmitool-plugin.js @@ -0,0 +1,200 @@ +$(function(){ + sensorArray(false); + eventArray(); + + //advanced view switch + $('.advancedview').switchButton({ + labels_placement: "left", + on_label: 'Advanced View', + off_label: 'Basic View', + checked: $.cookie('ipmitool_sensor_mode') == 'advanced' + }); + + //set cookie and toggle advanced columns + $('.advancedview').change(function () { + $('.advanced').toggle('slow'); + $.cookie('ipmitool_sensor_mode', $('.advancedview').prop('checked') ? 'advanced' : 'basic', { expires: 3650 }); + }); + + sensorRefresh(); +}); + +//sensor refresh +(function sensorRefresh() { + sensorArray(true); + setTimeout(sensorRefresh, 30000); +}()); + +//load ipmi sensor table +function sensorArray(Refresh){ + var Display = 'none'; + + if ($.cookie('ipmitool_sensor_mode') == 'advanced') { + $('.advanced').show(); + Display = 'table-cell'; + } + $.ajax({ + type: "POST", + dataType: "json", + url: "/plugins/ipmitool-plugin/include/ipmitool_array.php", + data : {options: "-vc sdr" + Options + atob(Password)}, + success: function(data) { + $.each(data, function (i, val) { + if (data[i][3] != "ns") { + var Reading = data[i][1]; + var LowerNonRec = data[i][13]; + var LowerCritical = data[i][14]; + var LowerNonCrit = data[i][15]; + var UpperNonCrit = data[i][12]; + var UpperCritical = data[i][11]; + var UpperNonRec = data[i][10]; + var Color = "green"; + var Name = data[i][0].replace('+', 'plus_').replace('-', 'minus_').replace(' ', '_').replace('.', '_'); + + if (data[i][6]=="Voltage"){ + if (parseFloat(Reading) > parseFloat(LowerNonRec) && parseFloat(Reading) < parseFloat(UpperNonRec)) + Color = "red"; + if (parseFloat(Reading) > parseFloat(LowerCritical) && parseFloat(Reading) < parseFloat(UpperCritical)) + Color = "yellow"; + if (parseFloat(Reading) > parseFloat(LowerNonCrit) && parseFloat(Reading) < parseFloat(UpperNonCrit)) + Color = "green"; + } else if (data[i][6]=="Fan"){ + if (parseInt(Reading) < parseInt(LowerNonCrit)) + Color = "red"; + } else if (data[i][6]=="Temperature"){ + if (parseInt(Reading) > parseInt(UpperNonCrit)) + Color = "red"; + } + + if (Refresh) { + $("#" + Name + " td.reading").html("" + Reading + ""); + } else { + $("#tblSensor tbody") + .append(""+ + ""+ //status + ""+data[i][0]+""+ //sensor name + "" + LowerNonRec + ""+ + "" + LowerCritical + ""+ + "" + LowerNonCrit + ""+ + "" + "" + Reading + "" + ""+ //sensor reading + ""+data[i][2]+""+ //sensor units + "" + UpperNonCrit + ""+ + "" + UpperCritical + ""+ + "" + UpperNonRec + ""+ + ""); + } + } + }); + $("#tblSensor").trigger("update"); //update sensor table + $('#tblSensor').tablesorter(); + }, + error : function() {}, + cache: false + }); +}; + +//load ipmi event table +function eventArray(){ + $("#tblEvent tbody").empty(); + + $.ajax({ + type: "POST", + dataType: "json", + url: "/plugins/ipmitool-plugin/include/ipmitool_array.php", + data : {options: "-c sel elist" + Options + atob(Password)}, + success: function(data) { + $.each(data, function (i, val) { + var Status = (data[i][5] == 'Asserted') ? 'red' : 'green'; + $("#tblEvent tbody") + .append(""+ + ""+ //status + "" + data[i][0] + ""+ //event id + "" + data[i][1] + " "+data[i][2]+""+ //time stamp + "" + data[i][3] + ""+ //sensor name + "" + data[i][4] +""+ //subject + ""+ //delete icon + ""); + + $('.delete').unbind('click').click(function () { + Delete($(this).parent().parent().attr("id")); + }); + + }); + + $("#tblEvent").trigger("update"); //update table for tablesorter + + $('#tblEvent').tablesorter({ + sortList: [[0,1]], + widgets: ['saveSort', 'filter', 'stickyHeaders'], + widgetOptions: { + stickyHeaders_filteredToTop: true, + filter_hideEmpty : true, + filter_liveSearch : true, + filter_saveFilters : true, + filter_reset : 'a.reset', + filter_functions: { + '.filter-time' : true, + '.filter-name' : true + } + } + }) + .tablesorterPager({ + container: $(".pager"), + fixedHeight: false, + size: 10 + }); + }, + complete: function () { + + }, + error : function() {} + }); +}; + +function Delete(Row) { + var Confirm = (Row == "all") ? confirm("Are your sure you want to remove all speedtests!?"): true; +/* if (Confirm){ + var EventId = $(this).val(); //get event id + var par = $(this).parent().parent(); //get table row + $.ajax({ + type : "POST", + url : "/plugins/ipmitool-plugin/include/delete_event.php", + data : {options: "delete " + EventId + Options + atob(Password)}, + success: function(data) { + par.remove(); //remove table row + }, + error : function() { } + }); + } +*/}; + +function clearEvents() { + //if all events checked clear all + if($('#allEvents').prop('checked')) { + $('#allEvents').switchButton({checked: false}); + $.ajax({ + type : "POST", + url : "/plugins/ipmitool-plugin/include/delete_event.php", + data : {options: "clear" + Options + atob(Password)}, + success: function(data) { + $("#tblEvent tbody").empty(); + }, + error : function() { } + }); + } else { + // clear only checked events + $(':checkbox:checked').each(function(){ + var EventId = $(this).val(); //get event id + var par = $(this).parent().parent(); //get table row + $.ajax({ + type : "POST", + url : "/plugins/ipmitool-plugin/include/delete_event.php", + data : {options: "delete " + EventId + Options + atob(Password)}, + success: function(data) { + par.remove(); //remove table row + }, + error : function() { } + }); + }); + } +}; diff --git a/source/ipmitool-plugin/usr/local/emhttp/plugins/ipmitool-plugin/js/jquery.mask.js b/source/ipmitool-plugin/usr/local/emhttp/plugins/ipmitool-plugin/js/jquery.mask.js new file mode 100644 index 00000000..bc9de52c --- /dev/null +++ b/source/ipmitool-plugin/usr/local/emhttp/plugins/ipmitool-plugin/js/jquery.mask.js @@ -0,0 +1,482 @@ +/** + * jquery.mask.js + * @version: v1.11.3 + * @author: Igor Escobar + * + * Created by Igor Escobar on 2012-03-10. Please report any bug at http://blog.igorescobar.com + * + * Copyright (c) 2012 Igor Escobar http://blog.igorescobar.com + * + * The MIT License (http://www.opensource.org/licenses/mit-license.php) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +/*jshint laxbreak: true */ +/* global define */ + +// UMD (Universal Module Definition) patterns for JavaScript modules that work everywhere. +// https://github.com/umdjs/umd/blob/master/jqueryPluginCommonjs.js +(function (factory) { + if (typeof define === "function" && define.amd) { + // AMD. Register as an anonymous module. + define(["jquery"], factory); + } else if (typeof exports === 'object') { + // Node/CommonJS + factory(require('jquery')); + } else { + // Browser globals + factory(window.jQuery || window.Zepto); + } +}(function ($) { + "use strict"; + var Mask = function (el, mask, options) { + el = $(el); + + var jMask = this, old_value = el.val(), regexMask; + + mask = typeof mask === "function" ? mask(el.val(), undefined, el, options) : mask; + + var p = { + invalid: [], + getCaret: function () { + try { + var sel, + pos = 0, + ctrl = el.get(0), + dSel = document.selection, + cSelStart = ctrl.selectionStart; + + // IE Support + if (dSel && navigator.appVersion.indexOf("MSIE 10") === -1) { + sel = dSel.createRange(); + sel.moveStart('character', el.is("input") ? -el.val().length : -el.text().length); + pos = sel.text.length; + } + // Firefox support + else if (cSelStart || cSelStart === '0') { + pos = cSelStart; + } + + return pos; + } catch (e) {} + }, + setCaret: function(pos) { + try { + if (el.is(":focus")) { + var range, ctrl = el.get(0); + + if (ctrl.setSelectionRange) { + ctrl.setSelectionRange(pos,pos); + } else if (ctrl.createTextRange) { + range = ctrl.createTextRange(); + range.collapse(true); + range.moveEnd('character', pos); + range.moveStart('character', pos); + range.select(); + } + } + } catch (e) {} + }, + events: function() { + el + .on('keyup.mask', p.behaviour) + .on("paste.mask drop.mask", function() { + setTimeout(function() { + el.keydown().keyup(); + }, 100); + }) + .on('change.mask', function(){ + el.data('changed', true); + }) + .on("blur.mask", function(){ + if (old_value !== el.val() && !el.data('changed')) { + el.trigger("change"); + } + el.data('changed', false); + }) + // it's very important that this callback remains in this position + // otherwhise old_value it's going to work buggy + .on('keydown.mask, blur.mask', function() { + old_value = el.val(); + }) + // select all text on focus + .on('focus.mask', function (e) { + if (options.selectOnFocus === true) { + $(e.target).select(); + } + }) + // clear the value if it not complete the mask + .on("focusout.mask", function() { + if (options.clearIfNotMatch && !regexMask.test(p.val())) { + p.val(''); + } + }); + }, + getRegexMask: function() { + var maskChunks = [], translation, pattern, optional, recursive, oRecursive, r; + + for (var i = 0; i < mask.length; i++) { + translation = jMask.translation[mask.charAt(i)]; + + if (translation) { + + pattern = translation.pattern.toString().replace(/.{1}$|^.{1}/g, ""); + optional = translation.optional; + recursive = translation.recursive; + + if (recursive) { + maskChunks.push(mask.charAt(i)); + oRecursive = {digit: mask.charAt(i), pattern: pattern}; + } else { + maskChunks.push(!optional && !recursive ? pattern : (pattern + "?")); + } + + } else { + maskChunks.push(mask.charAt(i).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')); + } + } + + r = maskChunks.join(""); + + if (oRecursive) { + r = r.replace(new RegExp("(" + oRecursive.digit + "(.*" + oRecursive.digit + ")?)"), "($1)?") + .replace(new RegExp(oRecursive.digit, "g"), oRecursive.pattern); + } + + return new RegExp(r); + }, + destroyEvents: function() { + el.off(['keydown', 'keyup', 'paste', 'drop', 'blur', 'focusout', ''].join('.mask ')); + }, + val: function(v) { + var isInput = el.is('input'), + method = isInput ? 'val' : 'text', + r; + + if (arguments.length > 0) { + if (el[method]() !== v) { + el[method](v); + } + r = el; + } else { + r = el[method](); + } + + return r; + }, + getMCharsBeforeCount: function(index, onCleanVal) { + for (var count = 0, i = 0, maskL = mask.length; i < maskL && i < index; i++) { + if (!jMask.translation[mask.charAt(i)]) { + index = onCleanVal ? index + 1 : index; + count++; + } + } + return count; + }, + caretPos: function (originalCaretPos, oldLength, newLength, maskDif) { + var translation = jMask.translation[mask.charAt(Math.min(originalCaretPos - 1, mask.length - 1))]; + + return !translation ? p.caretPos(originalCaretPos + 1, oldLength, newLength, maskDif) + : Math.min(originalCaretPos + newLength - oldLength - maskDif, newLength); + }, + behaviour: function(e) { + e = e || window.event; + p.invalid = []; + var keyCode = e.keyCode || e.which; + if ($.inArray(keyCode, jMask.byPassKeys) === -1) { + + var caretPos = p.getCaret(), + currVal = p.val(), + currValL = currVal.length, + changeCaret = caretPos < currValL, + newVal = p.getMasked(), + newValL = newVal.length, + maskDif = p.getMCharsBeforeCount(newValL - 1) - p.getMCharsBeforeCount(currValL - 1); + + p.val(newVal); + + // change caret but avoid CTRL+A + if (changeCaret && !(keyCode === 65 && e.ctrlKey)) { + // Avoid adjusting caret on backspace or delete + if (!(keyCode === 8 || keyCode === 46)) { + caretPos = p.caretPos(caretPos, currValL, newValL, maskDif); + } + p.setCaret(caretPos); + } + + return p.callbacks(e); + } + }, + getMasked: function (skipMaskChars) { + var buf = [], + value = p.val(), + m = 0, maskLen = mask.length, + v = 0, valLen = value.length, + offset = 1, addMethod = "push", + resetPos = -1, + lastMaskChar, + check; + + if (options.reverse) { + addMethod = "unshift"; + offset = -1; + lastMaskChar = 0; + m = maskLen - 1; + v = valLen - 1; + check = function () { + return m > -1 && v > -1; + }; + } else { + lastMaskChar = maskLen - 1; + check = function () { + return m < maskLen && v < valLen; + }; + } + + while (check()) { + var maskDigit = mask.charAt(m), + valDigit = value.charAt(v), + translation = jMask.translation[maskDigit]; + + if (translation) { + if (valDigit.match(translation.pattern)) { + buf[addMethod](valDigit); + if (translation.recursive) { + if (resetPos === -1) { + resetPos = m; + } else if (m === lastMaskChar) { + m = resetPos - offset; + } + + if (lastMaskChar === resetPos) { + m -= offset; + } + } + m += offset; + } else if (translation.optional) { + m += offset; + v -= offset; + } else if (translation.fallback) { + buf[addMethod](translation.fallback); + m += offset; + v -= offset; + } else { + p.invalid.push({p: v, v: valDigit, e: translation.pattern}); + } + v += offset; + } else { + if (!skipMaskChars) { + buf[addMethod](maskDigit); + } + + if (valDigit === maskDigit) { + v += offset; + } + + m += offset; + } + } + + var lastMaskCharDigit = mask.charAt(lastMaskChar); + if (maskLen === valLen + 1 && !jMask.translation[lastMaskCharDigit]) { + buf.push(lastMaskCharDigit); + } + + return buf.join(""); + }, + callbacks: function (e) { + var val = p.val(), + changed = val !== old_value, + defaultArgs = [val, e, el, options], + callback = function(name, criteria, args) { + if (typeof options[name] === "function" && criteria) { + options[name].apply(this, args); + } + }; + + callback('onChange', changed === true, defaultArgs); + callback('onKeyPress', changed === true, defaultArgs); + callback('onComplete', val.length === mask.length, defaultArgs); + callback('onInvalid', p.invalid.length > 0, [val, e, el, p.invalid, options]); + } + }; + + + // public methods + jMask.mask = mask; + jMask.options = options; + jMask.remove = function() { + var caret = p.getCaret(); + p.destroyEvents(); + p.val(jMask.getCleanVal()); + p.setCaret(caret - p.getMCharsBeforeCount(caret)); + return el; + }; + + // get value without mask + jMask.getCleanVal = function() { + return p.getMasked(true); + }; + + jMask.init = function(only_mask) { + only_mask = only_mask || false; + options = options || {}; + + jMask.byPassKeys = $.jMaskGlobals.byPassKeys; + jMask.translation = $.jMaskGlobals.translation; + + jMask.translation = $.extend({}, jMask.translation, options.translation); + jMask = $.extend(true, {}, jMask, options); + + regexMask = p.getRegexMask(); + + if (only_mask === false) { + + if (options.placeholder) { + el.attr('placeholder' , options.placeholder); + } + + // autocomplete needs to be off. we can't intercept events + // the browser doesn't fire any kind of event when something is + // selected in a autocomplete list so we can't sanitize it. + el.attr('autocomplete', 'off'); + p.destroyEvents(); + p.events(); + + var caret = p.getCaret(); + p.val(p.getMasked()); + p.setCaret(caret + p.getMCharsBeforeCount(caret, true)); + + } else { + p.events(); + p.val(p.getMasked()); + } + }; + + jMask.init(!el.is("input")); + }; + + $.maskWatchers = {}; + var HTMLAttributes = function () { + var input = $(this), + options = {}, + prefix = "data-mask-", + mask = input.attr('data-mask'); + + if (input.attr(prefix + 'reverse')) { + options.reverse = true; + } + + if (input.attr(prefix + 'clearifnotmatch')) { + options.clearIfNotMatch = true; + } + + if (input.attr(prefix + 'selectonfocus') === 'true') { + options.selectOnFocus = true; + } + + if (notSameMaskObject(input, mask, options)) { + return input.data('mask', new Mask(this, mask, options)); + } + }, + notSameMaskObject = function(field, mask, options) { + options = options || {}; + var maskObject = $(field).data('mask'), + stringify = JSON.stringify, + value = $(field).val() || $(field).text(); + try { + if (typeof mask === "function") { + mask = mask(value); + } + return typeof maskObject !== "object" || stringify(maskObject.options) !== stringify(options) || maskObject.mask !== mask; + } catch (e) {} + }; + + + $.fn.mask = function(mask, options) { + options = options || {}; + var selector = this.selector, + globals = $.jMaskGlobals, + interval = $.jMaskGlobals.watchInterval, + maskFunction = function() { + if (notSameMaskObject(this, mask, options)) { + return $(this).data('mask', new Mask(this, mask, options)); + } + }; + + $(this).each(maskFunction); + + if (selector && selector !== "" && globals.watchInputs) { + clearInterval($.maskWatchers[selector]); + $.maskWatchers[selector] = setInterval(function(){ + $(document).find(selector).each(maskFunction); + }, interval); + } + return this; + }; + + $.fn.unmask = function() { + clearInterval($.maskWatchers[this.selector]); + delete $.maskWatchers[this.selector]; + return this.each(function() { + var dataMask = $(this).data('mask'); + if (dataMask) { + dataMask.remove().removeData('mask'); + } + }); + }; + + $.fn.cleanVal = function() { + return this.data('mask').getCleanVal(); + }; + + $.applyDataMask = function() { + $(document).find($.jMaskGlobals.maskElements).filter(globals.dataMaskAttr).each(HTMLAttributes); + } + + var globals = { + maskElements: 'input,td,span,div', + dataMaskAttr: '*[data-mask]', + dataMask: true, + watchInterval: 300, + watchInputs: true, + watchDataMask: false, + byPassKeys: [9, 16, 17, 18, 36, 37, 38, 39, 40, 91], + translation: { + '0': {pattern: /\d/}, + '9': {pattern: /\d/, optional: true}, + '#': {pattern: /\d/, recursive: true}, + 'A': {pattern: /[a-zA-Z0-9]/}, + 'S': {pattern: /[a-zA-Z]/} + } + }; + + $.jMaskGlobals = $.jMaskGlobals || {}; + globals = $.jMaskGlobals = $.extend(true, {}, globals, $.jMaskGlobals); + + // looking for inputs with data-mask attribute + if (globals.dataMask) { $.applyDataMask(); } + + setInterval(function(){ + if ($.jMaskGlobals.watchDataMask) { $.applyDataMask(); } + }, globals.watchInterval); +}));