From a52df09d74115cd8beb2441f0885f88b3ce0610c Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Mon, 10 Jun 2013 14:53:27 +0100 Subject: [PATCH] webui: can now create new muxes from the UI This needs testing and I'm sure some data validation would be useful! --- src/webui/extjs_dvb.c | 43 ++++++++- src/webui/static/app/idnode.js | 154 ++++++++++++++++----------------- src/webui/static/app/mpegts.js | 60 ++++++------- 3 files changed, 142 insertions(+), 115 deletions(-) diff --git a/src/webui/extjs_dvb.c b/src/webui/extjs_dvb.c index eda410dd..01b7515a 100644 --- a/src/webui/extjs_dvb.c +++ b/src/webui/extjs_dvb.c @@ -128,11 +128,12 @@ extjs_idnode_grid htsmsg_t *list = htsmsg_create_list(); if (conf->sort.key) idnode_set_sort(ins, &conf->sort); - for (i = conf->start; i < ins->is_count && conf->limit > 0; i++, conf->limit--) { + for (i = conf->start; i < ins->is_count && conf->limit != 0; i++) { htsmsg_t *e = htsmsg_create_map(); htsmsg_add_str(e, "uuid", idnode_uuid_as_str(ins->is_array[i])); idnode_save(ins->is_array[i], e); htsmsg_add_msg(list, NULL, e); + if (conf->limit > 0) conf->limit--; } pthread_mutex_unlock(&global_lock); free(ins->is_array); @@ -216,7 +217,7 @@ static int extjs_mpegts_network (http_connection_t *hc, const char *remain, void *opaque) { - mpegts_network_t *mn; + mpegts_network_t *mn = NULL; htsbuf_queue_t *hq = &hc->hc_reply; const char *op = http_arg_get(&hc->hc_req_args, "op"); htsmsg_t *out = htsmsg_create_map(); @@ -233,6 +234,44 @@ extjs_mpegts_network } else if (!strcmp(op, "class")) { htsmsg_t *c = extjs_idnode_class(&mpegts_network_class); htsmsg_add_msg(out, "entries", c); + } else if (!strcmp(op, "mux_class")) { + const idclass_t *idc; + const char *uuid = http_arg_get(&hc->hc_req_args, "uuid"); + pthread_mutex_lock(&global_lock); + mn = (uuid ? mpegts_network_find(uuid) : NULL); + if (!mn) { + pthread_mutex_unlock(&global_lock); + return HTTP_STATUS_BAD_REQUEST; + } + if (!(idc = mn->mn_mux_class(mn))) { + pthread_mutex_unlock(&global_lock); + return HTTP_STATUS_BAD_REQUEST; + } + htsmsg_t *c = extjs_idnode_class(idc); + htsmsg_add_msg(out, "entries", c); + pthread_mutex_unlock(&global_lock); + } else if (!strcmp(op, "mux_create")) { + mpegts_mux_t *mm; + htsmsg_t *conf = NULL; + const char *c; + const char *uuid = http_arg_get(&hc->hc_req_args, "uuid"); + pthread_mutex_lock(&global_lock); + mn = (uuid ? mpegts_network_find(uuid) : NULL); + if (!mn) { + pthread_mutex_unlock(&global_lock); + return HTTP_STATUS_BAD_REQUEST; + } + if ((c = http_arg_get(&hc->hc_req_args, "conf"))) + conf = htsmsg_json_deserialize(c); + if (!conf) { + pthread_mutex_unlock(&global_lock); + return HTTP_STATUS_BAD_REQUEST; + } + mm = mn->mn_mux_create2(mn, conf); + pthread_mutex_unlock(&global_lock); + if (!mm) return HTTP_STATUS_BAD_REQUEST; // TODO: error message + } else { + return HTTP_STATUS_BAD_REQUEST; } htsmsg_json_serialize(out, hq, 0); diff --git a/src/webui/static/app/idnode.js b/src/webui/static/app/idnode.js index fdf2f9b8..1b7cb5fd 100644 --- a/src/webui/static/app/idnode.js +++ b/src/webui/static/app/idnode.js @@ -10,6 +10,69 @@ json_decode = function(d) return d; } +/* + * Field editor + */ +tvheadend.idnode_editor_field = function(f, create) +{ + var d = f.rdonly || false; + if (f.wronly && !create) d = false; + + switch(f.type) { + case 'str': + if (f.enum) { + return new Ext.form.ComboBox({ + fieldLabel : f.caption, + name : f.id, + value : f.value, + disabled : d, + width : 300, + mode : 'local', + store : f.enum, + typeAhead : true, + forceSelection : true, + triggerAction : 'all', + emptyText :'Select ' + f.caption +' ...' + }); + } else { + return new Ext.form.TextField({ + fieldLabel : f.caption, + name : f.id, + value : f.value, + disabled : d, + width : 300 + }); + } + + case 'bool': + return new Ext.form.Checkbox({ + fieldLabel : f.caption, + name : f.id, + checked : f.value, + disabled : d + }); + + case 'int': + case 'u32': + case 'u16': + return new Ext.form.NumberField({ + fieldLabel : f.caption, + name : f.id, + value : f.value, + disabled : d, + width : 300 + }); + + /* + case 'separator': + return new Ext.form.LabelField({ + fieldLabel : f.caption + }); +*/ + } + return null; +} + /* * ID node editor panel */ @@ -18,62 +81,9 @@ tvheadend.idnode_editor = function(item) var fields = [] for (var idx in item.params) { - var f = item.params[idx]; - var d = f.rdonly || false; - switch(f.type) { - case 'str': - if (f.enum) { - fields.push(new Ext.form.ComboBox({ - fieldLabel: f.caption, - name: f.id, - value: f.value, - mode: 'local', - disabled: d, - store: f.enum, - typeAhead: true, - forceSelection: true, - triggerAction: 'all', - emptyText:'Select ' + f.caption +' ...' - })); - } else { - fields.push({ - fieldLabel: f.caption, - name: f.id, - value: f.value, - disabled: d - }); - } - break; - - case 'bool': - fields.push({ - xtype: 'checkbox', - fieldLabel: f.caption, - name: f.id, - checked: f.value, - disabled: d - }); - break; - - case 'int': - case 'u32': - case 'u16': - fields.push(new Ext.form.NumberField({ - fieldLabel: f.caption, - name: f.id, - value: f.value, - disabled: d, - width : 300 - })); - break; - - case 'separator': - fields.push({ - xtype: 'label', - fieldLabel: f.caption - }); - break; - } + var f = tvheadend.idnode_editor_field(item.params[idx], true); + if (f) + fields.push(f); } var panel = new Ext.FormPanel({ @@ -161,25 +171,9 @@ tvheadend.idnode_create = function(conf) /* Fields */ for (i = 0; i < d.length; i++) { - if (d[i].rdonly) continue; - if (d[i].type == 'int' || d[i].type == 'u16' || d[i].type == 'u32') { - panel.add(new Ext.form.NumberField({ - fieldLabel : d[i].caption, - name : d[i].id, - width : 300 - })); - } else if (d[i].type == 'bool') { - panel.add(new Ext.form.Checkbox({ - fieldLabel : d[i].caption, - name : d[i].id - })); - } else if (d[i].type == 'str') { - panel.add(new Ext.form.TextField({ - fieldLabel : d[i].caption, - name : d[i].id, - width : 300 - })); - } + var f = tvheadend.idnode_editor_field(d[i]); + if (f) + panel.add(f); } panel.doLayout(); } @@ -199,7 +193,7 @@ tvheadend.idnode_create = function(conf) triggerAction : 'all', store : new Ext.data.JsonStore({ root : 'entries', - url : conf.select.url, + url : conf.select.url || conf.url, baseParams : conf.select.params, fields : [ conf.select.valueField, conf.select.displayField ] }), @@ -379,7 +373,7 @@ tvheadend.idnode_grid = function(panel, conf) d = json_decode(d); p = tvheadend.idnode_editor(d[0]); w = new Ext.Window({ - title : 'Add ' + conf.title, + title : 'Add ' + conf.titleS, layout : 'fit', autoWidth : true, autoHeight : true, @@ -404,7 +398,7 @@ tvheadend.idnode_grid = function(panel, conf) /* Grid Panel */ var grid = new Ext.grid.EditorGridPanel({ stripeRows : true, - title : conf.title, + title : conf.titleP, store : store, cm : model, selModel : select, @@ -419,8 +413,8 @@ tvheadend.idnode_grid = function(panel, conf) store : store, pageSize : 50, displayInfo : true, - displayMsg : conf.title + ' {0} - {1} of {2}', - emptyMsg : 'No ' + conf.title.toLowerCase() + ' to display' + displayMsg : conf.titleP + ' {0} - {1} of {2}', + emptyMsg : 'No ' + conf.titleP.toLowerCase() + ' to display' }) }); diff --git a/src/webui/static/app/mpegts.js b/src/webui/static/app/mpegts.js index 5ac2b1ac..ef04ae7a 100644 --- a/src/webui/static/app/mpegts.js +++ b/src/webui/static/app/mpegts.js @@ -8,33 +8,10 @@ tvheadend.networks = function(panel) { - var fields = [ - { - type : 'str', - id : 'name', - caption : 'Network Name' - }, - { - type : 'u16', - id : 'nid', - caption : 'Network ID' - }, - { - type : 'bool', - id : 'initscan', - caption : 'Initial scan' - }, - { - type : 'bool', - id : 'autodiscovery', - caption : 'Auto-discovery' - } - ]; - tvheadend.idnode_grid(panel, { - title : 'Network', + titleS : 'Network', + titleP : 'Networks', url : 'api/mpegts/network', - //fields : fields, add : { url : 'api/mpegts/input', title : 'Network', @@ -59,19 +36,36 @@ tvheadend.networks = function(panel) tvheadend.muxes = function(panel) { tvheadend.idnode_grid(panel, { - url : 'api/mpegts/mux', - title : 'Muxes', - add : true, - del : true + titleS : 'Mux', + titleP : 'Muxes', + url : 'api/mpegts/mux', + add : { + title : 'Mux', + url : 'api/mpegts/network', + select : { + caption : 'Network', + params : { op: 'list', limit: -1 }, + displayField : 'networkname', + valueField : 'uuid', + clazz : { + params : { op: 'mux_class' } + } + }, + create : { + params : { op: 'mux_create' } + } + }, + del : true }); } tvheadend.services = function(panel) { tvheadend.idnode_grid(panel, { - url : 'api/mpegts/service', - title : 'Services', - add : false, - del : false + url : 'api/mpegts/service', + titleS : 'Service', + titleP : 'Services', + add : false, + del : false }); }