Add support for copying a selection of muxes from one DVB adapter to another in the web UI.

This commit is contained in:
Andreas Öman 2009-09-01 21:16:16 +00:00
parent 55059017fa
commit 8e24c5960e
7 changed files with 226 additions and 60 deletions

View file

@ -262,6 +262,8 @@ const char *dvb_mux_add_by_params(th_dvb_adapter_t *tda,
int polarisation,
const char *satconf);
int dvb_mux_copy(th_dvb_adapter_t *dst, th_dvb_mux_instance_t *tdmi_src);
/**
* DVB Transport (aka DVB service)
*/

View file

@ -359,69 +359,19 @@ void
dvb_adapter_clone(th_dvb_adapter_t *dst, th_dvb_adapter_t *src)
{
th_dvb_mux_instance_t *tdmi_src, *tdmi_dst;
th_transport_t *t_src, *t_dst;
th_stream_t *st_src, *st_dst;
lock_assert(&global_lock);
while((tdmi_dst = LIST_FIRST(&dst->tda_muxes)) != NULL)
dvb_mux_destroy(tdmi_dst);
LIST_FOREACH(tdmi_src, &src->tda_muxes, tdmi_adapter_link) {
LIST_FOREACH(tdmi_src, &src->tda_muxes, tdmi_adapter_link)
dvb_mux_copy(dst, tdmi_src);
tdmi_dst = dvb_mux_create(dst,
&tdmi_src->tdmi_conf,
tdmi_src->tdmi_transport_stream_id,
tdmi_src->tdmi_network,
"copy operation", tdmi_src->tdmi_enabled,
NULL);
assert(tdmi_dst != NULL);
LIST_FOREACH(t_src, &tdmi_src->tdmi_transports, tht_group_link) {
t_dst = dvb_transport_find(tdmi_dst,
t_src->tht_dvb_service_id,
t_src->tht_pmt_pid, NULL);
t_dst->tht_pcr_pid = t_src->tht_pcr_pid;
t_dst->tht_enabled = t_src->tht_enabled;
t_dst->tht_servicetype = t_src->tht_servicetype;
t_dst->tht_scrambled = t_src->tht_scrambled;
if(t_src->tht_provider != NULL)
t_dst->tht_provider = strdup(t_src->tht_provider);
if(t_src->tht_svcname != NULL)
t_dst->tht_svcname = strdup(t_src->tht_svcname);
if(t_src->tht_ch != NULL)
transport_map_channel(t_dst, t_src->tht_ch, 0);
pthread_mutex_lock(&t_src->tht_stream_mutex);
LIST_FOREACH(st_src, &t_src->tht_components, st_link) {
st_dst = transport_stream_create(t_dst,
st_src->st_pid,
st_src->st_type);
st_dst->st_tb = (AVRational){1, 90000};
memcpy(st_dst->st_lang, st_src->st_lang, 4);
st_dst->st_frame_duration = st_src->st_frame_duration;
st_dst->st_caid = st_src->st_caid;
}
pthread_mutex_unlock(&t_src->tht_stream_mutex);
t_dst->tht_config_save(t_dst); // Save config
}
dvb_mux_save(tdmi_dst);
}
tda_save(dst);
}
/**
*
*/

View file

