*/
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);
((epggrab_channel_t*)b)->id);
}
-static int _ch_match ( epggrab_channel_t *ec, channel_t *ch )
-{
- // TODO: this needs implementing
- return 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;
-
- 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);
- }
- }
- }
- }
-}
-
-void epggrab_module_channels_save
- ( epggrab_module_t *mod, const char *path )
+// TODO: add other matches
+static int _ch_link ( epggrab_channel_t *ec, channel_t *ch )
{
- epggrab_channel_t *c;
- htsmsg_t *m = htsmsg_create_map();
+ int match = 0;
- RB_FOREACH(c, mod->channels, link) {
- if (c->channel) htsmsg_add_u32(m, c->id, c->channel->ch_id);
- }
- hts_settings_save(m, path);
-}
+ if (!ec || !ch) return 0;
+ if (ec->channel) return 0;
-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;
-}
+ if (ec->name && !strcmp(ec->name, ch->ch_name))
+ match = 1;
-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;
- }
+ 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);
}
- 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
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;
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);
}
/* **************************************************************************
{
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);
}
}
{
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);
}
}
{
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);
}
}
#include <pthread.h>
#include "channels.h"
+typedef struct epggrab_module epggrab_module_t;
+
/* **************************************************************************
* Grabber 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;
*/
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
*/
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 );
-
-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 );
+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_find
+ ( epggrab_module_t *mod, const char *id, int create, int *save );
/*
* Module list
#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);
}
/* **************************************************************************
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 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++;
}
- /* 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);
- }
- if (save) stats->channels.modified++;
-
return save;
}
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);
}
}
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;
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 ) {
save |= _pyepg_parse_schedule(htsmsg_get_map_by_field(f), stats);
}
}
-#if 0
- save |= chsave;
- if (chsave) pyepg_save();
-#endif
return save;
}
* 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 )
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;
}
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);
}
#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
* Note: converts to an ASCII format
* TODO: move somewhere else
*/
-#if 0
static const char *_xmltv_hash ( const char *str )
{
size_t i;
ret[MD5_DIGEST_LENGTH*2] = '\0';
return ret;
}
-#endif
/**
*
}
}
-#if 0
/**
* This is probably the most obscure formating there is. From xmltv.dtd:
*
}
}
-#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;
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?
return save | save2;
-#endif
- return 0;
}
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;
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;
}
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;
}
}
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)
return 0;
return _xmltv_parse_tv(tv, stats);
-#endif
- return 0;
}
static void _xmltv_load_grabbers ( 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;
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);
}