diff --git a/data/epggrab/opentv/genre/skyuk b/data/epggrab/opentv/genre/skyuk new file mode 100644 index 00000000..8e3a38b5 --- /dev/null +++ b/data/epggrab/opentv/genre/skyuk @@ -0,0 +1,258 @@ +[ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 166, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 80, + 85, + 80, + 80, + 84, + 81, + 84, + 80, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16, + 18, + 20, + 17, + 16, + 49, + 19, + 21, + 16, + 51, + 165, + 144, + 123, + 167, + 161, + 16, + 112, + 160, + 160, + 34, + 16, + 36, + 160, + 163, + 117, + 102, + 101, + 0, + 0, + 0, + 0, + 0, + 96, + 98, + 99, + 96, + 100, + 101, + 97, + 96, + 96, + 96, + 96, + 96, + 96, + 0, + 0, + 0, + 96, + 0, + 0, + 0, + 0, + 96, + 96, + 96, + 96, + 96, + 96, + 0, + 0, + 0, + 0, + 0, + 32, + 32, + 32, + 32, + 131, + 144, + 32, + 128, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 32, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16, + 18, + 16, + 16, + 20, + 16, + 16, + 16, + 19, + 17, + 19, + 22, + 16, + 16, + 18, + 23, + 19, + 24, + 18, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 64, + 69, + 70, + 69, + 69, + 64, + 69, + 64, + 67, + 64, + 69, + 71, + 74, + 69, + 74, + 73, + 64, + 68, + 75, + 64, + 64, + 64, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 +] diff --git a/data/epggrab/opentv/prov/skyuk b/data/epggrab/opentv/prov/skyuk index 49e51ac3..9aa7ec11 100644 --- a/data/epggrab/opentv/prov/skyuk +++ b/data/epggrab/opentv/prov/skyuk @@ -1,6 +1,7 @@ { "name": "Sky UK", "dict": "skyeng", + "genre": "skyuk", "nid": 2, "tsid": 2004, "sid": 4152, diff --git a/src/epggrab/channel.c b/src/epggrab/channel.c index f08afe9a..abd57633 100644 --- a/src/epggrab/channel.c +++ b/src/epggrab/channel.c @@ -210,10 +210,12 @@ static int _ch_id_cmp ( void *a, void *b ) /* Find/Create channel in the list */ epggrab_channel_t *epggrab_channel_find - ( epggrab_channel_tree_t *tree, const char *id, int create, int *save ) + ( epggrab_channel_tree_t *tree, const char *id, int create, int *save, + epggrab_module_t *owner ) { epggrab_channel_t *ec; static epggrab_channel_t *skel = NULL; + assert(owner); if (!skel) skel = calloc(1, sizeof(epggrab_channel_t)); skel->id = (char*)id; @@ -225,10 +227,11 @@ epggrab_channel_t *epggrab_channel_find } else { ec = RB_INSERT_SORTED(tree, skel, link, _ch_id_cmp); if (!ec) { - ec = skel; - skel = NULL; - ec->id = strdup(id); - *save = 1; + ec = skel; + skel = NULL; + ec->id = strdup(id); + ec->mod = owner; + *save = 1; } } return ec; diff --git a/src/epggrab/module.c b/src/epggrab/module.c index e34f3272..bf075455 100644 --- a/src/epggrab/module.c +++ b/src/epggrab/module.c @@ -216,7 +216,7 @@ static void _epggrab_module_channel_load htsmsg_t *a; htsmsg_field_t *f; - epggrab_channel_t *ch = epggrab_channel_find(mod->channels, id, 1, &save); + epggrab_channel_t *ch = epggrab_channel_find(mod->channels, id, 1, &save, mod); if ((str = htsmsg_get_str(m, "name"))) ch->name = strdup(str); diff --git a/src/epggrab/module/eit.c b/src/epggrab/module/eit.c index 8ec0f3e9..5b4d81b9 100644 --- a/src/epggrab/module/eit.c +++ b/src/epggrab/module/eit.c @@ -207,18 +207,16 @@ static int _eit_callback svc = dvb_transport_find(tdmi, sid, 0, NULL); if (!svc || !svc->s_enabled || !(ch = svc->s_ch)) return 0; - /* Ignore (disabled) */ - // TODO: should this be altered? if (!svc->s_dvb_eit_enable) return 0; /* Register as interesting */ - // TODO: do we want to register for now/next? - // TODO: want should the intervals be? if (tableid < 0x50) - epggrab_ota_register(ota, 20, 0); + epggrab_ota_register(ota, 20, 300); // 20s grab, 5min interval else - epggrab_ota_register(ota, 40, 0); + epggrab_ota_register(ota, 600, 3600); // 10min grab, 1hour interval + // Note: this does mean you will get a slight oddity for muxes that + // carry both, since they will end up with setting of 600/300 /* Up to date */ #if TODO_INCLUDE_EIT_VER_CHECK diff --git a/src/epggrab/module/opentv.c b/src/epggrab/module/opentv.c index 4ec06eee..8fb2219b 100644 --- a/src/epggrab/module/opentv.c +++ b/src/epggrab/module/opentv.c @@ -119,6 +119,13 @@ typedef struct opentv_dict RB_ENTRY(opentv_dict) h_link; } opentv_dict_t; +typedef struct opentv_genre +{ + char *id; + uint8_t map[256]; + RB_ENTRY(opentv_genre) h_link; +} opentv_genre_t; + /* Provider configuration */ typedef struct opentv_module_t { @@ -131,13 +138,14 @@ typedef struct opentv_module_t int *title; int *summary; opentv_dict_t *dict; + opentv_genre_t *genre; } opentv_module_t; /* * Dictionary list */ -RB_HEAD(, opentv_dict) _opentv_dicts; +RB_HEAD(, opentv_dict) _opentv_dicts; static int _dict_cmp ( void *a, void *b ) { @@ -151,6 +159,23 @@ static opentv_dict_t *_opentv_dict_find ( const char *id ) return RB_FIND(&_opentv_dicts, &skel, h_link, _dict_cmp); } +/* + * Genre mapping list + */ +RB_HEAD(, opentv_genre) _opentv_genres; + +static int _genre_cmp ( void *a, void *b ) +{ + return strcmp(((opentv_genre_t*)a)->id, ((opentv_genre_t*)b)->id); +} + +static opentv_genre_t *_opentv_genre_find ( const char *id ) +{ + opentv_genre_t skel; + skel.id = (char*)id; + return RB_FIND(&_opentv_genres, &skel, h_link, _genre_cmp); +} + /* ************************************************************************ * EPG Object wrappers * ***********************************************************************/ @@ -160,7 +185,8 @@ static epggrab_channel_t *_opentv_find_epggrab_channel { char chid[32]; sprintf(chid, "%s-%d", mod->id, cid); - return epggrab_channel_find(&_opentv_channels, chid, create, save); + return epggrab_channel_find(&_opentv_channels, chid, create, save, + (epggrab_module_t*)mod); } static epg_season_t *_opentv_find_season @@ -258,6 +284,8 @@ static int _opentv_parse_event_record ev->stop = (((int)buf[4] << 9) | (buf[5] << 1)) + ev->start; ev->cat = buf[6]; + if (prov->genre) + ev->cat = prov->genre->map[ev->cat]; if (!ev->title) ev->title = _opentv_parse_string(prov, buf+9, rlen-7); break; @@ -720,6 +748,44 @@ static int* _pid_list_to_array ( htsmsg_t *m ) return ret; } +static int _opentv_genre_load_one ( const char *id, htsmsg_t *m ) +{ + htsmsg_field_t *f; + opentv_genre_t *genre = calloc(1, sizeof(opentv_genre_t)); + genre->id = (char*)id; + if (RB_INSERT_SORTED(&_opentv_genres, genre, h_link, _genre_cmp)) { + tvhlog(LOG_DEBUG, "opentv", "ignore duplicate genre map %s", id); + free(genre); + return 0; + } else { + genre->id = strdup(id); + int i = 0; + HTSMSG_FOREACH(f, m) { + genre->map[i] = (uint8_t)f->hmf_s64; + if (++i == 256) break; + } + } + return 1; +} + +static void _opentv_genre_load ( htsmsg_t *m ) +{ + int r; + htsmsg_t *e; + htsmsg_field_t *f; + HTSMSG_FOREACH(f, m) { + if ((e = htsmsg_get_list(m, f->hmf_name))) { + if ((r = _opentv_genre_load_one(f->hmf_name, e))) { + if (r > 0) + tvhlog(LOG_INFO, "opentv", "genre map %s loaded", f->hmf_name); + else + tvhlog(LOG_WARNING, "opentv", "genre map %s failed", f->hmf_name); + } + } + } + htsmsg_destroy(m); +} + static int _opentv_dict_load_one ( const char *id, htsmsg_t *m ) { opentv_dict_t *dict = calloc(1, sizeof(opentv_dict_t)); @@ -766,6 +832,7 @@ static int _opentv_prov_load_one ( const char *id, htsmsg_t *m ) uint32_t tsid, sid, nid; const char *str, *name; opentv_dict_t *dict; + opentv_genre_t *genre; opentv_module_t *mod; /* Check config */ @@ -779,6 +846,14 @@ static int _opentv_prov_load_one ( const char *id, htsmsg_t *m ) if (htsmsg_get_u32(m, "tsid", &tsid)) return -1; if (htsmsg_get_u32(m, "sid", &sid)) return -1; + /* Genre map (optional) */ + str = htsmsg_get_str(m, "genre"); + if (str) + genre = _opentv_genre_find(str); + else + genre = NULL; + + /* Exists (we expect some duplicates due to config layout) */ sprintf(ibuf, "opentv-%s", id); if (epggrab_module_find_by_id(ibuf)) return 0; @@ -793,6 +868,7 @@ static int _opentv_prov_load_one ( const char *id, htsmsg_t *m ) /* Add provider details */ mod->dict = dict; + mod->genre = genre; mod->nid = nid; mod->tsid = tsid; mod->sid = sid; @@ -839,6 +915,13 @@ void opentv_init ( void ) _opentv_dict_load(m); tvhlog(LOG_INFO, "opentv", "dictonaries loaded"); + /* Load genres */ + if ((m = hts_settings_load("epggrab/opentv/genre"))) + _opentv_genre_load(m); + if ((m = hts_settings_load("%s/data/epggrab/opentv/genre", dr))) + _opentv_genre_load(m); + tvhlog(LOG_INFO, "opentv", "genre maps loaded"); + /* Load providers */ if ((m = hts_settings_load("epggrab/opentv/prov"))) _opentv_prov_load(m); diff --git a/src/epggrab/module/pyepg.c b/src/epggrab/module/pyepg.c index 4dc7268a..8793f7d2 100644 --- a/src/epggrab/module/pyepg.c +++ b/src/epggrab/module/pyepg.c @@ -30,11 +30,13 @@ #include "epggrab/private.h" static epggrab_channel_tree_t _pyepg_channels; +static epggrab_module_t *_pyepg_module; // primary module static epggrab_channel_t *_pyepg_channel_find ( const char *id, int create, int *save ) { - return epggrab_channel_find(&_pyepg_channels, id, create, save); + return epggrab_channel_find(&_pyepg_channels, id, create, save, + _pyepg_module); } /* ************************************************************************** @@ -439,9 +441,10 @@ void pyepg_init ( void ) NULL, _pyepg_parse, NULL, NULL); /* External module */ - epggrab_module_ext_create(NULL, "pyepg", "PyEPG", "pyepg", - _pyepg_parse, NULL, - &_pyepg_channels); + _pyepg_module = (epggrab_module_t*) + epggrab_module_ext_create(NULL, "pyepg", "PyEPG", "pyepg", + _pyepg_parse, NULL, + &_pyepg_channels); } void pyepg_load ( void ) diff --git a/src/epggrab/module/xmltv.c b/src/epggrab/module/xmltv.c index 546f367a..b34fab50 100644 --- a/src/epggrab/module/xmltv.c +++ b/src/epggrab/module/xmltv.c @@ -40,11 +40,14 @@ #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_channel_find(&_xmltv_channels, id, create, save); + + return epggrab_channel_find(&_xmltv_channels, id, create, save, + _xmltv_module); } /* ************************************************************************** @@ -494,9 +497,10 @@ static void _xmltv_load_grabbers ( void ) void xmltv_init ( void ) { /* External module */ - epggrab_module_ext_create(NULL, "xmltv", "XMLTV", "xmltv", - _xmltv_parse, NULL, - &_xmltv_channels); + _xmltv_module = (epggrab_module_t*) + epggrab_module_ext_create(NULL, "xmltv", "XMLTV", "xmltv", + _xmltv_parse, NULL, + &_xmltv_channels); /* Standard modules */ _xmltv_load_grabbers(); diff --git a/src/epggrab/private.h b/src/epggrab/private.h index ed1942d9..c4b94374 100644 --- a/src/epggrab/private.h +++ b/src/epggrab/private.h @@ -48,7 +48,8 @@ void epggrab_module_channels_load ( epggrab_module_t *m ); int epggrab_channel_link ( epggrab_channel_t *ec, struct channel *ch ); epggrab_channel_t *epggrab_channel_find - ( epggrab_channel_tree_t *chs, const char *id, int create, int *save ); + ( epggrab_channel_tree_t *chs, const char *id, int create, int *save, + epggrab_module_t *owner ); /* ************************************************************************** * Internal module routines