@ -875,3 +875,69 @@ dvb_mux_add_by_params(th_dvb_adapter_t *tda,
return NULL;
}
/**
*
*/
int
dvb_mux_copy(th_dvb_adapter_t *dst, th_dvb_mux_instance_t *tdmi_src)
{
th_dvb_mux_instance_t *tdmi_dst;
th_transport_t *t_src, *t_dst;
th_stream_t *st_src, *st_dst;
tdmi_dst = dvb_mux_create(dst,
&tdmi_src->tdmi_conf,
tdmi_src->tdmi_transport_stream_id,
tdmi_src->tdmi_network,
"copy operation", tdmi_src->tdmi_enabled,
NULL);
if(tdmi_dst == NULL)
return -1; // Already exist
LIST_FOREACH(t_src, &tdmi_src->tdmi_transports, tht_group_link) {
t_dst = dvb_transport_find(tdmi_dst,
t_src->tht_dvb_service_id,
t_src->tht_pmt_pid, NULL);
t_dst->tht_pcr_pid = t_src->tht_pcr_pid;
t_dst->tht_enabled = t_src->tht_enabled;
t_dst->tht_servicetype = t_src->tht_servicetype;
t_dst->tht_scrambled = t_src->tht_scrambled;
if(t_src->tht_provider != NULL)
t_dst->tht_provider = strdup(t_src->tht_provider);
if(t_src->tht_svcname != NULL)
t_dst->tht_svcname = strdup(t_src->tht_svcname);
if(t_src->tht_ch != NULL)
transport_map_channel(t_dst, t_src->tht_ch, 0);
pthread_mutex_lock(&t_src->tht_stream_mutex);
pthread_mutex_lock(&t_dst->tht_stream_mutex);
LIST_FOREACH(st_src, &t_src->tht_components, st_link) {
st_dst = transport_stream_create(t_dst,
st_src->st_pid,
st_src->st_type);
st_dst->st_tb = (AVRational){1, 90000};
memcpy(st_dst->st_lang, st_src->st_lang, 4);
st_dst->st_frame_duration = st_src->st_frame_duration;
st_dst->st_caid = st_src->st_caid;
}
pthread_mutex_unlock(&t_dst->tht_stream_mutex);
pthread_mutex_unlock(&t_src->tht_stream_mutex);
t_dst->tht_config_save(t_dst); // Save config
}
dvb_mux_save(tdmi_dst);
return 0;
}

View file

