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:
parent
0d34b48c05
commit
b85ca93e5d
4 changed files with 289 additions and 211 deletions
295
src/epggrab.c
295
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue