}
static int
-api_bouquet_scan
- ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
+bouquet_cb
+ ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp,
+ int (*cb)(const char *uuid) )
{
htsmsg_field_t *f;
htsmsg_t *uuids;
- bouquet_t *bq;
const char *uuid;
+ int r = 0;
if (!(f = htsmsg_field_find(args, "uuid")))
return -EINVAL;
HTSMSG_FOREACH(f, uuids) {
if (!(uuid = htsmsg_field_get_str(f))) continue;
pthread_mutex_lock(&global_lock);
- bq = bouquet_find_by_uuid(uuid);
- if (bq)
- bouquet_scan(bq);
+ cb(uuid);
pthread_mutex_unlock(&global_lock);
}
} else if ((uuid = htsmsg_field_get_str(f))) {
pthread_mutex_lock(&global_lock);
- bq = bouquet_find_by_uuid(uuid);
- if (bq)
- bouquet_scan(bq);
+ r = cb(uuid);
pthread_mutex_unlock(&global_lock);
- if (!bq)
- return -ENOENT;
} else {
return -EINVAL;
}
- return 0;
+ return r;
+}
+
+static int bouquet_cb_scan(const char *uuid)
+{
+ bouquet_t *bq = bouquet_find_by_uuid(uuid);
+ if (bq) {
+ bouquet_scan(bq);
+ return 0;
+ }
+ return -ENOENT;
+}
+
+static int
+api_bouquet_scan
+ ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
+{
+ return bouquet_cb(perm, opaque, op, args, resp, bouquet_cb_scan);
+}
+
+static int bouquet_cb_detach(const char *uuid)
+{
+ channel_t *ch = channel_find_by_uuid(uuid);
+ if (ch) {
+ bouquet_detach(ch);
+ return 0;
+ }
+ return -ENOENT;
+}
+
+static int
+api_bouquet_detach
+ ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
+{
+ return bouquet_cb(perm, opaque, op, args, resp, bouquet_cb_detach);
}
void api_bouquet_init ( void )
{ "bouquet/grid", ACCESS_ADMIN, api_idnode_grid, api_bouquet_grid },
{ "bouquet/create", ACCESS_ADMIN, api_bouquet_create, NULL },
{ "bouquet/scan", ACCESS_ADMIN, api_bouquet_scan, NULL },
+ { "bouquet/detach", ACCESS_ADMIN, api_bouquet_detach, NULL },
{ NULL },
};
bq->bq_rescan = 0;
}
+/*
+ *
+ */
+void
+bouquet_detach ( channel_t *ch )
+{
+ bouquet_t *bq = ch->ch_bouquet;
+ idnode_list_mapping_t *ilm;
+ service_lcn_t *tl;
+ service_t *t;
+ int64_t n = 0;
+
+ if (!bq)
+ return;
+ LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) {
+ t = (service_t *)ilm->ilm_in1;
+ LIST_FOREACH(tl, &t->s_lcns, sl_link)
+ if (tl->sl_bouquet == bq) {
+ n = (int64_t)tl->sl_lcn;
+ goto found;
+ }
+ }
+found:
+ if (n) {
+ n += (int64_t)ch->ch_bouquet->bq_lcn_offset * CHANNEL_SPLIT;
+ ch->ch_number = n;
+ }
+ ch->ch_bouquet = NULL;
+ idnode_changed(&ch->ch_id);
+}
+
/* **************************************************************************
* Class definition
* **************************************************************************/
void bouquet_completed(bouquet_t *bq, uint32_t seen);
void bouquet_change_comment(bouquet_t *bq, const char *comment, int replace);
void bouquet_scan(bouquet_t *bq);
+void bouquet_detach(channel_t *ch);
uint64_t bouquet_get_channel_number(bouquet_t *bq, service_t *t);
function reset_icons(ctx, e, store, sm) {
Ext.each(sm.getSelections(), function(channel) {
- channel.set('icon', '');
+ channel.set('icon', '');
+ });
+ }
+
+ function bouquet_detach(ctx, e, store, sm) {
+ tvheadend.AjaxUUID(sm.getSelections(), {
+ url: 'api/bouquet/detach',
+ success: function(d) { store.reload(); }
});
}
iconCls: 'clone',
text: _('Map all services'),
});
+ m.add({
+ name: 'bqdetach',
+ tooltip: _('Detach from bouquet'),
+ iconCls: 'bouquets',
+ text: _('Detach selected channels from bouquet'),
+ });
return new Ext.Toolbar.Button({
tooltip: _('Map services to channels'),
iconCls: 'clone',
callback: {
mapall: tvheadend.service_mapper_all,
mapsel: tvheadend.service_mapper_none,
+ bqdetach: bouquet_detach
}
};
);
};
+tvheadend.AjaxUUID = function(sel, conf)
+{
+ if (sel && sel.length > 0) {
+ var uuids = [];
+ for (var i = 0; i < sel.length; i++)
+ uuids.push(sel[i].id);
+ if (!conf.params)
+ conf.params = {};
+ conf.params.uuid = uuids;
+ tvheadend.Ajax(conf);
+ }
+}
+
tvheadend.loading = function(on) {
if (on)
Ext.getBody().mask(_('Loading, please wait...'), 'loading');