From 03ec6a835623d4d12266889696ad0782f5574c2f Mon Sep 17 00:00:00 2001 From: Feng Cheng Date: Tue, 30 Jul 2024 18:33:07 +0800 Subject: [PATCH] luci-app-udpxy: fix luci-app-udpxy modified bind and source option class to automatically generate possible values Changed ipaddr in datatype to ip4addr, udpxy only supports ipv4 add option source_network Signed-off-by: Feng Cheng --- .../luci-static/resources/view/udpxy.js | 169 +++++++++++++++++- .../luci-app-udpxy/po/templates/udpxy.pot | 72 +++++--- 2 files changed, 211 insertions(+), 30 deletions(-) diff --git a/applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js b/applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js index 93aa9c2c88..640d77155d 100644 --- a/applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js +++ b/applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js @@ -1,6 +1,153 @@ 'use strict'; 'require form'; 'require view'; +'require network'; +'require ui'; +'require tools.widgets as widgets'; + +var CBIBindSelect = form.ListValue.extend({ + __name__: 'CBI.CBIBindSelect', + + load: function(section_id) { + return Promise.all([ + network.getDevices(), + this.noaliases ? null : network.getNetworks() + ]).then(L.bind(function(data) { + this.devices = data[0]; + this.networks = data[1]; + + return this.super('load', section_id); + }, this)); + }, + + filter: function(section_id, value) { + return true; + }, + + renderWidget: function(section_id, option_index, cfgvalue) { + var values = L.toArray((cfgvalue != null) ? cfgvalue : this.default), + choices = {}, + checked = {}, + order = []; + + for (var i = 0; i < values.length; i++) + checked[values[i]] = true; + + values = []; + + if (!this.multiple && (this.rmempty || this.optional)) + choices[''] = E('em', _('unspecified')); + + for (var i = 0; i < this.devices.length; i++) { + var device = this.devices[i], + name = device.getName(), + type = device.getType(); + + if (name == 'lo' || name == this.exclude || !this.filter(section_id, name)) + continue; + + if (this.noaliases && type == 'alias') + continue; + + if (this.nobridges && type == 'bridge') + continue; + + if (this.noinactive && device.isUp() == false) + continue; + + var item = E([ + E('img', { + 'title': device.getI18n(), + 'src': L.resource('icons/%s%s.png'.format(type, device.isUp() ? '' : '_disabled')) + }), + E('span', { 'class': 'hide-open' }, [ name ]), + E('span', { 'class': 'hide-close'}, [ device.getI18n() ]) + ]); + + var networks = device.getNetworks(); + + if (networks.length > 0) + L.dom.append(item.lastChild, [ ' (', networks.map(function(n) { return n.getName() }).join(', '), ')' ]); + + if (checked[name]) + values.push(name); + + choices[name] = item; + order.push(name); + } + + if (this.networks != null) { + for (var i = 0; i < this.networks.length; i++) { + var net = this.networks[i], + device = network.instantiateDevice('@%s'.format(net.getName()), net), + name = device.getName(); + + if (name == '@loopback' || name == this.exclude || !this.filter(section_id, name)) + continue; + + if (this.noinactive && net.isUp() == false) + continue; + + var item = E([ + E('img', { + 'title': device.getI18n(), + 'src': L.resource('icons/alias%s.png'.format(net.isUp() ? '' : '_disabled')) + }), + E('span', { 'class': 'hide-open' }, [ name ]), + E('span', { 'class': 'hide-close'}, [ device.getI18n() ]) + ]); + + if (checked[name]) + values.push(name); + + choices[name] = item; + order.push(name); + } + } + + if (!this.nocreate) { + var keys = Object.keys(checked).sort(L.naturalCompare); + + for (var i = 0; i < keys.length; i++) { + if (choices.hasOwnProperty(keys[i])) + continue; + + choices[keys[i]] = E([ + E('img', { + 'title': _('Absent Interface'), + 'src': L.resource('icons/ethernet_disabled.png') + }), + E('span', { 'class': 'hide-open' }, [ keys[i] ]), + E('span', { 'class': 'hide-close'}, [ '%s: "%h"'.format(_('Absent Interface'), keys[i]) ]) + ]); + + values.push(keys[i]); + order.push(keys[i]); + } + } + + var widget = new ui.Dropdown(this.multiple ? values : values[0], choices, { + id: this.cbid(section_id), + sort: order, + multiple: this.multiple, + optional: this.optional || this.rmempty, + disabled: (this.readonly != null) ? this.readonly : this.map.readonly, + select_placeholder: E('em', _('unspecified')), + custom_placeholder: this.placeholder || _('custom'), + display_items: this.display_size || this.size || 3, + dropdown_items: this.dropdown_size || this.size || 5, + validate: L.bind(this.validate, this, section_id), + create: !this.nocreate, + create_markup: '' + + '
  • ' + + '{{value}}' + + ''+_('Custom Value')+': "{{value}}"' + + '
  • ' + }); + + return widget.render(); + }, +}); return view.extend({ render: function () { @@ -27,18 +174,26 @@ return view.extend({ o = s.option(form.Flag, 'status', _('Client statistics')); - o = s.option(form.Value, 'bind', _('HTTP Listen interface')); - o.datatype = 'or(ipaddr, network)'; - o.placeholder = '0.0.0.0 || lan1'; + o = s.option(CBIBindSelect, 'bind', _('HTTP Listen interface')); + o.datatype = 'or(ip4addr, device)'; + o.placeholder = '0.0.0.0 || br-lan'; o = s.option(form.Value, 'port', _('Port'), _('Default') + ' : ' + '%s'.format('4022')); o.datatype = 'port'; o.placeholder = '4022'; - o = s.option(form.Value, 'source', _('Multicast subscribe source interface'), _('Default') + ' : ' + '%s'.format('0.0.0.0')); - o.datatype = 'or(ipaddr, network)'; - o.placeholder = '0.0.0.0 || br-lan'; - + o = s.option(widgets.NetworkSelect, 'source_network', + _('Multicast subscribe Source Network'), + _('When the network is reloaded, the udpxy is reloaded'), + ); + o.datatype = 'network'; + + o = s.option(CBIBindSelect, 'source', + _('Multicast subscribe source interface'), + _('Default') + ' : ' + '%s'.format('0.0.0.0'), + ); + o.datatype = 'or(ip4addr, device)'; + o.placeholder = '0.0.0.0 || lan1'; o = s.option(form.Value, 'max_clients', _('Client amount upper limit')); o.datatype = 'range(1, 5000)'; diff --git a/applications/luci-app-udpxy/po/templates/udpxy.pot b/applications/luci-app-udpxy/po/templates/udpxy.pot index 2cb108fe50..edb00fc2ed 100644 --- a/applications/luci-app-udpxy/po/templates/udpxy.pot +++ b/applications/luci-app-udpxy/po/templates/udpxy.pot @@ -1,37 +1,46 @@ msgid "" msgstr "Content-Type: text/plain; charset=UTF-8" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:52 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:207 msgid "-1 is all." msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:56 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:211 msgid "-1 is unlimited." msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:52 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:117 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:121 +msgid "Absent Interface" +msgstr "" + +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:207 msgid "Buffer message amount" msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:56 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:211 msgid "Buffer time limit" msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:43 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:198 msgid "Client amount upper limit" msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:28 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:175 msgid "Client statistics" msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:34 -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:38 -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:46 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:144 +msgid "Custom Value" +msgstr "" + +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:181 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:193 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:201 msgid "Default" msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:16 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:163 msgid "Enabled" msgstr "" @@ -39,57 +48,74 @@ msgstr "" msgid "Grant UCI access for luci-app-udpxy" msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:30 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:177 msgid "HTTP Listen interface" msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:49 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:204 msgid "Ingress buffer size" msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:46 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:201 msgid "Log file" msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:38 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:186 +msgid "Multicast subscribe Source Network" +msgstr "" + +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:192 msgid "Multicast subscribe source interface" msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:60 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:215 msgid "Nice increment" msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:34 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:181 msgid "Port" msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:64 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:219 msgid "Renew multicast subscription periodicity" msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:22 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:169 msgid "Respawn" msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:49 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:204 msgid "Unit: bytes, Kb, Mb; Max 2097152 bytes" msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:64 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:219 msgid "Unit: seconds; 0 is skip." msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:25 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:172 msgid "Verbose logging" msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:9 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:187 +msgid "When the network is reloaded, the udpxy is reloaded" +msgstr "" + +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:136 +msgid "custom" +msgstr "" + +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:156 #: applications/luci-app-udpxy/root/usr/share/luci/menu.d/luci-app-udpxy.json:3 msgid "udpxy" msgstr "" -#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:10 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:157 msgid "" "udpxy is an IPTV stream relay, a UDP-to-HTTP multicast traffic relay daemon " "which forwards multicast UDP streams to HTTP clients." msgstr "" + +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:39 +#: applications/luci-app-udpxy/htdocs/luci-static/resources/view/udpxy.js:135 +msgid "unspecified" +msgstr "" -- 2.30.2