Some further updates (simplfications) to the epggrab framework.
This commit is contained in:
parent
73286da38a
commit
e5e7bc853c
5 changed files with 111 additions and 153 deletions
|
@ -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;
|
epggrab_channel_t *c;
|
||||||
htsmsg_t *m = htsmsg_create_map();
|
htsmsg_t *m = htsmsg_create_map();
|
||||||
|
|
||||||
sprintf(path, "epggrab/%s/channels", mod->id);
|
|
||||||
RB_FOREACH(c, mod->channels, link) {
|
RB_FOREACH(c, mod->channels, link) {
|
||||||
if (c->channel) htsmsg_add_u32(m, c->id, c->channel->ch_id);
|
if (c->channel) htsmsg_add_u32(m, c->id, c->channel->ch_id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,14 @@ typedef struct epggrab_channel_tree epggrab_channel_tree_t;
|
||||||
|
|
||||||
typedef struct epggrab_module epggrab_module_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
|
* Grabber base class
|
||||||
*/
|
*/
|
||||||
|
@ -64,8 +72,7 @@ struct epggrab_module
|
||||||
const char *id; ///< Module identifier
|
const char *id; ///< Module identifier
|
||||||
const char *name; ///< Module name (for display)
|
const char *name; ///< Module name (for display)
|
||||||
const char *path; ///< Module path (for fixed config)
|
const char *path; ///< Module path (for fixed config)
|
||||||
const uint8_t simple; ///< Include in simple list
|
const uint8_t flags; ///< Mode flags
|
||||||
const uint8_t async; ///< Asynchronous (not schedulable)
|
|
||||||
epggrab_channel_tree_t *channels; ///< Channel list
|
epggrab_channel_tree_t *channels; ///< Channel list
|
||||||
|
|
||||||
/* Enable/Disable for async */
|
/* 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_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_add ( epggrab_module_t *m, channel_t *ch );
|
||||||
int epggrab_module_channel_rem ( 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 );
|
int epggrab_module_channel_mod ( epggrab_module_t *m, channel_t *ch );
|
||||||
|
|
|
@ -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 )
|
void eit_init ( epggrab_module_list_t *list )
|
||||||
{
|
{
|
||||||
_eit_mod.id = strdup("eit");
|
_eit_mod.id = strdup("eit");
|
||||||
_eit_mod.name = strdup("EIT On-Air Grabber");
|
_eit_mod.name = strdup("EIT: On-Air Grabber");
|
||||||
*((uint8_t*)&_eit_mod.async) = 1;
|
*((uint8_t*)&_eit_mod.flags) = EPGGRAB_MODULE_ASYNC;
|
||||||
|
_eit_mod.enable = _eit_enable;
|
||||||
LIST_INSERT_HEAD(list, &_eit_mod, link);
|
LIST_INSERT_HEAD(list, &_eit_mod, link);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,6 @@
|
||||||
#include "epggrab/pyepg.h"
|
#include "epggrab/pyepg.h"
|
||||||
#include "channels.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 )
|
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;
|
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
|
static int _pyepg_parse
|
||||||
( epggrab_module_t *mod, htsmsg_t *data, epggrab_stats_t *stats )
|
( epggrab_module_t *mod, htsmsg_t *data, epggrab_stats_t *stats )
|
||||||
{
|
{
|
||||||
|
@ -384,83 +394,24 @@ static int _pyepg_parse
|
||||||
return 0;
|
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 )
|
void pyepg_init ( epggrab_module_list_t *list )
|
||||||
{
|
{
|
||||||
/* Common routines */
|
_pyepg_module.id = strdup("pyepg_sync");
|
||||||
_pyepg_sync.channels = _pyepg_async.channels = &_pyepg_channels;
|
_pyepg_module.path = strdup("/usr/bin/pyepg");
|
||||||
_pyepg_sync.ch_save = _pyepg_async.ch_save = epggrab_module_channels_save;
|
*((uint8_t*)&_pyepg_module.flags) = EPGGRAB_MODULE_SYNC
|
||||||
_pyepg_sync.ch_add = _pyepg_async.ch_add = epggrab_module_channel_add;
|
| EPGGRAB_MODULE_ASYNC
|
||||||
_pyepg_sync.ch_rem = _pyepg_async.ch_rem = epggrab_module_channel_rem;
|
| EPGGRAB_MODULE_ADVANCED
|
||||||
_pyepg_sync.ch_mod = _pyepg_async.ch_mod = epggrab_module_channel_mod;
|
| EPGGRAB_MODULE_SIMPLE;
|
||||||
_pyepg_sync.name = _pyepg_async.name = strdup("PyEPG");
|
_pyepg_module.enable = epggrab_module_enable;
|
||||||
|
_pyepg_module.grab = epggrab_module_grab;
|
||||||
/* Sync */
|
_pyepg_module.parse = _pyepg_parse;
|
||||||
_pyepg_sync.id = strdup("pyepg_sync");
|
_pyepg_module.channels = &_pyepg_channels;
|
||||||
_pyepg_sync.path = strdup("/usr/bin/pyepg");
|
_pyepg_module.ch_save = _pyepg_save;
|
||||||
_pyepg_sync.grab = _pyepg_grab;
|
_pyepg_module.ch_add = epggrab_module_channel_add;
|
||||||
_pyepg_sync.parse = _pyepg_parse;
|
_pyepg_module.ch_rem = epggrab_module_channel_rem;
|
||||||
|
_pyepg_module.ch_mod = epggrab_module_channel_mod;
|
||||||
/* Async */
|
|
||||||
_pyepg_async.id = strdup("pyepg_async");
|
|
||||||
_pyepg_async.enable = _pyepg_enable;
|
|
||||||
*((uint8_t*)&_pyepg_async.async) = 1;
|
|
||||||
|
|
||||||
/* Add to list */
|
/* Add to list */
|
||||||
LIST_INSERT_HEAD(list, &_pyepg_sync, link);
|
LIST_INSERT_HEAD(list, &_pyepg_module, link);
|
||||||
LIST_INSERT_HEAD(list, &_pyepg_async, link);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -367,12 +367,23 @@ _xmltv_parse_tv(htsmsg_t *body, epggrab_stats_t *stats)
|
||||||
}
|
}
|
||||||
return save;
|
return save;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/* ************************************************************************
|
||||||
*
|
* Module Setup
|
||||||
*/
|
* ***********************************************************************/
|
||||||
static int _xmltv_parse ( htsmsg_t *data, epggrab_stats_t *stats )
|
|
||||||
|
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;
|
htsmsg_t *tags, *tv;
|
||||||
|
|
||||||
if((tags = htsmsg_get_map(data, "tags")) == NULL)
|
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 0;
|
||||||
|
|
||||||
return _xmltv_parse_tv(tv, stats);
|
return _xmltv_parse_tv(tv, stats);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* ************************************************************************
|
static void _xmltv_load_grabbers ( epggrab_module_list_t *list )
|
||||||
* Config
|
|
||||||
* ***********************************************************************/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static htsmsg_t *xmltv_grabber_list ( void )
|
|
||||||
{
|
{
|
||||||
size_t i, outlen, p, n;
|
size_t i, outlen, p, n;
|
||||||
char *outbuf;
|
char *outbuf;
|
||||||
char errbuf[100];
|
char errbuf[100];
|
||||||
htsmsg_t *e = NULL, *array;
|
epggrab_module_t *mod;
|
||||||
|
|
||||||
/* Load data */
|
/* Load data */
|
||||||
outlen = spawn_and_store_stdout(XMLTV_FIND_GRABBERS, NULL, &outbuf);
|
outlen = spawn_and_store_stdout(XMLTV_FIND_GRABBERS, NULL, &outbuf);
|
||||||
if ( outlen < 1 ) {
|
if ( outlen < 1 ) {
|
||||||
tvhlog(LOG_ERR, "xmltv", "%s failed [%s]", XMLTV_FIND_GRABBERS, errbuf);
|
tvhlog(LOG_ERR, "xmltv", "%s failed [%s]", XMLTV_FIND_GRABBERS, errbuf);
|
||||||
return NULL;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process */
|
/* Process */
|
||||||
array = htsmsg_create_list();
|
|
||||||
p = n = i = 0;
|
p = n = i = 0;
|
||||||
while ( i < outlen ) {
|
while ( i < outlen ) {
|
||||||
if ( outbuf[i] == '\n' || outbuf[i] == '\0' ) {
|
if ( outbuf[i] == '\n' || outbuf[i] == '\0' ) {
|
||||||
outbuf[i] = '\0';
|
outbuf[i] = '\0';
|
||||||
e = htsmsg_create_map();
|
mod = calloc(1, sizeof(epggrab_module_t));
|
||||||
htsmsg_add_str(e, "path", &outbuf[p]);
|
mod->id = mod->path = strdup(&outbuf[p]);
|
||||||
htsmsg_add_str(e, "name", &outbuf[n]);
|
mod->name = malloc(200);
|
||||||
htsmsg_add_msg(array, NULL, e);
|
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;
|
p = n = i + 1;
|
||||||
} else if ( outbuf[i] == '|' ) {
|
} else if ( outbuf[i] == '|' ) {
|
||||||
outbuf[i] = '\0';
|
outbuf[i] = '\0';
|
||||||
|
@ -422,54 +434,29 @@ static htsmsg_t *xmltv_grabber_list ( void )
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
free(outbuf);
|
free(outbuf);
|
||||||
|
|
||||||
return array;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if TODO_XMLTV
|
void xmltv_init ( epggrab_module_list_t *list )
|
||||||
/* ************************************************************************
|
|
||||||
* Module Setup
|
|
||||||
* ***********************************************************************/
|
|
||||||
|
|
||||||
// TODO: config
|
|
||||||
// TODO: remove use of hardcoded xmltv script
|
|
||||||
|
|
||||||
static epggrab_module_t xmltv_module;
|
|
||||||
|
|
||||||
static const char* _xmltv_name ( void )
|
|
||||||
{
|
{
|
||||||
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
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue