udpxy.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. 'use strict';
  2. 'require form';
  3. 'require view';
  4. 'require network';
  5. 'require ui';
  6. 'require tools.widgets as widgets';
  7. var CBIBindSelect = form.ListValue.extend({
  8. __name__: 'CBI.CBIBindSelect',
  9. load: function(section_id) {
  10. return Promise.all([
  11. network.getDevices(),
  12. this.noaliases ? null : network.getNetworks()
  13. ]).then(L.bind(function(data) {
  14. this.devices = data[0];
  15. this.networks = data[1];
  16. return this.super('load', section_id);
  17. }, this));
  18. },
  19. filter: function(section_id, value) {
  20. return true;
  21. },
  22. renderWidget: function(section_id, option_index, cfgvalue) {
  23. var values = L.toArray((cfgvalue != null) ? cfgvalue : this.default),
  24. choices = {},
  25. checked = {},
  26. order = [];
  27. for (var i = 0; i < values.length; i++)
  28. checked[values[i]] = true;
  29. values = [];
  30. if (!this.multiple && (this.rmempty || this.optional))
  31. choices[''] = E('em', _('unspecified'));
  32. for (var i = 0; i < this.devices.length; i++) {
  33. var device = this.devices[i],
  34. name = device.getName(),
  35. type = device.getType();
  36. if (name == 'lo' || name == this.exclude || !this.filter(section_id, name))
  37. continue;
  38. if (this.noaliases && type == 'alias')
  39. continue;
  40. if (this.nobridges && type == 'bridge')
  41. continue;
  42. if (this.noinactive && device.isUp() == false)
  43. continue;
  44. var item = E([
  45. E('img', {
  46. 'title': device.getI18n(),
  47. 'src': L.resource('icons/%s%s.png'.format(type, device.isUp() ? '' : '_disabled'))
  48. }),
  49. E('span', { 'class': 'hide-open' }, [ name ]),
  50. E('span', { 'class': 'hide-close'}, [ device.getI18n() ])
  51. ]);
  52. var networks = device.getNetworks();
  53. if (networks.length > 0)
  54. L.dom.append(item.lastChild, [ ' (', networks.map(function(n) { return n.getName() }).join(', '), ')' ]);
  55. if (checked[name])
  56. values.push(name);
  57. choices[name] = item;
  58. order.push(name);
  59. }
  60. if (this.networks != null) {
  61. for (var i = 0; i < this.networks.length; i++) {
  62. var net = this.networks[i],
  63. device = network.instantiateDevice('@%s'.format(net.getName()), net),
  64. name = device.getName();
  65. if (name == '@loopback' || name == this.exclude || !this.filter(section_id, name))
  66. continue;
  67. if (this.noinactive && net.isUp() == false)
  68. continue;
  69. var item = E([
  70. E('img', {
  71. 'title': device.getI18n(),
  72. 'src': L.resource('icons/alias%s.png'.format(net.isUp() ? '' : '_disabled'))
  73. }),
  74. E('span', { 'class': 'hide-open' }, [ name ]),
  75. E('span', { 'class': 'hide-close'}, [ device.getI18n() ])
  76. ]);
  77. if (checked[name])
  78. values.push(name);
  79. choices[name] = item;
  80. order.push(name);
  81. }
  82. }
  83. if (!this.nocreate) {
  84. var keys = Object.keys(checked).sort(L.naturalCompare);
  85. for (var i = 0; i < keys.length; i++) {
  86. if (choices.hasOwnProperty(keys[i]))
  87. continue;
  88. choices[keys[i]] = E([
  89. E('img', {
  90. 'title': _('Absent Interface'),
  91. 'src': L.resource('icons/ethernet_disabled.png')
  92. }),
  93. E('span', { 'class': 'hide-open' }, [ keys[i] ]),
  94. E('span', { 'class': 'hide-close'}, [ '%s: "%h"'.format(_('Absent Interface'), keys[i]) ])
  95. ]);
  96. values.push(keys[i]);
  97. order.push(keys[i]);
  98. }
  99. }
  100. var widget = new ui.Dropdown(this.multiple ? values : values[0], choices, {
  101. id: this.cbid(section_id),
  102. sort: order,
  103. multiple: this.multiple,
  104. optional: this.optional || this.rmempty,
  105. disabled: (this.readonly != null) ? this.readonly : this.map.readonly,
  106. select_placeholder: E('em', _('unspecified')),
  107. custom_placeholder: this.placeholder || _('custom'),
  108. display_items: this.display_size || this.size || 3,
  109. dropdown_items: this.dropdown_size || this.size || 5,
  110. validate: L.bind(this.validate, this, section_id),
  111. create: !this.nocreate,
  112. create_markup: '' +
  113. '<li data-value="{{value}}">' +
  114. '<span class="hide-open">{{value}}</span>' +
  115. '<span class="hide-close">'+_('Custom Value')+': "{{value}}"</span>' +
  116. '</li>'
  117. });
  118. return widget.render();
  119. },
  120. });
  121. return view.extend({
  122. render: function () {
  123. var m, s, o;
  124. m = new form.Map('udpxy', _('udpxy'),
  125. _('udpxy is an IPTV stream relay, a UDP-to-HTTP multicast traffic relay daemon which forwards multicast UDP streams to HTTP clients.'));
  126. s = m.section(form.TypedSection, 'udpxy');
  127. s.anonymous = true;
  128. s.addremove = true;
  129. o = s.option(form.Flag, 'disabled', _('Enabled'));
  130. o.enabled = '0';
  131. o.disabled = '1';
  132. o.default = o.disabled;
  133. o.rmempty = false;
  134. o = s.option(form.Flag, 'respawn', _('Respawn'));
  135. o.default = o.disabled;
  136. o = s.option(form.Flag, 'verbose', _('Verbose logging'));
  137. o.default = o.disabled;
  138. o = s.option(form.Flag, 'status', _('Client statistics'));
  139. o = s.option(CBIBindSelect, 'bind', _('HTTP Listen interface'));
  140. o.datatype = 'or(ip4addr, device)';
  141. o.placeholder = '0.0.0.0 || br-lan';
  142. o = s.option(form.Value, 'port', _('Port'), _('Default') + ' : ' + '%s'.format('4022'));
  143. o.datatype = 'port';
  144. o.placeholder = '4022';
  145. o = s.option(widgets.NetworkSelect, 'source_network',
  146. _('Multicast subscribe Source Network'),
  147. _('When the network is reloaded, the udpxy is reloaded'),
  148. );
  149. o.datatype = 'network';
  150. o = s.option(CBIBindSelect, 'source',
  151. _('Multicast subscribe source interface'),
  152. _('Default') + ' : ' + '%s'.format('0.0.0.0'),
  153. );
  154. o.datatype = 'or(ip4addr, device)';
  155. o.placeholder = '0.0.0.0 || lan1';
  156. o = s.option(form.Value, 'max_clients', _('Client amount upper limit'));
  157. o.datatype = 'range(1, 5000)';
  158. o = s.option(form.Value, 'log_file', _('Log file'), _('Default') + ' : <code>/var/log/udpxy</code>');
  159. o.placeholder = '/var/log/udpxy';
  160. o = s.option(form.Value, 'buffer_size', _('Ingress buffer size'), _('Unit: bytes, Kb, Mb; Max 2097152 bytes'));
  161. o.placeholder = '4Kb';
  162. o = s.option(form.Value, 'buffer_messages', _('Buffer message amount'), _('-1 is all.'));
  163. o.datatype = 'or(-1, and(min(1),uinteger))';
  164. o.placeholder = '1';
  165. o = s.option(form.Value, 'buffer_time', _('Buffer time limit'), _('-1 is unlimited.'));
  166. o.datatype = 'or(-1, and(min(1),uinteger))';
  167. o.placeholder = '1';
  168. o = s.option(form.Value, 'nice_increment', _('Nice increment'));
  169. o.datatype = 'or(and(max(-1),uinteger), and(min(1),uinteger))';
  170. o.placeholder = '0';
  171. o = s.option(form.Value, 'mcsub_renew', _('Renew multicast subscription periodicity'), _('Unit: seconds; 0 is skip.'));
  172. o.datatype = 'or(0, range(30, 64000))';
  173. o.placeholder = '0';
  174. return m.render();
  175. }
  176. });