Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
epggrab: manage multiple channel names for 'Auto EPG', fixes #3205
  • Loading branch information
perexg committed Oct 26, 2015
1 parent 784487d commit eda1d0d
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 5 deletions.
2 changes: 2 additions & 0 deletions src/epggrab.h
Expand Up @@ -88,6 +88,8 @@ typedef struct epggrab_channel
char *id; ///< Grabber's ID

char *name; ///< Channel name
htsmsg_t *names; ///< List of all channel names for grabber's ID
htsmsg_t *newnames;///< List of all channel names for grabber's ID (scan)
char *icon; ///< Channel icon
char *comment; ///< Channel comment (EPG)
int64_t lcn; ///< Channel number (split)
Expand Down
71 changes: 69 additions & 2 deletions src/epggrab/channel.c
Expand Up @@ -39,10 +39,18 @@ SKEL_DECLARE(epggrab_channel_skel, epggrab_channel_t);
/* Check if channels match */
int epggrab_channel_match ( epggrab_channel_t *ec, channel_t *ch )
{
const char *chid, *s;
htsmsg_field_t *f;

if (!ec || !ch || !ch->ch_epgauto || !ch->ch_enabled || !ec->enabled) return 0;
if (LIST_FIRST(&ec->channels)) return 0; // ignore already paired

if (ec->name && !strcmp(ec->name, channel_get_epgid(ch))) return 1;
chid = channel_get_epgid(ch);
if (ec->name && !strcmp(ec->name, chid)) return 1;
if (ec->names)
HTSMSG_FOREACH(f, ec->names)
if ((s = htsmsg_field_get_str(f)) != NULL)
if (!strcmp(s, chid)) return 1;
if (ec->lcn && ec->lcn == channel_get_number(ch)) return 1;
return 0;
}
Expand Down Expand Up @@ -127,7 +135,7 @@ int epggrab_channel_set_name ( epggrab_channel_t *ec, const char *name )
channel_t *ch;
int save = 0;
if (!ec || !name) return 0;
if (!ec->name || strcmp(ec->name, name)) {
if (!ec->newnames && (!ec->name || strcmp(ec->name, name))) {
if (ec->name) free(ec->name);
ec->name = strdup(name);
if (epggrab_conf.channel_rename) {
Expand All @@ -139,6 +147,9 @@ int epggrab_channel_set_name ( epggrab_channel_t *ec, const char *name )
}
save = 1;
}
if (ec->newnames == NULL)
ec->newnames = htsmsg_create_list();
htsmsg_add_str(ec->newnames, NULL, name);
return save;
}

Expand Down Expand Up @@ -304,6 +315,8 @@ void epggrab_channel_destroy( epggrab_channel_t *ec, int delconf )
hts_settings_remove("epggrab/%s/channels/%s",
ec->mod->saveid, idnode_uuid_as_sstr(&ec->idnode));

htsmsg_destroy(ec->newnames);
htsmsg_destroy(ec->names);
free(ec->comment);
free(ec->name);
free(ec->icon);
Expand All @@ -319,6 +332,29 @@ void epggrab_channel_flush
epggrab_channel_destroy(ec, delconf);
}

void epggrab_channel_begin_scan ( epggrab_module_t *mod )
{
epggrab_channel_t *ec;
lock_assert(&global_lock);
RB_FOREACH(ec, &mod->channels, link)
if (ec->newnames) {
htsmsg_destroy(ec->newnames);
ec->newnames = NULL;
}
}

void epggrab_channel_end_scan ( epggrab_module_t *mod )
{
epggrab_channel_t *ec;
lock_assert(&global_lock);
RB_FOREACH(ec, &mod->channels, link)
if (ec->newnames) {
htsmsg_destroy(ec->names);
ec->names = ec->newnames;
ec->newnames = NULL;
}
}

/* **************************************************************************
* Global routines
* *************************************************************************/
Expand Down Expand Up @@ -435,6 +471,30 @@ epggrab_channel_class_path_get ( void *obj )
return &prop_sbuf_ptr;
}

static const void *
epggrab_channel_class_names_get ( void *obj )
{
epggrab_channel_t *ec = obj;
char *s = ec->names ? htsmsg_list_2_csv(ec->names, ',', 0) : NULL;
snprintf(prop_sbuf, PROP_SBUF_LEN, "%s", s ?: "");
free(s);
return &prop_sbuf_ptr;
}

static int
epggrab_channel_class_names_set ( void *obj, const void *p )
{
htsmsg_t *m = htsmsg_csv_2_list(p, ',');
epggrab_channel_t *ec = obj;
if (htsmsg_cmp(ec->names, m)) {
htsmsg_destroy(ec->names);
ec->names = m;
} else {
htsmsg_destroy(m);
}
return 0;
}

static const void *
epggrab_channel_class_channels_get ( void *obj )
{
Expand Down Expand Up @@ -508,6 +568,13 @@ const idclass_t epggrab_channel_class = {
.name = N_("Name"),
.off = offsetof(epggrab_channel_t, name),
},
{
.type = PT_STR,
.id = "names",
.name = N_("Names"),
.get = epggrab_channel_class_names_get,
.set = epggrab_channel_class_names_set,
},
{
.type = PT_S64,
.intsplit = CHANNEL_SPLIT,
Expand Down
8 changes: 8 additions & 0 deletions src/epggrab/module/pyepg.c
Expand Up @@ -373,6 +373,10 @@ static int _pyepg_parse_epg

if ((tags = htsmsg_get_map(data, "tags")) == NULL) return 0;

pthread_mutex_lock(&global_lock);
epggrab_channel_begin_scan(mod);
pthread_mutex_unlock(&global_lock);

HTSMSG_FOREACH(f, tags) {
save = 0;
if (strcmp(f->hmf_name, "channel") == 0 ) {
Expand Down Expand Up @@ -403,6 +407,10 @@ static int _pyepg_parse_epg
gsave |= save;
}

pthread_mutex_lock(&global_lock);
epggrab_channel_end_scan(mod);
pthread_mutex_unlock(&global_lock);

return gsave;
}

Expand Down
9 changes: 9 additions & 0 deletions src/epggrab/module/xmltv.c
Expand Up @@ -651,6 +651,10 @@ static int _xmltv_parse_tv
if((tags = htsmsg_get_map(body, "tags")) == NULL)
return 0;

pthread_mutex_lock(&global_lock);
epggrab_channel_begin_scan(mod);
pthread_mutex_unlock(&global_lock);

HTSMSG_FOREACH(f, tags) {
save = 0;
if(!strcmp(f->hmf_name, "channel")) {
Expand All @@ -665,6 +669,11 @@ static int _xmltv_parse_tv
}
gsave |= save;
}

pthread_mutex_lock(&global_lock);
epggrab_channel_end_scan(mod);
pthread_mutex_unlock(&global_lock);

return gsave;
}

Expand Down
4 changes: 4 additions & 0 deletions src/epggrab/private.h
Expand Up @@ -61,6 +61,10 @@ void epggrab_channel_destroy
( epggrab_channel_t *ec, int delconf );
void epggrab_channel_flush
( epggrab_module_t *mod, int delconf );
void epggrab_channel_begin_scan
( epggrab_module_t *mod );
void epggrab_channel_end_scan
( epggrab_module_t *mod );

void epggrab_channel_init(void);
void epggrab_channel_done(void);
Expand Down
70 changes: 67 additions & 3 deletions src/htsmsg.c
Expand Up @@ -937,6 +937,71 @@ htsmsg_copy(htsmsg_t *src)
return dst;
}

/**
*
*/
int
htsmsg_cmp(htsmsg_t *m1, htsmsg_t *m2)
{
htsmsg_field_t *f1, *f2;

if (m1 == NULL && m2 == NULL)
return 0;
if (m1 == NULL || m2 == NULL)
return 1;

f2 = TAILQ_FIRST(&m2->hm_fields);
TAILQ_FOREACH(f1, &m1->hm_fields, hmf_link) {

if (f1->hmf_type != f2->hmf_type)
return 1;
if (strcmp(f1->hmf_name ?: "", f2->hmf_name ?: ""))
return 1;

switch(f1->hmf_type) {

case HMF_MAP:
case HMF_LIST:
if (htsmsg_cmp(&f1->hmf_msg, &f2->hmf_msg))
return 1;
break;

case HMF_STR:
if (strcmp(f1->hmf_str, f2->hmf_str))
return 1;
break;

case HMF_S64:
if (f1->hmf_s64 != f2->hmf_s64)
return 1;
break;

case HMF_BOOL:
if (f1->hmf_bool != f2->hmf_bool)
return 1;
break;

case HMF_BIN:
if (f1->hmf_binsize != f2->hmf_binsize)
return 1;
if (memcmp(f1->hmf_bin, f2->hmf_bin, f1->hmf_binsize))
return 1;
break;

case HMF_DBL:
if (f1->hmf_dbl != f2->hmf_dbl)
return 1;
break;
}

f2 = TAILQ_NEXT(f2, hmf_link);
}

if (f2)
return 1;
return 0;
}

/**
*
*/
Expand Down Expand Up @@ -1004,12 +1069,11 @@ htsmsg_list_2_csv(htsmsg_t *m, char delim, int human)
if (human) {
sep[0] = delim;
sep[1] = ' ';
sep[2] = '\0';
ssep = "\"";
ssep = "";
} else {
sep[0] = delim;
sep[1] = '\0';
ssep = "";
ssep = "\"";
}
HTSMSG_FOREACH(f, m) {
if (f->hmf_type == HMF_STR) {
Expand Down
5 changes: 5 additions & 0 deletions src/htsmsg.h
Expand Up @@ -389,6 +389,11 @@ htsmsg_field_t *htsmsg_field_last(htsmsg_t *msg);
*/
htsmsg_t *htsmsg_copy(htsmsg_t *src);

/**
* Compare a message.
*/
int htsmsg_cmp(htsmsg_t *m1, htsmsg_t *m2);

#define HTSMSG_FOREACH(f, msg) TAILQ_FOREACH(f, &(msg)->hm_fields, hmf_link)


Expand Down

0 comments on commit eda1d0d

Please sign in to comment.