X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fluci2%2Fui.git;a=blobdiff_plain;f=luci2%2Fhtdocs%2Fluci2%2Fluci2.js;h=3e5af4a75408809b50b77d4a0e429ef7be887ac2;hp=172505949d43dd27c0302b0350944152a8575c1a;hb=e28f8f6a5a654a86dc6840f8bb1b16b888e24430;hpb=040ed60573605041313680e51b285cecff45f8cf diff --git a/luci2/htdocs/luci2/luci2.js b/luci2/htdocs/luci2/luci2.js index 1725059..3e5af4a 100644 --- a/luci2/htdocs/luci2/luci2.js +++ b/luci2/htdocs/luci2/luci2.js @@ -1,7 +1,7 @@ /* LuCI2 - OpenWrt Web Interface - Copyright 2013 Jo-Philipp Wich + Copyright 2013-2014 Jo-Philipp Wich Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -173,9 +173,16 @@ String.prototype.format = function() return out + str; } +if (!window.location.origin) + window.location.origin = '%s//%s%s'.format( + window.location.protocol, + window.location.hostname, + (window.location.port ? ':' + window.location.port : '') + ); + function LuCI2() { - var _luci2 = this; + var L = this; var Class = function() { }; @@ -214,11 +221,60 @@ function LuCI2() _class.prototype = prototype; _class.prototype.constructor = _class; - _class.extend = arguments.callee; + _class.extend = Class.extend; return _class; }; + Class.require = function(name) + { + var path = '/' + name.replace(/\./g, '/') + '.js'; + + return $.ajax(path, { + method: 'GET', + async: false, + cache: true, + dataType: 'text' + }).then(function(text) { + var code = '%s\n\n//@ sourceURL=%s/%s'.format(text, window.location.origin, path); + var construct = eval(code); + + var parts = name.split(/\./); + var cparent = L.Class || (L.Class = { }); + + for (var i = 1; i < parts.length - 1; i++) + { + cparent = cparent[parts[i]]; + + if (!cparent) + throw "Missing parent class"; + } + + cparent[parts[i]] = construct; + }); + }; + + Class.instantiate = function(name) + { + Class.require(name).then(function() { + var parts = name.split(/\./); + var iparent = L; + var construct = L.Class; + + for (var i = 1; i < parts.length - 1; i++) + { + iparent = iparent[parts[i]]; + construct = construct[parts[i]]; + + if (!iparent) + throw "Missing parent class"; + } + + if (construct[parts[i]]) + iparent[parts[i]] = new construct[parts[i]](); + }); + }; + this.defaults = function(obj, def) { for (var key in def) @@ -253,42 +309,42 @@ function LuCI2() plural: function(n) { return 0 + (n != 1) }, init: function() { - if (_luci2.i18n.loaded) + if (L.i18n.loaded) return; var lang = (navigator.userLanguage || navigator.language || 'en').toLowerCase(); var langs = (lang.indexOf('-') > -1) ? [ lang, lang.split(/-/)[0] ] : [ lang ]; for (var i = 0; i < langs.length; i++) - $.ajax('%s/i18n/base.%s.json'.format(_luci2.globals.resource, langs[i]), { + $.ajax('%s/i18n/base.%s.json'.format(L.globals.resource, langs[i]), { async: false, cache: true, dataType: 'json', success: function(data) { - $.extend(_luci2.i18n.catalog, data); + $.extend(L.i18n.catalog, data); - var pe = _luci2.i18n.catalog['']; + var pe = L.i18n.catalog['']; if (pe) { - delete _luci2.i18n.catalog['']; + delete L.i18n.catalog['']; try { var pf = new Function('n', 'return 0 + (' + pe + ')'); - _luci2.i18n.plural = pf; + L.i18n.plural = pf; } catch (e) { }; } } }); - _luci2.i18n.loaded = true; + L.i18n.loaded = true; } }; this.tr = function(msgid) { - _luci2.i18n.init(); + L.i18n.init(); - var msgstr = _luci2.i18n.catalog[msgid]; + var msgstr = L.i18n.catalog[msgid]; if (typeof(msgstr) == 'undefined') return msgid; @@ -300,23 +356,23 @@ function LuCI2() this.trp = function(msgid, msgid_plural, count) { - _luci2.i18n.init(); + L.i18n.init(); - var msgstr = _luci2.i18n.catalog[msgid]; + var msgstr = L.i18n.catalog[msgid]; if (typeof(msgstr) == 'undefined') return (count == 1) ? msgid : msgid_plural; else if (typeof(msgstr) == 'string') return msgstr; else - return msgstr[_luci2.i18n.plural(count)]; + return msgstr[L.i18n.plural(count)]; }; this.trc = function(msgctx, msgid) { - _luci2.i18n.init(); + L.i18n.init(); - var msgstr = _luci2.i18n.catalog[msgid + '\u0004' + msgctx]; + var msgstr = L.i18n.catalog[msgid + '\u0004' + msgctx]; if (typeof(msgstr) == 'undefined') return msgid; @@ -328,16 +384,16 @@ function LuCI2() this.trcp = function(msgctx, msgid, msgid_plural, count) { - _luci2.i18n.init(); + L.i18n.init(); - var msgstr = _luci2.i18n.catalog[msgid + '\u0004' + msgctx]; + var msgstr = L.i18n.catalog[msgid + '\u0004' + msgctx]; if (typeof(msgstr) == 'undefined') return (count == 1) ? msgid : msgid_plural; else if (typeof(msgstr) == 'string') return msgstr; else - return msgstr[_luci2.i18n.plural(count)]; + return msgstr[L.i18n.plural(count)]; }; this.setHash = function(key, value) @@ -364,8 +420,10 @@ function LuCI2() h += keys[i] + ':' + data[keys[i]]; } - if (h) + if (h.length) location.hash = '#' + h; + else + location.hash = ''; }; this.getHash = function(key) @@ -386,5222 +444,262 @@ function LuCI2() return data; }; - this.globals = { - timeout: 3000, - resource: '/luci2', - sid: '00000000000000000000000000000000' - }; - - this.rpc = { - - _id: 1, - _batch: undefined, - _requests: { }, - - _call: function(req, cb) - { - return $.ajax('/ubus', { - cache: false, - contentType: 'application/json', - data: JSON.stringify(req), - dataType: 'json', - type: 'POST', - timeout: _luci2.globals.timeout - }).then(cb); - }, - - _list_cb: function(msg) - { - /* verify message frame */ - if (typeof(msg) != 'object' || msg.jsonrpc != '2.0' || !msg.id) - throw 'Invalid JSON response'; - - return msg.result; - }, - - _call_cb: function(msg) + this.toArray = function(x) + { + switch (typeof(x)) { - var data = [ ]; - var type = Object.prototype.toString; + case 'number': + case 'boolean': + return [ x ]; - if (!$.isArray(msg)) - msg = [ msg ]; + case 'string': + var r = [ ]; + var l = x.split(/\s+/); + for (var i = 0; i < l.length; i++) + if (l[i].length > 0) + r.push(l[i]); + return r; - for (var i = 0; i < msg.length; i++) + case 'object': + if ($.isArray(x)) { - /* verify message frame */ - if (typeof(msg[i]) != 'object' || msg[i].jsonrpc != '2.0' || !msg[i].id) - throw 'Invalid JSON response'; - - /* fetch related request info */ - var req = _luci2.rpc._requests[msg[i].id]; - if (typeof(req) != 'object') - throw 'No related request for JSON response'; - - /* fetch response attribute and verify returned type */ - var ret = undefined; - - if ($.isArray(msg[i].result) && msg[i].result[0] == 0) - ret = (msg[i].result.length > 1) ? msg[i].result[1] : msg[i].result[0]; - - if (req.expect) - { - for (var key in req.expect) - { - if (typeof(ret) != 'undefined' && key != '') - ret = ret[key]; - - if (type.call(ret) != type.call(req.expect[key])) - ret = req.expect[key]; - - break; - } - } - - /* apply filter */ - if (typeof(req.filter) == 'function') - { - req.priv[0] = ret; - req.priv[1] = req.params; - ret = req.filter.apply(_luci2.rpc, req.priv); - } - - /* store response data */ - if (typeof(req.index) == 'number') - data[req.index] = ret; - else - data = ret; - - /* delete request object */ - delete _luci2.rpc._requests[msg[i].id]; + var r = [ ]; + for (var i = 0; i < x.length; i++) + r.push(x[i]); + return r; + } + else if ($.isPlainObject(x)) + { + var r = [ ]; + for (var k in x) + if (x.hasOwnProperty(k)) + r.push(k); + return r.sort(); } - - return data; - }, - - list: function() - { - var params = [ ]; - for (var i = 0; i < arguments.length; i++) - params[i] = arguments[i]; - - var msg = { - jsonrpc: '2.0', - id: this._id++, - method: 'list', - params: (params.length > 0) ? params : undefined - }; - - return this._call(msg, this._list_cb); - }, - - batch: function() - { - if (!$.isArray(this._batch)) - this._batch = [ ]; - }, - - flush: function() - { - if (!$.isArray(this._batch)) - return _luci2.deferrable([ ]); - - var req = this._batch; - delete this._batch; - - /* call rpc */ - return this._call(req, this._call_cb); - }, - - declare: function(options) - { - var _rpc = this; - - return function() { - /* build parameter object */ - var p_off = 0; - var params = { }; - if ($.isArray(options.params)) - for (p_off = 0; p_off < options.params.length; p_off++) - params[options.params[p_off]] = arguments[p_off]; - - /* all remaining arguments are private args */ - var priv = [ undefined, undefined ]; - for (; p_off < arguments.length; p_off++) - priv.push(arguments[p_off]); - - /* store request info */ - var req = _rpc._requests[_rpc._id] = { - expect: options.expect, - filter: options.filter, - params: params, - priv: priv - }; - - /* build message object */ - var msg = { - jsonrpc: '2.0', - id: _rpc._id++, - method: 'call', - params: [ - _luci2.globals.sid, - options.object, - options.method, - params - ] - }; - - /* when a batch is in progress then store index in request data - * and push message object onto the stack */ - if ($.isArray(_rpc._batch)) - { - req.index = _rpc._batch.push(msg) - 1; - return _luci2.deferrable(msg); - } - - /* call rpc */ - return _rpc._call(msg, _rpc._call_cb); - }; } - }; - this.uci = { - - writable: function() - { - return _luci2.session.access('ubus', 'uci', 'commit'); - }, - - add: _luci2.rpc.declare({ - object: 'uci', - method: 'add', - params: [ 'config', 'type', 'name', 'values' ], - expect: { section: '' } - }), + return [ ]; + }; - apply: function() + this.toObject = function(x) + { + switch (typeof(x)) { + case 'number': + case 'boolean': + return { x: true }; - }, - - configs: _luci2.rpc.declare({ - object: 'uci', - method: 'configs', - expect: { configs: [ ] } - }), + case 'string': + var r = { }; + var l = x.split(/\x+/); + for (var i = 0; i < l.length; i++) + if (l[i].length > 0) + r[l[i]] = true; + return r; - _changes: _luci2.rpc.declare({ - object: 'uci', - method: 'changes', - params: [ 'config' ], - expect: { changes: [ ] } - }), - - changes: function(config) - { - if (typeof(config) == 'string') - return this._changes(config); - - var configlist; - return this.configs().then(function(configs) { - _luci2.rpc.batch(); - configlist = configs; - - for (var i = 0; i < configs.length; i++) - _luci2.uci._changes(configs[i]); - - return _luci2.rpc.flush(); - }).then(function(changes) { - var rv = { }; - - for (var i = 0; i < configlist.length; i++) - if (changes[i].length) - rv[configlist[i]] = changes[i]; - - return rv; - }); - }, - - commit: _luci2.rpc.declare({ - object: 'uci', - method: 'commit', - params: [ 'config' ] - }), - - _delete_one: _luci2.rpc.declare({ - object: 'uci', - method: 'delete', - params: [ 'config', 'section', 'option' ] - }), - - _delete_multiple: _luci2.rpc.declare({ - object: 'uci', - method: 'delete', - params: [ 'config', 'section', 'options' ] - }), - - 'delete': function(config, section, option) - { - if ($.isArray(option)) - return this._delete_multiple(config, section, option); - else - return this._delete_one(config, section, option); - }, - - delete_all: _luci2.rpc.declare({ - object: 'uci', - method: 'delete', - params: [ 'config', 'type', 'match' ] - }), - - _foreach: _luci2.rpc.declare({ - object: 'uci', - method: 'get', - params: [ 'config', 'type' ], - expect: { values: { } } - }), - - foreach: function(config, type, cb) - { - return this._foreach(config, type).then(function(sections) { - for (var s in sections) - cb(sections[s]); - }); - }, - - get: _luci2.rpc.declare({ - object: 'uci', - method: 'get', - params: [ 'config', 'section', 'option' ], - expect: { '': { } }, - filter: function(data, params) { - if (typeof(params.option) == 'undefined') - return data.values ? data.values['.type'] : undefined; - else - return data.value; + case 'object': + if ($.isArray(x)) + { + var r = { }; + for (var i = 0; i < x.length; i++) + r[x[i]] = true; + return r; } - }), - - get_all: _luci2.rpc.declare({ - object: 'uci', - method: 'get', - params: [ 'config', 'section' ], - expect: { values: { } }, - filter: function(data, params) { - if (typeof(params.section) == 'string') - data['.section'] = params.section; - else if (typeof(params.config) == 'string') - data['.package'] = params.config; - return data; + else if ($.isPlainObject(x)) + { + return x; } - }), - - get_first: function(config, type, option) - { - return this._foreach(config, type).then(function(sections) { - for (var s in sections) - { - var val = (typeof(option) == 'string') ? sections[s][option] : sections[s]['.name']; - - if (typeof(val) != 'undefined') - return val; - } + } - return undefined; - }); - }, - - section: _luci2.rpc.declare({ - object: 'uci', - method: 'add', - params: [ 'config', 'type', 'name', 'values' ], - expect: { section: '' } - }), - - _set: _luci2.rpc.declare({ - object: 'uci', - method: 'set', - params: [ 'config', 'section', 'values' ] - }), - - set: function(config, section, option, value) - { - if (typeof(value) == 'undefined' && typeof(option) == 'string') - return this.section(config, section, option); /* option -> type */ - else if ($.isPlainObject(option)) - return this._set(config, section, option); /* option -> values */ - - var values = { }; - values[option] = value; - - return this._set(config, section, values); - }, - - order: _luci2.rpc.declare({ - object: 'uci', - method: 'order', - params: [ 'config', 'sections' ] - }) + return { }; }; - this.network = { - listNetworkNames: function() { - return _luci2.rpc.list('network.interface.*').then(function(list) { - var names = [ ]; - for (var name in list) - if (name != 'network.interface.loopback') - names.push(name.substring(18)); - names.sort(); - return names; - }); - }, - - listDeviceNames: _luci2.rpc.declare({ - object: 'network.device', - method: 'status', - expect: { '': { } }, - filter: function(data) { - var names = [ ]; - for (var name in data) - if (name != 'lo') - names.push(name); - names.sort(); - return names; - } - }), - - getNetworkStatus: function() - { - var nets = [ ]; - var devs = { }; - - return this.listNetworkNames().then(function(names) { - _luci2.rpc.batch(); - - for (var i = 0; i < names.length; i++) - _luci2.network.getInterfaceStatus(names[i]); - - return _luci2.rpc.flush(); - }).then(function(networks) { - for (var i = 0; i < networks.length; i++) - { - var net = nets[i] = networks[i]; - var dev = net.l3_device || net.l2_device; - if (dev) - net.device = devs[dev] || (devs[dev] = { }); - } - - _luci2.rpc.batch(); - - for (var dev in devs) - _luci2.network.getDeviceStatus(dev); - - return _luci2.rpc.flush(); - }).then(function(devices) { - _luci2.rpc.batch(); - - for (var i = 0; i < devices.length; i++) - { - var brm = devices[i]['bridge-members']; - delete devices[i]['bridge-members']; - - $.extend(devs[devices[i]['device']], devices[i]); - - if (!brm) - continue; - - devs[devices[i]['device']].subdevices = [ ]; - - for (var j = 0; j < brm.length; j++) - { - if (!devs[brm[j]]) - { - devs[brm[j]] = { }; - _luci2.network.getDeviceStatus(brm[j]); - } - - devs[devices[i]['device']].subdevices[j] = devs[brm[j]]; - } - } - - return _luci2.rpc.flush(); - }).then(function(subdevices) { - for (var i = 0; i < subdevices.length; i++) - $.extend(devs[subdevices[i]['device']], subdevices[i]); - - _luci2.rpc.batch(); - - for (var dev in devs) - _luci2.wireless.getDeviceStatus(dev); - - return _luci2.rpc.flush(); - }).then(function(wifidevices) { - for (var i = 0; i < wifidevices.length; i++) - if (wifidevices[i]) - devs[wifidevices[i]['device']].wireless = wifidevices[i]; - - nets.sort(function(a, b) { - if (a['interface'] < b['interface']) - return -1; - else if (a['interface'] > b['interface']) - return 1; - else - return 0; - }); - - return nets; - }); - }, - - findWanInterfaces: function(cb) - { - return this.listNetworkNames().then(function(names) { - _luci2.rpc.batch(); - - for (var i = 0; i < names.length; i++) - _luci2.network.getInterfaceStatus(names[i]); + this.filterArray = function(array, item) + { + if (!$.isArray(array)) + return [ ]; - return _luci2.rpc.flush(); - }).then(function(interfaces) { - var rv = [ undefined, undefined ]; + for (var i = 0; i < array.length; i++) + if (array[i] === item) + array.splice(i--, 1); - for (var i = 0; i < interfaces.length; i++) - { - if (!interfaces[i].route) - continue; + return array; + }; - for (var j = 0; j < interfaces[i].route.length; j++) - { - var rt = interfaces[i].route[j]; + this.toClassName = function(str, suffix) + { + var n = ''; + var l = str.split(/[\/.]/); - if (typeof(rt.table) != 'undefined') - continue; + for (var i = 0; i < l.length; i++) + if (l[i].length > 0) + n += l[i].charAt(0).toUpperCase() + l[i].substr(1).toLowerCase(); - if (rt.target == '0.0.0.0' && rt.mask == 0) - rv[0] = interfaces[i]; - else if (rt.target == '::' && rt.mask == 0) - rv[1] = interfaces[i]; - } - } + if (typeof(suffix) == 'string') + n += suffix; - return rv; - }); - }, - - getDHCPLeases: _luci2.rpc.declare({ - object: 'luci2.network', - method: 'dhcp_leases', - expect: { leases: [ ] } - }), - - getDHCPv6Leases: _luci2.rpc.declare({ - object: 'luci2.network', - method: 'dhcp6_leases', - expect: { leases: [ ] } - }), - - getRoutes: _luci2.rpc.declare({ - object: 'luci2.network', - method: 'routes', - expect: { routes: [ ] } - }), - - getIPv6Routes: _luci2.rpc.declare({ - object: 'luci2.network', - method: 'routes', - expect: { routes: [ ] } - }), - - getARPTable: _luci2.rpc.declare({ - object: 'luci2.network', - method: 'arp_table', - expect: { entries: [ ] } - }), - - getInterfaceStatus: _luci2.rpc.declare({ - object: 'network.interface', - method: 'status', - params: [ 'interface' ], - expect: { '': { } }, - filter: function(data, params) { - data['interface'] = params['interface']; - data['l2_device'] = data['device']; - delete data['device']; - return data; - } - }), - - getDeviceStatus: _luci2.rpc.declare({ - object: 'network.device', - method: 'status', - params: [ 'name' ], - expect: { '': { } }, - filter: function(data, params) { - data['device'] = params['name']; - return data; - } - }), - - getConntrackCount: _luci2.rpc.declare({ - object: 'luci2.network', - method: 'conntrack_count', - expect: { '': { count: 0, limit: 0 } } - }), - - listSwitchNames: _luci2.rpc.declare({ - object: 'luci2.network', - method: 'switch_list', - expect: { switches: [ ] } - }), - - getSwitchInfo: _luci2.rpc.declare({ - object: 'luci2.network', - method: 'switch_info', - params: [ 'switch' ], - expect: { info: { } }, - filter: function(data, params) { - data['attrs'] = data['switch']; - data['vlan_attrs'] = data['vlan']; - data['port_attrs'] = data['port']; - data['switch'] = params['switch']; - - delete data.vlan; - delete data.port; - - return data; - } - }), - - getSwitchStatus: _luci2.rpc.declare({ - object: 'luci2.network', - method: 'switch_status', - params: [ 'switch' ], - expect: { ports: [ ] } - }) + return n; }; - this.wireless = { - listDeviceNames: _luci2.rpc.declare({ - object: 'iwinfo', - method: 'devices', - expect: { 'devices': [ ] }, - filter: function(data) { - data.sort(); - return data; - } - }), - - getDeviceStatus: _luci2.rpc.declare({ - object: 'iwinfo', - method: 'info', - params: [ 'device' ], - expect: { '': { } }, - filter: function(data, params) { - if (!$.isEmptyObject(data)) - { - data['device'] = params['device']; - return data; - } - return undefined; - } - }), - - getAssocList: _luci2.rpc.declare({ - object: 'iwinfo', - method: 'assoclist', - params: [ 'device' ], - expect: { results: [ ] }, - filter: function(data, params) { - for (var i = 0; i < data.length; i++) - data[i]['device'] = params['device']; - - data.sort(function(a, b) { - if (a.bssid < b.bssid) - return -1; - else if (a.bssid > b.bssid) - return 1; - else - return 0; - }); - - return data; - } - }), - - getWirelessStatus: function() { - return this.listDeviceNames().then(function(names) { - _luci2.rpc.batch(); + this.toColor = function(str) + { + if (typeof(str) != 'string' || str.length == 0) + return '#CCCCCC'; - for (var i = 0; i < names.length; i++) - _luci2.wireless.getDeviceStatus(names[i]); + if (str == 'wan') + return '#F09090'; + else if (str == 'lan') + return '#90F090'; - return _luci2.rpc.flush(); - }).then(function(networks) { - var rv = { }; + var i = 0, hash = 0; - var phy_attrs = [ - 'country', 'channel', 'frequency', 'frequency_offset', - 'txpower', 'txpower_offset', 'hwmodes', 'hardware', 'phy' - ]; + while (i < str.length) + hash = str.charCodeAt(i++) + ((hash << 5) - hash); - var net_attrs = [ - 'ssid', 'bssid', 'mode', 'quality', 'quality_max', - 'signal', 'noise', 'bitrate', 'encryption' - ]; + var r = (hash & 0xFF) % 128; + var g = ((hash >> 8) & 0xFF) % 128; - for (var i = 0; i < networks.length; i++) - { - var phy = rv[networks[i].phy] || ( - rv[networks[i].phy] = { networks: [ ] } - ); + var min = 0; + var max = 128; - var net = { - device: networks[i].device - }; + if ((r + g) < 128) + min = 128 - r - g; + else + max = 255 - r - g; - for (var j = 0; j < phy_attrs.length; j++) - phy[phy_attrs[j]] = networks[i][phy_attrs[j]]; + var b = min + (((hash >> 16) & 0xFF) % (max - min)); - for (var j = 0; j < net_attrs.length; j++) - net[net_attrs[j]] = networks[i][net_attrs[j]]; + return '#%02X%02X%02X'.format(0xFF - r, 0xFF - g, 0xFF - b); + }; - phy.networks.push(net); - } + this.parseIPv4 = function(str) + { + if ((typeof(str) != 'string' && !(str instanceof String)) || + !str.match(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/)) + return undefined; - return rv; - }); - }, + var num = [ ]; + var parts = str.split(/\./); - getAssocLists: function() + for (var i = 0; i < parts.length; i++) { - return this.listDeviceNames().then(function(names) { - _luci2.rpc.batch(); + var n = parseInt(parts[i], 10); + if (isNaN(n) || n > 255) + return undefined; - for (var i = 0; i < names.length; i++) - _luci2.wireless.getAssocList(names[i]); + num.push(n); + } - return _luci2.rpc.flush(); - }).then(function(assoclists) { - var rv = [ ]; + return num; + }; - for (var i = 0; i < assoclists.length; i++) - for (var j = 0; j < assoclists[i].length; j++) - rv.push(assoclists[i][j]); + this.parseIPv6 = function(str) + { + if ((typeof(str) != 'string' && !(str instanceof String)) || + !str.match(/^[a-fA-F0-9:]+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})?$/)) + return undefined; - return rv; - }); - }, + var parts = str.split(/::/); + if (parts.length == 0 || parts.length > 2) + return undefined; - formatEncryption: function(enc) + var lnum = [ ]; + if (parts[0].length > 0) { - var format_list = function(l, s) + var left = parts[0].split(/:/); + for (var i = 0; i < left.length; i++) { - var rv = [ ]; - for (var i = 0; i < l.length; i++) - rv.push(l[i].toUpperCase()); - return rv.join(s ? s : ', '); - } - - if (!enc || !enc.enabled) - return _luci2.tr('None'); + var n = parseInt(left[i], 16); + if (isNaN(n)) + return undefined; - if (enc.wep) - { - if (enc.wep.length == 2) - return _luci2.tr('WEP Open/Shared') + ' (%s)'.format(format_list(enc.ciphers, ', ')); - else if (enc.wep[0] == 'shared') - return _luci2.tr('WEP Shared Auth') + ' (%s)'.format(format_list(enc.ciphers, ', ')); - else - return _luci2.tr('WEP Open System') + ' (%s)'.format(format_list(enc.ciphers, ', ')); - } - else if (enc.wpa) - { - if (enc.wpa.length == 2) - return _luci2.tr('mixed WPA/WPA2') + ' %s (%s)'.format( - format_list(enc.authentication, '/'), - format_list(enc.ciphers, ', ') - ); - else if (enc.wpa[0] == 2) - return 'WPA2 %s (%s)'.format( - format_list(enc.authentication, '/'), - format_list(enc.ciphers, ', ') - ); - else - return 'WPA %s (%s)'.format( - format_list(enc.authentication, '/'), - format_list(enc.ciphers, ', ') - ); + lnum.push((n / 256) >> 0); + lnum.push(n % 256); } - - return _luci2.tr('Unknown'); } - }; - - this.system = { - getSystemInfo: _luci2.rpc.declare({ - object: 'system', - method: 'info', - expect: { '': { } } - }), - - getBoardInfo: _luci2.rpc.declare({ - object: 'system', - method: 'board', - expect: { '': { } } - }), - - getDiskInfo: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'diskfree', - expect: { '': { } } - }), - - getInfo: function(cb) - { - _luci2.rpc.batch(); - - this.getSystemInfo(); - this.getBoardInfo(); - this.getDiskInfo(); - - return _luci2.rpc.flush().then(function(info) { - var rv = { }; - - $.extend(rv, info[0]); - $.extend(rv, info[1]); - $.extend(rv, info[2]); - - return rv; - }); - }, - - getProcessList: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'process_list', - expect: { processes: [ ] }, - filter: function(data) { - data.sort(function(a, b) { return a.pid - b.pid }); - return data; - } - }), - - getSystemLog: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'syslog', - expect: { log: '' } - }), - - getKernelLog: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'dmesg', - expect: { log: '' } - }), - getZoneInfo: function(cb) + var rnum = [ ]; + if (parts.length > 1 && parts[1].length > 0) { - return $.getJSON(_luci2.globals.resource + '/zoneinfo.json', cb); - }, - - sendSignal: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'process_signal', - params: [ 'pid', 'signal' ], - filter: function(data) { - return (data == 0); - } - }), - - initList: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'init_list', - expect: { initscripts: [ ] }, - filter: function(data) { - data.sort(function(a, b) { return (a.start || 0) - (b.start || 0) }); - return data; - } - }), - - initEnabled: function(init, cb) - { - return this.initList().then(function(list) { - for (var i = 0; i < list.length; i++) - if (list[i].name == init) - return !!list[i].enabled; - - return false; - }); - }, - - initRun: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'init_action', - params: [ 'name', 'action' ], - filter: function(data) { - return (data == 0); - } - }), - - initStart: function(init, cb) { return _luci2.system.initRun(init, 'start', cb) }, - initStop: function(init, cb) { return _luci2.system.initRun(init, 'stop', cb) }, - initRestart: function(init, cb) { return _luci2.system.initRun(init, 'restart', cb) }, - initReload: function(init, cb) { return _luci2.system.initRun(init, 'reload', cb) }, - initEnable: function(init, cb) { return _luci2.system.initRun(init, 'enable', cb) }, - initDisable: function(init, cb) { return _luci2.system.initRun(init, 'disable', cb) }, - - - getRcLocal: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'rclocal_get', - expect: { data: '' } - }), - - setRcLocal: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'rclocal_set', - params: [ 'data' ] - }), - - - getCrontab: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'crontab_get', - expect: { data: '' } - }), - - setCrontab: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'crontab_set', - params: [ 'data' ] - }), - - - getSSHKeys: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'sshkeys_get', - expect: { keys: [ ] } - }), - - setSSHKeys: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'sshkeys_set', - params: [ 'keys' ] - }), - - - setPassword: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'password_set', - params: [ 'user', 'password' ] - }), - - - listLEDs: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'led_list', - expect: { leds: [ ] } - }), - - listUSBDevices: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'usb_list', - expect: { devices: [ ] } - }), - - - testUpgrade: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'upgrade_test', - expect: { '': { } } - }), - - startUpgrade: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'upgrade_start', - params: [ 'keep' ] - }), - - cleanUpgrade: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'upgrade_clean' - }), - - - restoreBackup: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'backup_restore' - }), - - cleanBackup: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'backup_clean' - }), - - - getBackupConfig: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'backup_config_get', - expect: { config: '' } - }), - - setBackupConfig: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'backup_config_set', - params: [ 'data' ] - }), - - - listBackup: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'backup_list', - expect: { files: [ ] } - }), - - - testReset: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'reset_test', - expect: { supported: false } - }), - - startReset: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'reset_start' - }), - - - performReboot: _luci2.rpc.declare({ - object: 'luci2.system', - method: 'reboot' - }) - }; - - this.opkg = { - updateLists: _luci2.rpc.declare({ - object: 'luci2.opkg', - method: 'update', - expect: { '': { } } - }), - - _allPackages: _luci2.rpc.declare({ - object: 'luci2.opkg', - method: 'list', - params: [ 'offset', 'limit', 'pattern' ], - expect: { '': { } } - }), - - _installedPackages: _luci2.rpc.declare({ - object: 'luci2.opkg', - method: 'list_installed', - params: [ 'offset', 'limit', 'pattern' ], - expect: { '': { } } - }), - - _findPackages: _luci2.rpc.declare({ - object: 'luci2.opkg', - method: 'find', - params: [ 'offset', 'limit', 'pattern' ], - expect: { '': { } } - }), - - _fetchPackages: function(action, offset, limit, pattern) - { - var packages = [ ]; - - return action(offset, limit, pattern).then(function(list) { - if (!list.total || !list.packages) - return { length: 0, total: 0 }; - - packages.push.apply(packages, list.packages); - packages.total = list.total; - - if (limit <= 0) - limit = list.total; + var right = parts[1].split(/:/); - if (packages.length >= limit) - return packages; - - _luci2.rpc.batch(); - - for (var i = offset + packages.length; i < limit; i += 100) - action(i, (Math.min(i + 100, limit) % 100) || 100, pattern); - - return _luci2.rpc.flush(); - }).then(function(lists) { - for (var i = 0; i < lists.length; i++) + for (var i = 0; i < right.length; i++) + { + if (right[i].indexOf('.') > 0) { - if (!lists[i].total || !lists[i].packages) - continue; + var addr = L.parseIPv4(right[i]); + if (!addr) + return undefined; - packages.push.apply(packages, lists[i].packages); - packages.total = lists[i].total; + rnum.push.apply(rnum, addr); + continue; } - return packages; - }); - }, - - listPackages: function(offset, limit, pattern) - { - return _luci2.opkg._fetchPackages(_luci2.opkg._allPackages, offset, limit, pattern); - }, - - installedPackages: function(offset, limit, pattern) - { - return _luci2.opkg._fetchPackages(_luci2.opkg._installedPackages, offset, limit, pattern); - }, - - findPackages: function(offset, limit, pattern) - { - return _luci2.opkg._fetchPackages(_luci2.opkg._findPackages, offset, limit, pattern); - }, - - installPackage: _luci2.rpc.declare({ - object: 'luci2.opkg', - method: 'install', - params: [ 'package' ], - expect: { '': { } } - }), - - removePackage: _luci2.rpc.declare({ - object: 'luci2.opkg', - method: 'remove', - params: [ 'package' ], - expect: { '': { } } - }), - - getConfig: _luci2.rpc.declare({ - object: 'luci2.opkg', - method: 'config_get', - expect: { config: '' } - }), - - setConfig: _luci2.rpc.declare({ - object: 'luci2.opkg', - method: 'config_set', - params: [ 'data' ] - }) - }; - - this.session = { - - login: _luci2.rpc.declare({ - object: 'session', - method: 'login', - params: [ 'username', 'password' ], - expect: { '': { } } - }), - - access: _luci2.rpc.declare({ - object: 'session', - method: 'access', - params: [ 'scope', 'object', 'function' ], - expect: { access: false } - }), - - isAlive: function() - { - return _luci2.session.access('ubus', 'session', 'access'); - }, - - startHeartbeat: function() - { - this._hearbeatInterval = window.setInterval(function() { - _luci2.session.isAlive().then(function(alive) { - if (!alive) - { - _luci2.session.stopHeartbeat(); - _luci2.ui.login(true); - } - - }); - }, _luci2.globals.timeout * 2); - }, + var n = parseInt(right[i], 16); + if (isNaN(n)) + return undefined; - stopHeartbeat: function() - { - if (typeof(this._hearbeatInterval) != 'undefined') - { - window.clearInterval(this._hearbeatInterval); - delete this._hearbeatInterval; + rnum.push((n / 256) >> 0); + rnum.push(n % 256); } } - }; - - this.ui = { - - saveScrollTop: function() - { - this._scroll_top = $(document).scrollTop(); - }, - - restoreScrollTop: function() - { - if (typeof(this._scroll_top) == 'undefined') - return; - - $(document).scrollTop(this._scroll_top); - - delete this._scroll_top; - }, - - loading: function(enable) - { - var win = $(window); - var body = $('body'); - - var state = _luci2.ui._loading || (_luci2.ui._loading = { - modal: $('
') - .addClass('cbi-modal-loader') - .append($('
').text(_luci2.tr('Loading data...'))) - .appendTo(body) - }); - if (enable) - { - body.css('overflow', 'hidden'); - body.css('padding', 0); - body.css('width', win.width()); - body.css('height', win.height()); - state.modal.css('width', win.width()); - state.modal.css('height', win.height()); - state.modal.show(); - } - else - { - state.modal.hide(); - body.css('overflow', ''); - body.css('padding', ''); - body.css('width', ''); - body.css('height', ''); - } - }, + if (rnum.length > 0 && (lnum.length + rnum.length) > 15) + return undefined; - dialog: function(title, content, options) - { - var win = $(window); - var body = $('body'); - - var state = _luci2.ui._dialog || (_luci2.ui._dialog = { - dialog: $('
') - .addClass('cbi-modal-dialog') - .append($('
') - .append($('
') - .addClass('cbi-modal-dialog-header')) - .append($('
') - .addClass('cbi-modal-dialog-body')) - .append($('
') - .addClass('cbi-modal-dialog-footer') - .append($('