bouquet: use hard channel tag link to allow tag renaming
This commit is contained in:
parent
75cdc2831b
commit
8812f5c51c
3 changed files with 96 additions and 3 deletions
|
@ -98,6 +98,8 @@ bouquet_destroy(bouquet_t *bq)
|
|||
|
||||
idnode_set_free(bq->bq_active_services);
|
||||
idnode_set_free(bq->bq_services);
|
||||
assert(bq->bq_services_waiting == NULL);
|
||||
free((char *)bq->bq_chtag_waiting);
|
||||
free(bq->bq_name);
|
||||
free(bq->bq_src);
|
||||
free(bq);
|
||||
|
@ -118,6 +120,21 @@ bouquet_destroy_by_service(service_t *t)
|
|||
idnode_set_remove(bq->bq_services, &t->s_id);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
bouquet_destroy_by_channel_tag(channel_tag_t *ct)
|
||||
{
|
||||
bouquet_t *bq;
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
||||
RB_FOREACH(bq, &bouquets, bq_link)
|
||||
if (bq->bq_chtag_ptr == ct)
|
||||
bq->bq_chtag_ptr = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
@ -146,10 +163,24 @@ bouquet_find_by_source(const char *name, const char *src, int create)
|
|||
static channel_tag_t *
|
||||
bouquet_tag(bouquet_t *bq, int create)
|
||||
{
|
||||
channel_tag_t *ct;
|
||||
char buf[128];
|
||||
/* TODO: cache the channel_tag_t * pointer */
|
||||
|
||||
assert(!bq->bq_in_load);
|
||||
if (bq->bq_chtag_waiting) {
|
||||
bq->bq_chtag_ptr = channel_tag_find_by_uuid(bq->bq_chtag_waiting);
|
||||
free((char *)bq->bq_chtag_waiting);
|
||||
bq->bq_chtag_waiting = NULL;
|
||||
}
|
||||
if (bq->bq_chtag_ptr)
|
||||
return bq->bq_chtag_ptr;
|
||||
snprintf(buf, sizeof(buf), "*** %s", bq->bq_name ?: "???");
|
||||
return channel_tag_find_by_name(buf, create);
|
||||
ct = channel_tag_find_by_name(buf, create);
|
||||
if (ct) {
|
||||
bq->bq_chtag_ptr = ct;
|
||||
bouquet_save(bq, 0);
|
||||
}
|
||||
return ct;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -386,6 +417,8 @@ bouquet_class_mapnolcn_notify ( void *obj )
|
|||
service_t *t;
|
||||
size_t z;
|
||||
|
||||
if (bq->bq_in_load)
|
||||
return;
|
||||
if (!bq->bq_mapnolcn && bq->bq_enabled && bq->bq_maptoch) {
|
||||
for (z = 0; z < bq->bq_services->is_count; z++) {
|
||||
t = (service_t *)bq->bq_services->is_array[z];
|
||||
|
@ -404,6 +437,8 @@ bouquet_class_mapnoname_notify ( void *obj )
|
|||
service_t *t;
|
||||
size_t z;
|
||||
|
||||
if (bq->bq_in_load)
|
||||
return;
|
||||
if (!bq->bq_mapnoname && bq->bq_enabled && bq->bq_maptoch) {
|
||||
for (z = 0; z < bq->bq_services->is_count; z++) {
|
||||
t = (service_t *)bq->bq_services->is_array[z];
|
||||
|
@ -424,6 +459,8 @@ bouquet_class_chtag_notify ( void *obj )
|
|||
channel_tag_t *ct;
|
||||
size_t z;
|
||||
|
||||
if (bq->bq_in_load)
|
||||
return;
|
||||
if (!bq->bq_chtag && bq->bq_enabled && bq->bq_maptoch) {
|
||||
ct = bouquet_tag(bq, 0);
|
||||
if (!ct)
|
||||
|
@ -444,9 +481,46 @@ bouquet_class_chtag_notify ( void *obj )
|
|||
static void
|
||||
bouquet_class_lcn_offset_notify ( void *obj )
|
||||
{
|
||||
if (((bouquet_t *)obj)->bq_in_load)
|
||||
return;
|
||||
bouquet_notify_channels((bouquet_t *)obj);
|
||||
}
|
||||
|
||||
static const void *
|
||||
bouquet_class_chtag_ref_get ( void *obj )
|
||||
{
|
||||
static const char *buf;
|
||||
bouquet_t *bq = obj;
|
||||
|
||||
if (bq->bq_chtag_ptr)
|
||||
buf = idnode_uuid_as_str(&bq->bq_chtag_ptr->ct_id);
|
||||
else
|
||||
buf = "";
|
||||
return &buf;
|
||||
}
|
||||
|
||||
static char *
|
||||
bouquet_class_chtag_ref_rend ( void *obj )
|
||||
{
|
||||
bouquet_t *bq = obj;
|
||||
if (bq->bq_chtag_ptr)
|
||||
return strdup(bq->bq_chtag_ptr->ct_name ?: "");
|
||||
else
|
||||
return strdup("");
|
||||
}
|
||||
|
||||
static int
|
||||
bouquet_class_chtag_ref_set ( void *obj, const void *p )
|
||||
{
|
||||
bouquet_t *bq = obj;
|
||||
|
||||
free((char *)bq->bq_chtag_waiting);
|
||||
bq->bq_chtag_waiting = NULL;
|
||||
if (bq->bq_in_load)
|
||||
bq->bq_chtag_waiting = strdup((const char *)p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const void *
|
||||
bouquet_class_services_get ( void *obj )
|
||||
{
|
||||
|
@ -537,6 +611,15 @@ const idclass_t bouquet_class = {
|
|||
.off = offsetof(bouquet_t, bq_chtag),
|
||||
.notify = bouquet_class_chtag_notify,
|
||||
},
|
||||
{
|
||||
.type = PT_STR,
|
||||
.id = "chtag_ref",
|
||||
.name = "Channel Tag Reference",
|
||||
.get = bouquet_class_chtag_ref_get,
|
||||
.set = bouquet_class_chtag_ref_set,
|
||||
.rend = bouquet_class_chtag_ref_rend,
|
||||
.opts = PO_RDONLY | PO_HIDDEN,
|
||||
},
|
||||
{
|
||||
.type = PT_STR,
|
||||
.id = "name",
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "idnode.h"
|
||||
#include "htsmsg.h"
|
||||
#include "service.h"
|
||||
#include "channels.h"
|
||||
|
||||
typedef struct bouquet {
|
||||
idnode_t bq_id;
|
||||
|
@ -37,6 +38,8 @@ typedef struct bouquet {
|
|||
int bq_mapnolcn;
|
||||
int bq_mapnoname;
|
||||
int bq_chtag;
|
||||
channel_tag_t*bq_chtag_ptr;
|
||||
const char *bq_chtag_waiting;
|
||||
char *bq_name;
|
||||
char *bq_src;
|
||||
char *bq_comment;
|
||||
|
@ -63,6 +66,7 @@ bouquet_t * bouquet_create(const char *uuid, htsmsg_t *conf,
|
|||
const char *name, const char *src);
|
||||
|
||||
void bouquet_destroy_by_service(service_t *t);
|
||||
void bouquet_destroy_by_channel_tag(channel_tag_t *ct);
|
||||
|
||||
static inline bouquet_t *
|
||||
bouquet_find_by_uuid(const char *uuid)
|
||||
|
|
|
@ -926,7 +926,12 @@ channel_tag_unmap(channel_t *ch, channel_tag_t *ct)
|
|||
LIST_REMOVE(ctm, ctm_channel_link);
|
||||
LIST_REMOVE(ctm, ctm_tag_link);
|
||||
free(ctm);
|
||||
channel_tag_save(ct);
|
||||
channel_save(ch);
|
||||
idnode_notify_simple(&ch->ch_id);
|
||||
if (ct->ct_enabled && !ct->ct_internal) {
|
||||
htsp_tag_update(ct);
|
||||
htsp_channel_update(ch);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -990,6 +995,7 @@ channel_tag_destroy(channel_tag_t *ct, int delconf)
|
|||
TAILQ_REMOVE(&channel_tags, ct, ct_link);
|
||||
idnode_unlink(&ct->ct_id);
|
||||
|
||||
bouquet_destroy_by_channel_tag(ct);
|
||||
autorec_destroy_by_channel_tag(ct, delconf);
|
||||
access_destroy_by_channel_tag(ct, delconf);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue