From b85ca93e5d43149c5e2ea025ac905372cab8d272 Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Thu, 7 Jun 2012 21:46:51 +0100 Subject: [PATCH] Yet more tidying up of the epggrab framework including epggrab channel save/load. Definitely think I am getting somewhere now. --- src/epggrab.c | 295 +++++++++++++++++++++++++++++--------------- src/epggrab.h | 49 +++++--- src/epggrab/pyepg.c | 92 ++++++-------- src/epggrab/xmltv.c | 64 +++++----- 4 files changed, 289 insertions(+), 211 deletions(-) diff --git a/src/epggrab.c b/src/epggrab.c index 9b41dd41..9e269cb3 100644 --- a/src/epggrab.c +++ b/src/epggrab.c @@ -135,24 +135,28 @@ static void _epggrab_socket_handler ( epggrab_module_t *mod, int s ) */ static void* _epggrab_internal_thread ( void* p ) { - int confver = -1; // force first run + int err, confver = -1; // force first run struct timespec ts; epggrab_module_t *mod; /* Setup timeout */ ts.tv_nsec = 0; - ts.tv_sec = 0; + time(&ts.tv_sec); while ( 1 ) { /* Check for config change */ pthread_mutex_lock(&epggrab_mutex); while ( confver == epggrab_confver ) { - int err = pthread_cond_timedwait(&epggrab_cond, &epggrab_mutex, &ts); + if (epggrab_module) { + err = pthread_cond_timedwait(&epggrab_cond, &epggrab_mutex, &ts); + } else { + err = pthread_cond_wait(&epggrab_cond, &epggrab_mutex); + } if ( err == ETIMEDOUT ) break; } confver = epggrab_confver; - mod = NULL;//epggrab_module; + mod = epggrab_module; ts.tv_sec += epggrab_interval; pthread_mutex_unlock(&epggrab_mutex); @@ -196,95 +200,26 @@ static int _ch_id_cmp ( void *a, void *b ) ((epggrab_channel_t*)b)->id); } -static int _ch_match ( epggrab_channel_t *ec, channel_t *ch ) +// TODO: add other matches +static int _ch_link ( epggrab_channel_t *ec, channel_t *ch ) { - // TODO: this needs implementing - return 0; -} + int match = 0; -void epggrab_module_channels_load ( epggrab_module_t *mod ) -{ - char path[100]; - uint32_t chid; - htsmsg_t *m; - htsmsg_field_t *f; - epggrab_channel_t *ec; - channel_t *ch; + if (!ec || !ch) return 0; + if (ec->channel) return 0; - sprintf(path, "epggrab/%s/channels", mod->id); - if ((m = hts_settings_load(path))) { - HTSMSG_FOREACH(f, m) { - if ( !htsmsg_get_u32(m, f->hmf_name, &chid) ) { - ch = channel_find_by_identifier(chid); - if (ch) { - ec = calloc(1, sizeof(epggrab_channel_t)); - ec->id = strdup(f->hmf_name); - ec->channel = ch; - RB_INSERT_SORTED(mod->channels, ec, link, _ch_id_cmp); - } - } - } + if (ec->name && !strcmp(ec->name, ch->ch_name)) + match = 1; + + if (match) { + tvhlog(LOG_INFO, "epggrab", "linking %s to %s", + ch->ch_name, ec->id); + ec->channel = ch; + if (ec->name) channel_rename(ch, ec->name); + if (ec->icon) channel_set_icon(ch, ec->icon); } -} -void epggrab_module_channels_save - ( epggrab_module_t *mod, const char *path ) -{ - epggrab_channel_t *c; - htsmsg_t *m = htsmsg_create_map(); - - RB_FOREACH(c, mod->channels, link) { - if (c->channel) htsmsg_add_u32(m, c->id, c->channel->ch_id); - } - hts_settings_save(m, path); -} - -int epggrab_module_channel_add ( epggrab_module_t *mod, channel_t *ch ) -{ - int save = 0; - epggrab_channel_t *egc; - RB_FOREACH(egc, mod->channels, link) { - if (_ch_match(egc, ch) ) { - save = 1; - egc->channel = ch; - break; - } - } - return save; -} - -int epggrab_module_channel_rem ( epggrab_module_t *mod, channel_t *ch ) -{ - int save = 0; - epggrab_channel_t *egc; - RB_FOREACH(egc, mod->channels, link) { - if (egc->channel == ch) { - save = 1; - egc->channel = NULL; - break; - } - } - return save; -} - -int epggrab_module_channel_mod ( epggrab_module_t *mod, channel_t *ch ) -{ - return epggrab_module_channel_add(mod, ch); -} - - -epggrab_channel_t *epggrab_module_channel_create ( epggrab_module_t *mod ) -{ - // TODO: implement this - return NULL; -} - -epggrab_channel_t *epggrab_module_channel_find - ( epggrab_module_t *mod, const char *id ) -{ - epggrab_channel_t skel; - skel.id = (char*)id; - return RB_FIND(mod->channels, &skel, link, _ch_id_cmp); + return match; } // TODO: could use TCP socket to allow remote access @@ -340,6 +275,14 @@ int epggrab_module_enable_socket ( epggrab_module_t *mod, uint8_t e ) return 1; } +const char *epggrab_module_socket_path ( const char *id ) +{ + char *ret = malloc(100); + snprintf(ret, 100, "%s/epggrab/%s.sock", + hts_settings_get_root(), id); + return ret; +} + char *epggrab_module_grab ( epggrab_module_t *mod ) { int outlen; @@ -373,12 +316,166 @@ htsmsg_t *epggrab_module_trans_xml return ret; } -const char *epggrab_module_socket_path ( epggrab_module_t *mod ) +// TODO: add extra metadata +void epggrab_module_channel_save + ( epggrab_module_t *mod, epggrab_channel_t *ch ) { - char *ret = malloc(100); - snprintf(ret, 100, "%s/epggrab/%s.sock", - hts_settings_get_root(), mod->id); - return ret; + htsmsg_t *m = htsmsg_create_map(); + + if (ch->name) + htsmsg_add_str(m, "name", ch->name); + if (ch->icon) + htsmsg_add_str(m, "icon", ch->icon); + if (ch->channel) + htsmsg_add_u32(m, "channel", ch->channel->ch_id); + + hts_settings_save(m, "epggrab/%s/channels/%s", mod->id, ch->id); +} + +static void epggrab_module_channel_load + ( epggrab_module_t *mod, htsmsg_t *m, const char *id ) +{ + int save = 0; + const char *str; + uint32_t u32; + + epggrab_channel_t *ch = epggrab_module_channel_find(mod, id, 1, &save); + + if ((str = htsmsg_get_str(m, "name"))) + save |= epggrab_channel_set_name(ch, str); + if ((str = htsmsg_get_str(m, "icon"))) + save |= epggrab_channel_set_icon(ch, str); + + if (!htsmsg_get_u32(m, "channel", &u32)) + ch->channel = channel_find_by_identifier(u32); + + epggrab_channel_link(ch); +} + +void epggrab_module_channels_load ( epggrab_module_t *mod ) +{ + htsmsg_t *m, *e; + htsmsg_field_t *f; + + if ((m = hts_settings_load("epggrab/%s/channels", mod->id))) { + HTSMSG_FOREACH(f, m) { + printf("CHANNEL %s\n", f->hmf_name); + if ((e = htsmsg_get_map_by_field(f))) + epggrab_module_channel_load(mod, e, f->hmf_name); + } + } +} + +void epggrab_module_channel_add ( epggrab_module_t *mod, channel_t *ch ) +{ + epggrab_channel_t *egc; + RB_FOREACH(egc, mod->channels, link) { + if (_ch_link(egc, ch) ) { + epggrab_module_channel_save(mod, egc); + break; + } + } +} + +void epggrab_module_channel_rem ( epggrab_module_t *mod, channel_t *ch ) +{ + epggrab_channel_t *egc; + RB_FOREACH(egc, mod->channels, link) { + if (egc->channel == ch) { + egc->channel = NULL; + epggrab_module_channel_save(mod, egc); + break; + } + } +} + +void epggrab_module_channel_mod ( epggrab_module_t *mod, channel_t *ch ) +{ + return epggrab_module_channel_add(mod, ch); +} + + +epggrab_channel_t *epggrab_module_channel_find + ( epggrab_module_t *mod, const char *id, int create, int *save ) +{ + epggrab_channel_t *ec; + static epggrab_channel_t *skel = NULL; + + if (!mod || !mod->channels ) return NULL; + + if ( !skel ) skel = calloc(1, sizeof(epggrab_channel_t)); + skel->id = (char*)id; + skel->mod = mod; + + /* Find */ + if (!create) { + ec = RB_FIND(mod->channels, skel, link, _ch_id_cmp); + + /* Create (if required) */ + } else { + ec = RB_INSERT_SORTED(mod->channels, skel, link, _ch_id_cmp); + if ( ec == NULL ) { + skel->id = strdup(skel->id); + ec = skel; + skel = NULL; + *save = 1; + } + } + + return ec; +} + +/* ************************************************************************** + * Channels + * *************************************************************************/ + +int epggrab_channel_set_name ( epggrab_channel_t *ec, const char *name ) +{ + int save = 0; + if (!ec || !name) return 0; + if (!ec->name || strcmp(ec->name, name)) { + if (ec->name) free(ec->name); + ec->name = strdup(name); + if (ec->channel) channel_rename(ec->channel, name); + save = 1; + } + return save; +} + +int epggrab_channel_set_icon ( epggrab_channel_t *ec, const char *icon ) +{ + int save = 0; + if (!ec->icon || strcmp(ec->icon, icon) ) { + if (!ec | !icon) return 0; + if (ec->icon) free(ec->icon); + ec->icon = strdup(icon); + if (ec->channel) channel_set_icon(ec->channel, icon); + save = 1; + } + return save; +} + +// TODO: add other match critera +// TODO: add additional metadata updates +// TODO: add configurable updating +void epggrab_channel_link ( epggrab_channel_t *ec ) +{ + channel_t *ch; + + if (!ec) return; + + /* Link */ + if (ec->channel) { + RB_FOREACH(ch, &channel_name_tree, ch_name_link) { + if (_ch_link(ec, ch)) break; + } + } +} + +void epggrab_channel_updated ( epggrab_channel_t *ec ) +{ + epggrab_channel_link(ec); + epggrab_module_channel_save(ec->mod, ec); } /* ************************************************************************** @@ -526,9 +623,7 @@ void epggrab_channel_add ( channel_t *ch ) { epggrab_module_t *m; LIST_FOREACH(m, &epggrab_modules, link) { - if (m->ch_add) - if (m->ch_add(m, ch) && m->ch_save) - m->ch_save(m); + if (m->ch_add) m->ch_add(m, ch); } } @@ -536,9 +631,7 @@ void epggrab_channel_rem ( channel_t *ch ) { epggrab_module_t *m; LIST_FOREACH(m, &epggrab_modules, link) { - if (m->ch_rem) - if (m->ch_rem(m, ch) && m->ch_save) - m->ch_save(m); + if (m->ch_rem) m->ch_rem(m, ch); } } @@ -546,9 +639,7 @@ void epggrab_channel_mod ( channel_t *ch ) { epggrab_module_t *m; LIST_FOREACH(m, &epggrab_modules, link) { - if (m->ch_mod) - if (m->ch_mod(m, ch) && m->ch_save) - m->ch_save(m); + if (m->ch_mod) m->ch_mod(m, ch); } } diff --git a/src/epggrab.h b/src/epggrab.h index 41c7e005..93b0f86c 100644 --- a/src/epggrab.h +++ b/src/epggrab.h @@ -4,6 +4,8 @@ #include #include "channels.h" +typedef struct epggrab_module epggrab_module_t; + /* ************************************************************************** * Grabber Stats * *************************************************************************/ @@ -33,10 +35,12 @@ typedef struct epggrab_stats */ typedef struct epggrab_channel { - RB_ENTRY(epggrab_channel) link; ///< Global link + RB_ENTRY(epggrab_channel) link; ///< Global link + epggrab_module_t *mod; ///< Linked module char *id; ///< Grabber's ID char *name; ///< Channel name + char *icon; ///< Channel icon struct channel *channel; ///< Mapped channel // TODO: I think we might need a list of channels! } epggrab_channel_t; @@ -52,12 +56,23 @@ typedef struct epggrab_channel_tree epggrab_channel_tree_t; */ htsmsg_t* epggrab_channel_list ( void ); +/* + * Mutators + */ +int epggrab_channel_set_name ( epggrab_channel_t *ch, const char *name ); +int epggrab_channel_set_icon ( epggrab_channel_t *ch, const char *icon ); + +void epggrab_channel_updated ( epggrab_channel_t *ch ); +void epggrab_channel_link ( epggrab_channel_t *ch ); + +/* + * Match the channel + */ + /* ************************************************************************** * Grabber Modules * *************************************************************************/ -typedef struct epggrab_module epggrab_module_t; - /* * Grabber flags */ @@ -90,36 +105,30 @@ struct epggrab_module htsmsg_t *d, epggrab_stats_t *s ); /* Channel listings */ - int (*ch_add) ( epggrab_module_t *m, channel_t *ch ); - int (*ch_rem) ( epggrab_module_t *m, channel_t *ch ); - int (*ch_mod) ( epggrab_module_t *m, channel_t *ch ); - - /* Save any settings */ - void (*ch_save) ( epggrab_module_t *m ); + void (*ch_add) ( epggrab_module_t *m, channel_t *ch ); + void (*ch_rem) ( epggrab_module_t *m, channel_t *ch ); + void (*ch_mod) ( epggrab_module_t *m, channel_t *ch ); }; /* * Default module functions - * - * Kinda like a base class (shared by current modules xmltv and pyepg) */ int epggrab_module_enable_socket ( epggrab_module_t *m, uint8_t e ); -const char *epggrab_module_socket_path ( epggrab_module_t *m ); +const char *epggrab_module_socket_path ( const char *id ); char *epggrab_module_grab ( epggrab_module_t *m ); htsmsg_t *epggrab_module_trans_xml ( epggrab_module_t *m, char *d ); +void epggrab_module_channel_save + ( epggrab_module_t *m, epggrab_channel_t *ch ); void epggrab_module_channels_load ( epggrab_module_t *m ); -void epggrab_module_channels_save ( epggrab_module_t *m, const char *path ); -int epggrab_module_channel_add ( epggrab_module_t *m, channel_t *ch ); -int epggrab_module_channel_rem ( epggrab_module_t *m, channel_t *ch ); -int epggrab_module_channel_mod ( epggrab_module_t *m, channel_t *ch ); +void epggrab_module_channel_add ( epggrab_module_t *m, channel_t *ch ); +void epggrab_module_channel_rem ( epggrab_module_t *m, channel_t *ch ); +void epggrab_module_channel_mod ( epggrab_module_t *m, channel_t *ch ); -epggrab_channel_t *epggrab_module_channel_create - ( epggrab_module_t *m ); -epggrab_channel_t *epggrab_module_channel_find - ( epggrab_module_t *m, const char *id ); +epggrab_channel_t *epggrab_module_channel_find + ( epggrab_module_t *mod, const char *id, int create, int *save ); /* * Module list diff --git a/src/epggrab/pyepg.c b/src/epggrab/pyepg.c index bbb532c8..1a52f2d9 100644 --- a/src/epggrab/pyepg.c +++ b/src/epggrab/pyepg.c @@ -28,15 +28,13 @@ #include "epggrab/pyepg.h" #include "channels.h" +static epggrab_channel_tree_t _pyepg_channels; +static epggrab_module_t *_pyepg_module; -static channel_t *_pyepg_channel_create ( epggrab_channel_t *skel, int *save ) +static epggrab_channel_t *_pyepg_channel_find + ( const char *id, int create, int *save ) { - return NULL; -} - -static channel_t *_pyepg_channel_find ( const char *id ) -{ - return NULL; + return epggrab_module_channel_find(_pyepg_module, id, create, save); } /* ************************************************************************** @@ -57,37 +55,32 @@ static int _pyepg_parse_time ( const char *str, time_t *out ) static int _pyepg_parse_channel ( htsmsg_t *data, epggrab_stats_t *stats ) { - int save = 0, save2 = 0; + int save = 0; htsmsg_t *attr, *tags; - const char *icon; - channel_t *ch; - epggrab_channel_t skel; + const char *str; + epggrab_channel_t *ch; if ( data == NULL ) return 0; if ((attr = htsmsg_get_map(data, "attrib")) == NULL) return 0; - if ((skel.id = (char*)htsmsg_get_str(attr, "id")) == NULL) return 0; + if ((str = htsmsg_get_str(attr, "id")) == NULL) return 0; if ((tags = htsmsg_get_map(data, "tags")) == NULL) return 0; - skel.name = (char*)htsmsg_xml_get_cdata_str(tags, "name"); - icon = htsmsg_xml_get_cdata_str(tags, "image"); - - ch = _pyepg_channel_create(&skel, &save2); + if (!(ch = _pyepg_channel_find(str, 1, &save))) return 0; stats->channels.total++; - if (save2) { - stats->channels.created++; - save |= 1; - } + if (save) stats->channels.created++; - /* Update values */ - if (ch) { - if (skel.name) { - if(!ch->ch_name || strcmp(ch->ch_name, skel.name)) { - save |= channel_rename(ch, skel.name); - } - } - if (icon) channel_set_icon(ch, icon); + /* Update data */ + if ((str = htsmsg_xml_get_cdata_str(tags, "name"))) + save |= epggrab_channel_set_name(ch, str); + if ((str = htsmsg_xml_get_cdata_str(tags, "image"))) + save |= epggrab_channel_set_icon(ch, str); + // TODO: extra metadata + + /* Update */ + if (save) { + epggrab_channel_updated(ch); + stats->channels.modified++; } - if (save) stats->channels.modified++; return save; } @@ -311,21 +304,21 @@ static int _pyepg_parse_schedule ( htsmsg_t *data, epggrab_stats_t *stats ) int save = 0; htsmsg_t *attr, *tags; htsmsg_field_t *f; - channel_t *channel; + epggrab_channel_t *ec; const char *str; if ( data == NULL ) return 0; - if ((attr = htsmsg_get_map(data, "attrib")) == NULL) return 0; - if ((str = htsmsg_get_str(attr, "channel")) == NULL) return 0; - if ((channel = _pyepg_channel_find(str)) == NULL) return 0; - if ((tags = htsmsg_get_map(data, "tags")) == NULL) return 0; - stats->channels.total++; + if ((attr = htsmsg_get_map(data, "attrib")) == NULL) return 0; + if ((str = htsmsg_get_str(attr, "channel")) == NULL) return 0; + if ((ec = _pyepg_channel_find(str, 0, NULL)) == NULL) return 0; + if ((tags = htsmsg_get_map(data, "tags")) == NULL) return 0; + if (!ec->channel) return 0; HTSMSG_FOREACH(f, tags) { if (strcmp(f->hmf_name, "broadcast") == 0) { save |= _pyepg_parse_broadcast(htsmsg_get_map_by_field(f), - channel, stats); + ec->channel, stats); } } @@ -334,7 +327,7 @@ static int _pyepg_parse_schedule ( htsmsg_t *data, epggrab_stats_t *stats ) static int _pyepg_parse_epg ( htsmsg_t *data, epggrab_stats_t *stats ) { - int save = 0, chsave = 0; + int save = 0; htsmsg_t *tags; htsmsg_field_t *f; @@ -342,7 +335,7 @@ static int _pyepg_parse_epg ( htsmsg_t *data, epggrab_stats_t *stats ) HTSMSG_FOREACH(f, tags) { if (strcmp(f->hmf_name, "channel") == 0 ) { - chsave |= _pyepg_parse_channel(htsmsg_get_map_by_field(f), stats); + save |= _pyepg_parse_channel(htsmsg_get_map_by_field(f), stats); } else if (strcmp(f->hmf_name, "brand") == 0 ) { save |= _pyepg_parse_brand(htsmsg_get_map_by_field(f), stats); } else if (strcmp(f->hmf_name, "series") == 0 ) { @@ -353,10 +346,6 @@ static int _pyepg_parse_epg ( htsmsg_t *data, epggrab_stats_t *stats ) save |= _pyepg_parse_schedule(htsmsg_get_map_by_field(f), stats); } } -#if 0 - save |= chsave; - if (chsave) pyepg_save(); -#endif return save; } @@ -366,12 +355,6 @@ static int _pyepg_parse_epg ( htsmsg_t *data, epggrab_stats_t *stats ) * Module Setup * ***********************************************************************/ -epggrab_channel_tree_t _pyepg_channels; - -static void _pyepg_save ( epggrab_module_t *mod ) -{ - epggrab_module_channels_save(mod, "epggrab/pyepg/channels"); -} static int _pyepg_parse ( epggrab_module_t *mod, htsmsg_t *data, epggrab_stats_t *stats ) @@ -384,12 +367,6 @@ static int _pyepg_parse if ((epg = htsmsg_get_map(tags, "epg")) != NULL) return _pyepg_parse_epg(epg, stats); - /* XMLTV format */ - if ((epg = htsmsg_get_map(tags, "tv")) != NULL) { - mod = epggrab_module_find_by_id("xmltv_sync"); - if (mod) return mod->parse(mod, epg, stats); - } - return 0; } @@ -406,22 +383,25 @@ void pyepg_init ( epggrab_module_list_t *list ) mod->trans = epggrab_module_trans_xml; mod->parse = _pyepg_parse; mod->channels = &_pyepg_channels; - mod->ch_save = _pyepg_save; mod->ch_add = epggrab_module_channel_add; mod->ch_rem = epggrab_module_channel_rem; mod->ch_mod = epggrab_module_channel_mod; *((uint8_t*)&mod->flags) = EPGGRAB_MODULE_SIMPLE; LIST_INSERT_HEAD(list, mod, link); + _pyepg_module = mod; /* External module */ mod = calloc(1, sizeof(epggrab_module_t)); mod->id = strdup("pyepg_ext"); - mod->path = epggrab_module_socket_path(mod); + mod->path = epggrab_module_socket_path("pyepg"); mod->name = strdup("PyEPG"); mod->enable = epggrab_module_enable_socket; mod->trans = epggrab_module_trans_xml; mod->parse = _pyepg_parse; *((uint8_t*)&mod->flags) = EPGGRAB_MODULE_EXTERNAL; LIST_INSERT_HEAD(list, mod, link); + + /* Load channel config */ + epggrab_module_channels_load(_pyepg_module); } diff --git a/src/epggrab/xmltv.c b/src/epggrab/xmltv.c index 270707ab..c60145dd 100644 --- a/src/epggrab/xmltv.c +++ b/src/epggrab/xmltv.c @@ -37,10 +37,19 @@ #define XMLTV_FIND_GRABBERS "/usr/bin/tv_find_grabbers" +static epggrab_channel_tree_t _xmltv_channels; +static epggrab_module_t *_xmltv_module; + +static epggrab_channel_t *_xmltv_channel_find + ( const char *id, int create, int *save ) +{ + return epggrab_module_channel_find(_xmltv_module, id, create, save); +} + + /* ************************************************************************** * Parsing * *************************************************************************/ -#if TODO_XMLTV_GRABBER /** * Hash the description to get a URI for episode @@ -48,7 +57,6 @@ * Note: converts to an ASCII format * TODO: move somewhere else */ -#if 0 static const char *_xmltv_hash ( const char *str ) { size_t i; @@ -61,7 +69,6 @@ static const char *_xmltv_hash ( const char *str ) ret[MD5_DIGEST_LENGTH*2] = '\0'; return ret; } -#endif /** * @@ -94,7 +101,6 @@ _xmltv_str2time(const char *str) } } -#if 0 /** * This is probably the most obscure formating there is. From xmltv.dtd: * @@ -221,16 +227,13 @@ get_episode_info } } -#endif - /** * Parse tags inside of a programme */ static int -_xmltv_parse_programme_tags(epg_channel_t *xc, htsmsg_t *tags, +_xmltv_parse_programme_tags(channel_t *ch, htsmsg_t *tags, time_t start, time_t stop, epggrab_stats_t *stats) { -#if TODO_XMLTV int save = 0, save2 = 0; epg_episode_t *ee; epg_broadcast_t *ebc; @@ -243,13 +246,14 @@ _xmltv_parse_programme_tags(epg_channel_t *xc, htsmsg_t *tags, get_episode_info(tags, &onscreen, &sn, &en, &pn); /* Create/Find broadcast */ - ebc = epg_broadcast_find_by_time(xc, start, stop, 1, &save2); + ebc = epg_broadcast_find_by_time(ch, start, stop, 1, &save2); if ( ebc != NULL ) { stats->broadcasts.total++; if (save2) stats->broadcasts.created++; - save2 |= epg_broadcast_set_episode(ebc, ee); + //save2 |= epg_broadcast_set_episode(ebc, ee); if (save2) stats->broadcasts.modified++; } + // TODO: this needs reworking // TODO: // do we attempt to make an episode URI from info? @@ -278,8 +282,6 @@ _xmltv_parse_programme_tags(epg_channel_t *xc, htsmsg_t *tags, return save | save2; -#endif - return 0; } @@ -293,14 +295,15 @@ _xmltv_parse_programme(htsmsg_t *body, epggrab_stats_t *stats) htsmsg_t *attribs, *tags; const char *s, *chid; time_t start, stop; - epg_channel_t *xc; + epggrab_channel_t *ch; if(body == NULL) return 0; if((attribs = htsmsg_get_map(body, "attrib")) == NULL) return 0; if((tags = htsmsg_get_map(body, "tags")) == NULL) return 0; if((chid = htsmsg_get_str(attribs, "channel")) == NULL) return 0; - if((xc = epg_channel_find_by_uri(chid, 0, NULL)) == NULL) return 0; + if((ch = _xmltv_channel_find(chid, 0, NULL)) == NULL) return 0; + if (ch->channel == NULL) return 0; if((s = htsmsg_get_str(attribs, "start")) == NULL) return 0; start = _xmltv_str2time(s); if((s = htsmsg_get_str(attribs, "stop")) == NULL) return 0; @@ -308,7 +311,7 @@ _xmltv_parse_programme(htsmsg_t *body, epggrab_stats_t *stats) if(stop <= start || stop < dispatch_clock) return 0; - save |= _xmltv_parse_programme_tags(xc, tags, start, stop, stats); + save |= _xmltv_parse_programme_tags(ch->channel, tags, start, stop, stats); return save; } @@ -321,27 +324,30 @@ _xmltv_parse_channel(htsmsg_t *body, epggrab_stats_t *stats) int save =0; htsmsg_t *attribs, *tags, *subtag; const char *id, *name, *icon; - epg_channel_t *xc; + epggrab_channel_t *ch; if(body == NULL) return 0; if((attribs = htsmsg_get_map(body, "attrib")) == NULL) return 0; if((id = htsmsg_get_str(attribs, "id")) == NULL) return 0; if((tags = htsmsg_get_map(body, "tags")) == NULL) return 0; - if((xc = epg_channel_find_by_uri(id, 1, &save)) == NULL) return 0; + if((ch = _xmltv_channel_find(id, 1, &save)) == NULL) return 0; stats->channels.total++; if (save) stats->channels.created++; if((name = htsmsg_xml_get_cdata_str(tags, "display-name")) != NULL) { - save |= epg_channel_set_name(xc, name); + save |= epggrab_channel_set_name(ch, name); } if((subtag = htsmsg_get_map(tags, "icon")) != NULL && (attribs = htsmsg_get_map(subtag, "attrib")) != NULL && (icon = htsmsg_get_str(attribs, "src")) != NULL) { - save |= epg_channel_set_icon(xc, icon); + save |= epggrab_channel_set_icon(ch, icon); + } + if (save) { + epggrab_channel_updated(ch); + stats->channels.modified++; } - if (save) stats->channels.modified++; return save; } @@ -367,23 +373,14 @@ _xmltv_parse_tv(htsmsg_t *body, epggrab_stats_t *stats) } return save; } -#endif /* ************************************************************************ * Module Setup * ***********************************************************************/ -epggrab_channel_tree_t _xmltv_channels; - -static void _xmltv_save ( epggrab_module_t *mod ) -{ - epggrab_module_channels_save(mod, "epggrab/xmltv/channels"); -} - static int _xmltv_parse ( epggrab_module_t *mod, htsmsg_t *data, epggrab_stats_t *stats ) { -#if 0 htsmsg_t *tags, *tv; if((tags = htsmsg_get_map(data, "tags")) == NULL) @@ -393,8 +390,6 @@ static int _xmltv_parse return 0; return _xmltv_parse_tv(tv, stats); -#endif - return 0; } static void _xmltv_load_grabbers ( epggrab_module_list_t *list ) @@ -443,7 +438,7 @@ void xmltv_init ( epggrab_module_list_t *list ) mod = calloc(1, sizeof(epggrab_module_t)); mod->id = strdup("xmltv"); mod->name = strdup("XMLTV"); - mod->path = epggrab_module_socket_path(mod); + mod->path = epggrab_module_socket_path("xmltv"); mod->enable = epggrab_module_enable_socket; mod->trans = epggrab_module_trans_xml; mod->parse = _xmltv_parse; @@ -451,10 +446,13 @@ void xmltv_init ( epggrab_module_list_t *list ) mod->ch_add = epggrab_module_channel_add; mod->ch_rem = epggrab_module_channel_rem; mod->ch_mod = epggrab_module_channel_mod; - mod->ch_save = _xmltv_save; *((uint8_t*)&mod->flags) = EPGGRAB_MODULE_EXTERNAL; LIST_INSERT_HEAD(list, mod, link); + _xmltv_module = mod; /* Standard modules */ _xmltv_load_grabbers(list); + + /* Load channel config */ + epggrab_module_channels_load(mod); }