Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
bouquets: improve mapping / tag creation, fixes #3608
  • Loading branch information
perexg committed Mar 7, 2016
1 parent d532539 commit 3b6a5ac
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 80 deletions.
211 changes: 138 additions & 73 deletions src/bouquet.c
Expand Up @@ -66,6 +66,7 @@ bouquet_create(const char *uuid, htsmsg_t *conf,
bq->bq_services = idnode_set_create(1);
bq->bq_active_services = idnode_set_create(1);
bq->bq_ext_url_period = 60;
bq->bq_mapencrypted = 1;

if (idnode_insert(&bq->bq_id, uuid, &bouquet_class, 0)) {
if (uuid)
Expand Down Expand Up @@ -273,6 +274,7 @@ bouquet_map_channel(bouquet_t *bq, service_t *t)
.check_availability = 0,
.encrypted = 1,
.merge_same_name = 0,
.type_tags = 0,
.provider_tags = 0,
.network_tags = 0
};
Expand All @@ -287,12 +289,19 @@ bouquet_map_channel(bouquet_t *bq, service_t *t)
return;
if (!bq->bq_mapnoname && noname(service_get_channel_name(t)))
return;
if (!bq->bq_mapencrypted && service_is_encrypted(t))
return;
LIST_FOREACH(ilm, &t->s_channels, ilm_in1_link)
if (((channel_t *)ilm->ilm_in2)->ch_bouquet == bq)
break;
if (!ilm)
if (!ilm) {
sm_conf.encrypted = bq->bq_mapencrypted;
sm_conf.merge_same_name = bq->bq_mapmergename;
sm_conf.type_tags = bq->bq_chtag_type_tags;
sm_conf.provider_tags = bq->bq_chtag_provider_tags;
sm_conf.network_tags = bq->bq_chtag_network_tags;
ch = service_mapper_process(&sm_conf, t, bq);
else
} else
ch = (channel_t *)ilm->ilm_in2;
if (ch && bq->bq_chtag)
if (channel_tag_map(bouquet_tag(bq, 1), ch, ch))
Expand Down Expand Up @@ -672,64 +681,137 @@ bouquet_class_maptoch_notify ( void *obj, const char *lang )
}

static void
bouquet_class_mapnolcn_notify ( void *obj, const char *lang )
bouquet_class_lcn_offset_notify ( void *obj, const char *lang )
{
bouquet_t *bq = obj;
service_t *t;
size_t z;

if (bq->bq_in_load)
if (((bouquet_t *)obj)->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];
if ((bq->bq_only_bq_lcn || service_get_channel_number(t) <= 0) &&
bouquet_get_channel_number0(bq, t) <= 0)
bouquet_unmap_channel(bq, t);
}
} else {
bouquet_map_to_channels(bq);
}
bouquet_notify_channels((bouquet_t *)obj);
}

static void
bouquet_class_mapnoname_notify ( void *obj, const char *lang )
static idnode_slist_t bouquest_class_mapopt_slist[] = {
{
.id = "mapnolcn",
.name = N_("Map zero-numbered channels"),
.off = offsetof(bouquet_t, bq_mapnolcn),
},
{
.id = "mapnoname",
.name = N_("Map unnamed channels"),
.off = offsetof(bouquet_t, bq_mapnoname),
},
{
.id = "mapradio",
.name = N_("Map radio channels"),
.off = offsetof(bouquet_t, bq_mapradio),
},
{
.id = "encrypted",
.name = N_("Map encrypted services"),
.off = offsetof(bouquet_t, bq_mapencrypted),
},
{
.id = "merge_name",
.name = N_("Merge same name"),
.off = offsetof(bouquet_t, bq_mapmergename),
},
{}
};

static htsmsg_t *
bouquet_class_mapopt_enum ( void *obj, const char *lang )
{
bouquet_t *bq = obj;
service_t *t;
size_t z;
return idnode_slist_enum(obj, bouquest_class_mapopt_slist, lang);
}

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];
if (noname(service_get_channel_name(t)))
bouquet_unmap_channel(bq, t);
}
} else {
bouquet_map_to_channels(bq);
}
static const void *
bouquet_class_mapopt_get ( void *obj )
{
return idnode_slist_get(obj, bouquest_class_mapopt_slist);
}

