Yet more tidying up of the epggrab framework including epggrab channel save/load. Definitely think I am getting somewhere now.

This commit is contained in:
Adam Sutton 2012-06-07 21:46:51 +01:00
parent 0d34b48c05
commit b85ca93e5d
4 changed files with 289 additions and 211 deletions

View file

@ -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);
}
}

View file

@ -4,6 +4,8 @@
#include <pthread.h>
#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

View file

@ -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);
}

View file

@ -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);
}