#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#include <assert.h>
#include "htsmsg.h"
#include "settings.h"
#include "tvheadend.h"
*/
void epggrab_init ( void )
{
+ epggrab_module_t *m;
+
/* Defaults */
epggrab_advanced = 0;
epggrab_eit = 1; // on air grab enabled
epggrab_module = NULL; // disabled
/* Initialise modules */
- LIST_INSERT_HEAD(&epggrab_modules, eit_init(), glink);
+ m = eit_init();
+ LIST_INSERT_HEAD(&epggrab_modules, m, glink);
#if TODO_XMLTV_SUPPORT
- LIST_INSERT_HEAD(&epggrab_modules, xmltv_init(), glink);
+ m = xmltv_init();
+ LIST_INSERT_HEAD(&epggrab_modules, m, glink);
#endif
- LIST_INSERT_HEAD(&epggrab_modules, pyepg_init(), glink);
+ m = pyepg_init();
+ LIST_INSERT_HEAD(&epggrab_modules, m, glink);
/* Start thread */
pthread_t tid;
}
}
+void epggrab_module_channels_load
+ ( const char *path, epggrab_channel_tree_t *tree )
+{
+ uint32_t chid;
+ htsmsg_t *m;
+ htsmsg_field_t *f;
+ epggrab_channel_t *ec;
+ channel_t *ch;
+
+ 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;
+ assert(RB_INSERT_SORTED(tree, ec, glink, _ch_id_cmp) == NULL);
+ }
+ }
+ }
+ }
+}
+
+void epggrab_module_channels_save
+ ( const char *path, epggrab_channel_tree_t *tree )
+{
+ epggrab_channel_t *c;
+ htsmsg_t *m = htsmsg_create_map();
+ RB_FOREACH(c, tree, glink) {
+ if (c->channel) htsmsg_add_u32(m, c->id, c->channel->ch_id);
+ }
+ hts_settings_save(m, path);
+}
+
epggrab_channel_t *epggrab_module_channel_create
- ( epggrab_channel_tree_t *tree, epggrab_channel_t *iskel )
+ ( epggrab_channel_tree_t *tree, epggrab_channel_t *iskel, int *save )
{
epggrab_channel_t *egc;
static epggrab_channel_t *skel = NULL;
skel->id = strdup(skel->id);
skel->name = strdup(skel->name);
skel->channel = _channel_find(skel);
+ if ( skel->channel ) *save |= 1;
egc = skel;
skel = NULL;
}
return RB_FIND(tree, &skel, glink, _ch_id_cmp);
}
-void epggrab_module_channel_add ( epggrab_channel_tree_t *tree, channel_t *ch )
+int epggrab_module_channel_add ( epggrab_channel_tree_t *tree, channel_t *ch )
{
+ int save = 0;
epggrab_channel_t *egc;
RB_FOREACH(egc, tree, glink) {
if (_channel_match(egc, ch) ) {
+ save = 1;
egc->channel = ch;
break;
}
}
+ return save;
}
-void epggrab_module_channel_rem ( epggrab_channel_tree_t *tree, channel_t *ch )
+int epggrab_module_channel_rem ( epggrab_channel_tree_t *tree, channel_t *ch )
{
+ int save = 0;
epggrab_channel_t *egc;
RB_FOREACH(egc, tree, glink) {
if (egc->channel == ch) {
+ save = 1;
egc->channel = NULL;
break;
}
}
+ return save;
}
-void epggrab_module_channel_mod ( epggrab_channel_tree_t *tree, channel_t *ch )
+int epggrab_module_channel_mod ( epggrab_channel_tree_t *tree, channel_t *ch )
{
- epggrab_module_channel_add(tree, ch);
+ return epggrab_module_channel_add(tree, ch);
}
/* **************************************************************************
/*
* Module specific channel handling
*/
-void epggrab_module_channel_add ( epggrab_channel_tree_t *tree, struct channel *ch );
-void epggrab_module_channel_rem ( epggrab_channel_tree_t *tree, struct channel *ch );
-void epggrab_module_channel_mod ( epggrab_channel_tree_t *tree, struct channel *ch );
+void epggrab_module_channels_load ( const char *path, epggrab_channel_tree_t *tree );
+void epggrab_module_channels_save ( const char *path, epggrab_channel_tree_t *tree );
+int epggrab_module_channel_add ( epggrab_channel_tree_t *tree, struct channel *ch );
+int epggrab_module_channel_rem ( epggrab_channel_tree_t *tree, struct channel *ch );
+int epggrab_module_channel_mod ( epggrab_channel_tree_t *tree, struct channel *ch );
-epggrab_channel_t *epggrab_module_channel_create ( epggrab_channel_tree_t *tree, epggrab_channel_t *ch );
+epggrab_channel_t *epggrab_module_channel_create ( epggrab_channel_tree_t *tree, epggrab_channel_t *ch, int *save );
epggrab_channel_t *epggrab_module_channel_find ( epggrab_channel_tree_t *tree, const char *id );
#endif /* __EPGGRAB_H__ */
#include "epggrab/pyepg.h"
#include "channels.h"
+epggrab_channel_tree_t _pyepg_channels;
+
+/* **************************************************************************
+ * Config/Load save
+ * *************************************************************************/
+
+static void _pyepg_load ( void )
+{
+ epggrab_module_channels_load("epggrab/pyepg/channels", &_pyepg_channels);
+}
+
+static void _pyepg_save ( void )
+{
+ epggrab_module_channels_save("epggrab/pyepg/channels", &_pyepg_channels);
+}
+
/* **************************************************************************
* Channels
* *************************************************************************/
-epggrab_channel_tree_t _pyepg_channels;
-static channel_t *_pyepg_channel_create ( epggrab_channel_t *skel )
+static channel_t *_pyepg_channel_create ( epggrab_channel_t *skel, int *save )
{
epggrab_channel_t *ch
- = epggrab_module_channel_create(&_pyepg_channels, skel);
+ = epggrab_module_channel_create(&_pyepg_channels, skel, save);
if (ch) return ch->channel;
return NULL;
}
static void _pyepg_channel_add ( channel_t *ch )
{
- epggrab_module_channel_add(&_pyepg_channels, ch);
+ if ( epggrab_module_channel_add(&_pyepg_channels, ch) )
+ _pyepg_save();
}
static void _pyepg_channel_rem ( channel_t *ch )
{
- epggrab_module_channel_rem(&_pyepg_channels, ch);
+ if ( epggrab_module_channel_rem(&_pyepg_channels, ch) )
+ _pyepg_save();
}
static void _pyepg_channel_mod ( channel_t *ch )
{
- epggrab_module_channel_mod(&_pyepg_channels, ch);
+ if ( epggrab_module_channel_mod(&_pyepg_channels, ch) )
+ _pyepg_save();
}
/* **************************************************************************
static int _pyepg_parse_channel ( htsmsg_t *data, epggrab_stats_t *stats )
{
- int save = 0;
+ int save = 0, save2 = 0;
htsmsg_t *attr, *tags;
const char *icon;
channel_t *ch;
skel.name = (char*)htsmsg_xml_get_cdata_str(tags, "name");
icon = htsmsg_xml_get_cdata_str(tags, "image");
- ch = _pyepg_channel_create(&skel);
+ ch = _pyepg_channel_create(&skel, &save2);
+ stats->channels.total++;
+ if (save2) {
+ stats->channels.created++;
+ save |= 1;
+ }
/* Update values */
if (ch) {
- // TODO: set the name
- //if (skel.name) save |= channel_rename(ch, skel.name);
+ 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;
}
static int _pyepg_parse_epg ( htsmsg_t *data, epggrab_stats_t *stats )
{
- int save = 0;
+ int save = 0, chsave = 0;
htsmsg_t *tags;
htsmsg_field_t *f;
HTSMSG_FOREACH(f, tags) {
if (strcmp(f->hmf_name, "channel") == 0 ) {
- save |= _pyepg_parse_channel(htsmsg_get_map_by_field(f), stats);
+ chsave |= _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);
}
}
+ save |= chsave;
+ if (chsave) _pyepg_save();
return save;
}
pyepg_module.ch_add = _pyepg_channel_add;
pyepg_module.ch_rem = _pyepg_channel_rem;
pyepg_module.ch_mod = _pyepg_channel_mod;
+ _pyepg_load();
return &pyepg_module;
}