static char *
bouquet_class_mapopt_rend ( void *obj, const char *lang )
{
return idnode_slist_rend(obj, bouquest_class_mapopt_slist, lang);
}

static int
bouquet_class_mapopt_set ( void *obj, const void *p )
{
return idnode_slist_set(obj, bouquest_class_mapopt_slist, p);
}

static void
bouquet_class_mapradio_notify ( void *obj, const char *lang )
bouquet_class_mapopt_notify ( void *obj, const char *lang )
{
bouquet_t *bq = obj;
service_t *t;
size_t z;

if (bq->bq_in_load)
return;
if (!bq->bq_mapradio && bq->bq_enabled && bq->bq_maptoch) {
if (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];
if (service_is_radio(t))
if (!bq->bq_mapradio && service_is_radio(t))
bouquet_unmap_channel(bq, t);
else if (!bq->bq_mapnoname && noname(service_get_channel_name(t)))
bouquet_unmap_channel(bq, t);
else if (!bq->bq_mapradio && service_is_radio(t))
bouquet_unmap_channel(bq, t);
else if (!bq->bq_mapencrypted && service_is_encrypted(t))
bouquet_unmap_channel(bq, t);
}
} else {
bouquet_map_to_channels(bq);
}
bouquet_map_to_channels(bq);
}

static idnode_slist_t bouquest_class_chtag_slist[] = {
{
.id = "bouquet_tag",
.name = N_("Create bouquet tag"),
.off = offsetof(bouquet_t, bq_chtag),
},
{
.id = "type_tags",
.name = N_("Create type based tags"),
.off = offsetof(bouquet_t, bq_chtag_type_tags),
},
{
.id = "providers_tags",
.name = N_("Create provider name tags"),
.off = offsetof(bouquet_t, bq_chtag_provider_tags),
},
{
.id = "network_tags",
.name = N_("Create network name tags"),
.off = offsetof(bouquet_t, bq_chtag_network_tags),
},
{}
};

static htsmsg_t *
bouquet_class_chtag_enum ( void *obj, const char *lang )
{
return idnode_slist_enum(obj, bouquest_class_chtag_slist, lang);
}

static const void *
bouquet_class_chtag_get ( void *obj )
{
return idnode_slist_get(obj, bouquest_class_chtag_slist);
}

static char *
bouquet_class_chtag_rend ( void *obj, const char *lang )
{
return idnode_slist_rend(obj, bouquest_class_chtag_slist, lang);
}

static int
bouquet_class_chtag_set ( void *obj, const void *p )
{
return idnode_slist_set(obj, bouquest_class_chtag_slist, p);
}

static void
Expand All @@ -755,17 +837,8 @@ bouquet_class_chtag_notify ( void *obj, const char *lang )
if (ilm)
channel_tag_unmap((channel_t *)ilm->ilm_in2, ct);
}
} else {
bouquet_map_to_channels(bq);
}
}

static void
bouquet_class_lcn_offset_notify ( void *obj, const char *lang )
{
if (((bouquet_t *)obj)->bq_in_load)
return;
bouquet_notify_channels((bouquet_t *)obj);
bouquet_map_to_channels(bq);
}

