webui: can now create new muxes from the UI

This needs testing and I'm sure some data validation would be useful!
This commit is contained in:
Adam Sutton 2013-06-10 14:53:27 +01:00
parent 6dc3b71ce7
commit a52df09d74
3 changed files with 142 additions and 115 deletions

View file

@ -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);

View file

@ -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'
})
});

View file

@ -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
});
}