From e5e7bc853cc3500cc346235b826fd3f1cc905d65 Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Sun, 3 Jun 2012 23:12:15 +0100 Subject: [PATCH] Some further updates (simplfications) to the epggrab framework. --- src/epggrab.c | 5 +- src/epggrab.h | 17 +++++-- src/epggrab/eit.c | 20 ++++++-- src/epggrab/pyepg.c | 105 +++++++++++---------------------------- src/epggrab/xmltv.c | 117 ++++++++++++++++++++------------------------ 5 files changed, 111 insertions(+), 153 deletions(-) diff --git a/src/epggrab.c b/src/epggrab.c index c8a5da95..9cb3e609 100644 --- a/src/epggrab.c +++ b/src/epggrab.c @@ -66,13 +66,12 @@ void epggrab_module_channels_load ( epggrab_module_t *mod ) } } -void epggrab_module_channels_save ( epggrab_module_t *mod ) +void epggrab_module_channels_save + ( epggrab_module_t *mod, const char *path ) { - char path[100]; epggrab_channel_t *c; htsmsg_t *m = htsmsg_create_map(); - sprintf(path, "epggrab/%s/channels", mod->id); RB_FOREACH(c, mod->channels, link) { if (c->channel) htsmsg_add_u32(m, c->id, c->channel->ch_id); } diff --git a/src/epggrab.h b/src/epggrab.h index 28a6b35a..50b9887b 100644 --- a/src/epggrab.h +++ b/src/epggrab.h @@ -54,6 +54,14 @@ typedef struct epggrab_channel_tree epggrab_channel_tree_t; typedef struct epggrab_module epggrab_module_t; +/* + * Grabber flags + */ +#define EPGGRAB_MODULE_SYNC 0x1 +#define EPGGRAB_MODULE_ASYNC 0x2 +#define EPGGRAB_MODULE_SIMPLE 0x4 +#define EPGGRAB_MODULE_ADVANCED 0x8 + /* * Grabber base class */ @@ -64,8 +72,7 @@ struct epggrab_module const char *id; ///< Module identifier const char *name; ///< Module name (for display) const char *path; ///< Module path (for fixed config) - const uint8_t simple; ///< Include in simple list - const uint8_t async; ///< Asynchronous (not schedulable) + const uint8_t flags; ///< Mode flags epggrab_channel_tree_t *channels; ///< Channel list /* Enable/Disable for async */ @@ -87,10 +94,12 @@ struct epggrab_module }; /* - * Default channel handlers + * Default module functions */ +void epggrab_module_enable ( epggrab_module_t *m, uint8_t e ); +htsmsg_t *epggrab_module_grab ( epggrab_module_t *m, const char *cmd, const char *opts ); void epggrab_module_channels_load ( epggrab_module_t *m ); -void epggrab_module_channels_save ( 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 ); diff --git a/src/epggrab/eit.c b/src/epggrab/eit.c index ba5368df..faf811ea 100644 --- a/src/epggrab/eit.c +++ b/src/epggrab/eit.c @@ -84,11 +84,23 @@ void eit_callback ( channel_t *ch, int id, time_t start, time_t stop, } } -epggrab_module_t _eit_mod; +/* ************************************************************************ + * Module Setup + * ***********************************************************************/ + +static epggrab_module_t _eit_mod; +static uint8_t _eit_enabled; + +static void _eit_enable ( epggrab_module_t *mod, uint8_t e ) +{ + _eit_enabled = e; +} + void eit_init ( epggrab_module_list_t *list ) { - _eit_mod.id = strdup("eit"); - _eit_mod.name = strdup("EIT On-Air Grabber"); - *((uint8_t*)&_eit_mod.async) = 1; + _eit_mod.id = strdup("eit"); + _eit_mod.name = strdup("EIT: On-Air Grabber"); + *((uint8_t*)&_eit_mod.flags) = EPGGRAB_MODULE_ASYNC; + _eit_mod.enable = _eit_enable; LIST_INSERT_HEAD(list, &_eit_mod, link); } diff --git a/src/epggrab/pyepg.c b/src/epggrab/pyepg.c index 2155bfde..088d3a56 100644 --- a/src/epggrab/pyepg.c +++ b/src/epggrab/pyepg.c @@ -28,9 +28,6 @@ #include "epggrab/pyepg.h" #include "channels.h" -epggrab_channel_tree_t _pyepg_channels; -epggrab_module_t _pyepg_sync; -epggrab_module_t _pyepg_async; static channel_t *_pyepg_channel_create ( epggrab_channel_t *skel, int *save ) { @@ -364,6 +361,19 @@ static int _pyepg_parse_epg ( htsmsg_t *data, epggrab_stats_t *stats ) return save; } + +/* ************************************************************************ + * Module Setup + * ***********************************************************************/ + +epggrab_channel_tree_t _pyepg_channels; +epggrab_module_t _pyepg_module; + +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,83 +394,24 @@ static int _pyepg_parse return 0; } -/* ************************************************************************ - * Module Setup - * ***********************************************************************/ - -static void _pyepg_enable ( epggrab_module_t *mod, uint8_t e ) -{ -} - - -static htsmsg_t* _pyepg_grab ( epggrab_module_t *mod, const char *icmd, const char *iopts ) -{ - int i, outlen; - char *outbuf; - char errbuf[100]; - const char *argv[32]; // 32 args max! - char *toksave, *tok; - char *opts = NULL; - htsmsg_t *ret; - - /* TODO: do something (much) better! */ - if (iopts) opts = strdup(iopts); - i = 1; - argv[0] = "/usr/bin/pyepg"; - if ( opts ) { - tok = strtok_r(opts, " ", &toksave); - while ( tok != NULL ) { - argv[i++] = tok; - tok = strtok_r(NULL, " ", &toksave); - } - } - argv[i] = NULL; - - /* Debug */ - tvhlog(LOG_DEBUG, "pyepg", "grab %s %s", argv[0], iopts ? iopts : ""); - - /* Grab */ -#if 0 - outlen = spawn_and_store_stdout(argv[0], (char *const*)argv, &outbuf); -#else - outlen = spawn_and_store_stdout("/home/aps/tmp/epg.sh", NULL, &outbuf); -#endif - free(opts); - if ( outlen < 1 ) { - tvhlog(LOG_ERR, "pyepg", "no output detected"); - return NULL; - } - - /* Extract */ - ret = htsmsg_xml_deserialize(outbuf, errbuf, sizeof(errbuf)); - if (!ret) - tvhlog(LOG_ERR, "pyepg", "htsmsg_xml_deserialize error %s", errbuf); - return ret; -} - void pyepg_init ( epggrab_module_list_t *list ) { - /* Common routines */ - _pyepg_sync.channels = _pyepg_async.channels = &_pyepg_channels; - _pyepg_sync.ch_save = _pyepg_async.ch_save = epggrab_module_channels_save; - _pyepg_sync.ch_add = _pyepg_async.ch_add = epggrab_module_channel_add; - _pyepg_sync.ch_rem = _pyepg_async.ch_rem = epggrab_module_channel_rem; - _pyepg_sync.ch_mod = _pyepg_async.ch_mod = epggrab_module_channel_mod; - _pyepg_sync.name = _pyepg_async.name = strdup("PyEPG"); - - /* Sync */ - _pyepg_sync.id = strdup("pyepg_sync"); - _pyepg_sync.path = strdup("/usr/bin/pyepg"); - _pyepg_sync.grab = _pyepg_grab; - _pyepg_sync.parse = _pyepg_parse; - - /* Async */ - _pyepg_async.id = strdup("pyepg_async"); - _pyepg_async.enable = _pyepg_enable; - *((uint8_t*)&_pyepg_async.async) = 1; + _pyepg_module.id = strdup("pyepg_sync"); + _pyepg_module.path = strdup("/usr/bin/pyepg"); + *((uint8_t*)&_pyepg_module.flags) = EPGGRAB_MODULE_SYNC + | EPGGRAB_MODULE_ASYNC + | EPGGRAB_MODULE_ADVANCED + | EPGGRAB_MODULE_SIMPLE; + _pyepg_module.enable = epggrab_module_enable; + _pyepg_module.grab = epggrab_module_grab; + _pyepg_module.parse = _pyepg_parse; + _pyepg_module.channels = &_pyepg_channels; + _pyepg_module.ch_save = _pyepg_save; + _pyepg_module.ch_add = epggrab_module_channel_add; + _pyepg_module.ch_rem = epggrab_module_channel_rem; + _pyepg_module.ch_mod = epggrab_module_channel_mod; /* Add to list */ - LIST_INSERT_HEAD(list, &_pyepg_sync, link); - LIST_INSERT_HEAD(list, &_pyepg_async, link); + LIST_INSERT_HEAD(list, &_pyepg_module, link); } diff --git a/src/epggrab/xmltv.c b/src/epggrab/xmltv.c index f96d982b..dee9f9fc 100644 --- a/src/epggrab/xmltv.c +++ b/src/epggrab/xmltv.c @@ -367,12 +367,23 @@ _xmltv_parse_tv(htsmsg_t *body, epggrab_stats_t *stats) } return save; } +#endif -/** - * - */ -static int _xmltv_parse ( htsmsg_t *data, epggrab_stats_t *stats ) +/* ************************************************************************ + * 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) @@ -382,38 +393,39 @@ static int _xmltv_parse ( htsmsg_t *data, epggrab_stats_t *stats ) return 0; return _xmltv_parse_tv(tv, stats); -} #endif + return 0; +} -/* ************************************************************************ - * Config - * ***********************************************************************/ - -#if 0 -static htsmsg_t *xmltv_grabber_list ( void ) +static void _xmltv_load_grabbers ( epggrab_module_list_t *list ) { size_t i, outlen, p, n; char *outbuf; char errbuf[100]; - htsmsg_t *e = NULL, *array; + epggrab_module_t *mod; /* Load data */ outlen = spawn_and_store_stdout(XMLTV_FIND_GRABBERS, NULL, &outbuf); if ( outlen < 1 ) { tvhlog(LOG_ERR, "xmltv", "%s failed [%s]", XMLTV_FIND_GRABBERS, errbuf); - return NULL; + return; } /* Process */ - array = htsmsg_create_list(); p = n = i = 0; while ( i < outlen ) { if ( outbuf[i] == '\n' || outbuf[i] == '\0' ) { outbuf[i] = '\0'; - e = htsmsg_create_map(); - htsmsg_add_str(e, "path", &outbuf[p]); - htsmsg_add_str(e, "name", &outbuf[n]); - htsmsg_add_msg(array, NULL, e); + mod = calloc(1, sizeof(epggrab_module_t)); + mod->id = mod->path = strdup(&outbuf[p]); + mod->name = malloc(200); + sprintf((char*)mod->name, "XMLTV: %s", &outbuf[n]); + mod->parse = _xmltv_parse; + 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; + LIST_INSERT_HEAD(list, mod, link); p = n = i + 1; } else if ( outbuf[i] == '|' ) { outbuf[i] = '\0'; @@ -422,54 +434,29 @@ static htsmsg_t *xmltv_grabber_list ( void ) i++; } free(outbuf); - - return array; } -#endif -#if TODO_XMLTV -/* ************************************************************************ - * Module Setup - * ***********************************************************************/ - -// TODO: config -// TODO: remove use of hardcoded xmltv script - -static epggrab_module_t xmltv_module; - -static const char* _xmltv_name ( void ) +void xmltv_init ( epggrab_module_list_t *list ) { - return "xmltv"; + epggrab_module_t *mod; + + /* Advanced module */ + mod = calloc(1, sizeof(epggrab_module_t)); + mod->id = strdup("xmltv"); + mod->name = strdup("XMLTV: Advanced"); + *((uint8_t*)&mod->flags) = EPGGRAB_MODULE_ASYNC + | EPGGRAB_MODULE_SYNC + | EPGGRAB_MODULE_ADVANCED; + mod->enable = epggrab_module_enable; + mod->grab = epggrab_module_grab; + mod->parse = _xmltv_parse; + mod->channels = &_xmltv_channels; + 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; + LIST_INSERT_HEAD(list, mod, link); + + /* Standard modules */ + _xmltv_load_grabbers(list); } - -static htsmsg_t* _xmltv_grab ( const char *iopts ) -{ - size_t outlen; - char *outbuf; - char errbuf[100]; - - /* Debug */ - tvhlog(LOG_DEBUG, "xmltv", "grab %s", cmd); - - /* Grab */ - outlen = spawn_and_store_stdout(cmd, NULL, &outbuf); - if ( outlen < 1 ) { - tvhlog(LOG_ERR, "xmltv", "no output detected"); - return NULL; - } - - /* Extract */ - return htsmsg_xml_deserialize(outbuf, errbuf, sizeof(errbuf)); -} - -epggrab_module_t* xmltv_init ( void ) -{ - xmltv_module.enable = NULL; - xmltv_module.disable = NULL; - xmltv_module.grab = _xmltv_grab; - xmltv_module.parse = _xmltv_parse; - xmltv_module.name = _xmltv_name; - return &xmltv_module; -} - -#endif