static const void *
Expand Down Expand Up @@ -899,36 +972,28 @@ const idclass_t bouquet_class = {
.notify = bouquet_class_maptoch_notify,
},
{
.type = PT_BOOL,
.id = "mapnolcn",
.name = N_("Map zero-numbered channels"),
.off = offsetof(bouquet_t, bq_mapnolcn),
.notify = bouquet_class_mapnolcn_notify,
.opts = PO_ADVANCED,
},
{
.type = PT_BOOL,
.id = "mapnoname",
.name = N_("Map unnamed channels"),
.off = offsetof(bouquet_t, bq_mapnoname),
.notify = bouquet_class_mapnoname_notify,
.type = PT_INT,
.id = "mapopt",
.name = N_("Channel mapping options"),
.notify = bouquet_class_mapopt_notify,
.list = bouquet_class_mapopt_enum,
.get = bouquet_class_mapopt_get,
.set = bouquet_class_mapopt_set,
.rend = bouquet_class_mapopt_rend,
.opts = PO_ADVANCED,
.islist = 1
},
{
.type = PT_BOOL,
.id = "mapradio",
.name = N_("Map radio channels"),
.off = offsetof(bouquet_t, bq_mapradio),
.notify = bouquet_class_mapradio_notify,
.opts = PO_ADVANCED,
},
{
.type = PT_BOOL,
.type = PT_INT,
.id = "chtag",
.name = N_("Create tag"),
.off = offsetof(bouquet_t, bq_chtag),
.name = N_("Create tags"),
.notify = bouquet_class_chtag_notify,
.list = bouquet_class_chtag_enum,
.get = bouquet_class_chtag_get,
.set = bouquet_class_chtag_set,
.rend = bouquet_class_chtag_rend,
.opts = PO_ADVANCED,
.islist = 1
},
{
.type = PT_STR,
Expand Down
5 changes: 5 additions & 0 deletions src/bouquet.h
Expand Up @@ -40,7 +40,12 @@ typedef struct bouquet {
int bq_mapnolcn;
int bq_mapnoname;
int bq_mapradio;
int bq_mapencrypted;
int bq_mapmergename;
int bq_chtag;
int bq_chtag_type_tags;
int bq_chtag_provider_tags;
int bq_chtag_network_tags;
channel_tag_t*bq_chtag_ptr;
const char *bq_chtag_waiting;
char *bq_name;
Expand Down
81 changes: 81 additions & 0 deletions src/idnode.c
Expand Up @@ -1393,6 +1393,87 @@ idnode_serialize0(idnode_t *self, htsmsg_t *list, int optmask, const char *lang)
return m;
}

/* **************************************************************************
* Simple list helpers
* *************************************************************************/

htsmsg_t *
idnode_slist_enum ( idnode_t *in, idnode_slist_t *options, const char *lang )
{
htsmsg_t *l = htsmsg_create_list(), *m;

for (; options->id; options++) {
m = htsmsg_create_map();
htsmsg_add_str(m, "key", options->id);
htsmsg_add_str(m, "val", tvh_gettext_lang(lang, options->name));
htsmsg_add_msg(l, NULL, m);
}
return l;
}

htsmsg_t *
idnode_slist_get ( idnode_t *in, idnode_slist_t *options )
{
htsmsg_t *l = htsmsg_create_list();
int *ip;

for (; options->id; options++) {
ip = (void *)in + options->off;
if (*ip)
htsmsg_add_str(l, NULL, options->id);
}
return l;
}

int
idnode_slist_set ( idnode_t *in, idnode_slist_t *options, const htsmsg_t *vals )
{
idnode_slist_t *o;
htsmsg_field_t *f;
int *ip, changed = 0;
const char *s;

for (o = options; o->id; o++) {
ip = (void *)in + o->off;
HTSMSG_FOREACH(f, vals) {
if ((s = htsmsg_field_get_str(f)) != NULL)
continue;
if (strcmp(s, o->id))
continue;
if (*ip == 0) changed = 1;
break;
}
if (f == NULL && *ip) changed = 1;
}
HTSMSG_FOREACH(f, vals) {
if ((s = htsmsg_field_get_str(f)) != NULL)
continue;
for (o = options; o->id; o++) {
if (strcmp(o->id, s)) continue;
ip = (void *)in + o->off;
*ip = 1;
break;
}
}
return changed;
}

char *
idnode_slist_rend ( idnode_t *in, idnode_slist_t *options, const char *lang )
{
int *ip;
size_t l = 0;

prop_sbuf[0] = '\0';
for (; options->id; options++) {
ip = (void *)in + options->off;
if (*ip)
tvh_strlcatf(prop_sbuf, PROP_SBUF_LEN, l, "%s%s", prop_sbuf[0] ? "," : "",
tvh_gettext_lang(lang, options->name));
}
return prop_sbuf_ptr;
}

/* **************************************************************************
* List helpers
* *************************************************************************/
Expand Down

0 comments on commit 3b6a5ac

Please sign in to comment.