@ -946,9 +946,10 @@ static int
extjs_dvbadapter(http_connection_t *hc, const char *remain, void *opaque)
{
htsbuf_queue_t *hq = &hc->hc_reply;
th_dvb_adapter_t *tda;
th_dvb_adapter_t *tda, *ref;
htsmsg_t *out, *array, *r;
const char *op = http_arg_get(&hc->hc_req_args, "op");
const char *sibling = http_arg_get(&hc->hc_req_args, "sibling");
const char *s, *sc;
th_dvb_mux_instance_t *tdmi;
th_transport_t *t;
@ -958,11 +959,14 @@ extjs_dvbadapter(http_connection_t *hc, const char *remain, void *opaque)
if(remain == NULL) {
/* Just list all adapters */
ref = sibling != NULL ? dvb_adapter_find_by_identifier(sibling) : NULL;
array = htsmsg_create_list();
TAILQ_FOREACH(tda, &dvb_adapters, tda_global_link)
htsmsg_add_msg(array, NULL, dvb_adapter_build_msg(tda));
TAILQ_FOREACH(tda, &dvb_adapters, tda_global_link) {
if(ref == NULL || (ref != tda && ref->tda_type == tda->tda_type))
htsmsg_add_msg(array, NULL, dvb_adapter_build_msg(tda));
}
pthread_mutex_unlock(&global_lock);
out = htsmsg_create_map();
htsmsg_add_msg(out, "entries", array);
@ -1504,6 +1508,62 @@ extjs_dvb_addmux(http_connection_t *hc, const char *remain, void *opaque)
}
/**
*
*/
static int
extjs_dvb_copymux(http_connection_t *hc, const char *remain, void *opaque)
{
htsmsg_t *out;
htsbuf_queue_t *hq = &hc->hc_reply;
th_dvb_adapter_t *tda;
htsmsg_t *in;
const char *entries = http_arg_get(&hc->hc_req_args, "entries");
const char *id;
htsmsg_field_t *f;
th_dvb_mux_instance_t *tdmi;
in = entries != NULL ? htsmsg_json_deserialize(entries) : NULL;
if(in == NULL)
return 400;
pthread_mutex_lock(&global_lock);
if(remain == NULL ||
(tda = dvb_adapter_find_by_identifier(remain)) == NULL) {
pthread_mutex_unlock(&global_lock);
return 404;
}
TAILQ_FOREACH(f, &in->hm_fields, hmf_link) {
if((id = htsmsg_field_get_string(f)) != NULL &&
(tdmi = dvb_mux_find_by_identifier(id)) != NULL &&
tda != tdmi->tdmi_adapter) {
if(dvb_mux_copy(tda, tdmi)) {
char buf[100];
dvb_mux_nicename(buf, sizeof(buf), tdmi);
tvhlog(LOG_NOTICE, "DVB",
"Skipped copy of mux %s to adapter %s, mux already exist",
buf, tda->tda_displayname);
}
}
}
pthread_mutex_unlock(&global_lock);
out = htsmsg_create_map();
htsmsg_json_serialize(out, hq, 0);
http_output_content(hc, "text/x-json; charset=UTF-8");
htsmsg_destroy(out);
return 0;
}
/**
*
*/
@ -1737,6 +1797,9 @@ extjs_start(void)
http_path_add("/dvb/addmux",
NULL, extjs_dvb_addmux, ACCESS_ADMIN);
http_path_add("/dvb/copymux",
NULL, extjs_dvb_copymux, ACCESS_ADMIN);
http_path_add("/iptv/services",
NULL, extjs_iptvservices, ACCESS_ADMIN);

View file

@ -194,6 +194,78 @@ tvheadend.dvb_muxes = function(adapterData, satConfStore) {
})
}
}
function copySelected() {
function doCopy() {
var selectedKeys = grid.selModel.selections.keys;
var target = panel.getForm().getValues('targetID').targetID;
Ext.Ajax.request({
url: "dvb/copymux/" + target,
params: {
entries:Ext.encode(selectedKeys)
},
failure:function(response,options) {
Ext.MessageBox.alert('Server Error','Unable to copy');
},
success: function() {
win.close();
}
});
}
targetStore = new Ext.data.JsonStore({
root:'entries',
id: 'identifier',
url:'dvb/adapter',
fields: ['identifier',
'name'],
baseParams: {sibling: adapterId}
});
var panel = new Ext.FormPanel({
frame:true,
border:true,
bodyStyle:'padding:5px',
labelAlign: 'right',
labelWidth: 110,
defaultType: 'textfield',
items: [
new Ext.form.ComboBox({
store: targetStore,
fieldLabel: 'Target adapter',
name: 'targetadapter',
hiddenName: 'targetID',
editable: false,
allowBlank: false,
triggerAction: 'all',
mode: 'remote',
displayField:'name',
valueField:'identifier',
emptyText: 'Select target adapter...'
})
],
buttons: [{
text: 'Copy',
handler: doCopy
}]
});
win = new Ext.Window({
title: 'Copy multiplex configuration',
layout: 'fit',
width: 500,
height: 120,
modal: true,
plain: true,
items: panel
});
win.show();
}
function saveChanges() {
var mr = store.getModifiedRecords();
@ -226,13 +298,22 @@ tvheadend.dvb_muxes = function(adapterData, satConfStore) {
var delBtn = new Ext.Toolbar.Button({
tooltip: 'Delete one or more selected muxes',
iconCls:'remove',
text: 'Delete selected',
text: 'Delete selected...',
handler: delSelected,
disabled: true
});
var copyBtn = new Ext.Toolbar.Button({
tooltip: 'Copy selected multiplexes to other adapter',
iconCls:'clone',
text: 'Copy to other adapter...',
handler: copySelected,
disabled: true
});
selModel.on('selectionchange', function(s) {
delBtn.setDisabled(s.getCount() == 0);
copyBtn.setDisabled(s.getCount() == 0);
});
var saveBtn = new Ext.Toolbar.Button({
@ -263,8 +344,8 @@ tvheadend.dvb_muxes = function(adapterData, satConfStore) {
viewConfig: {forceFit:true},
selModel: selModel,
tbar: [
delBtn, '-', saveBtn, rejectBtn, '-', {
text: 'Add mux(es) manually',
delBtn, copyBtn, '-', saveBtn, rejectBtn, '-', {
text: 'Add mux(es) manually...',
iconCls:'add',
handler: function() {
tvheadend.addMuxManually(adapterData, satConfStore)

View file

@ -189,6 +189,10 @@
background-image:url(../icons/world.png) !important;
}
.clone {
background-image:url(../icons/layers.png) !important;
}
.x-smallhdr {

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B