]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Yet more tidying up of the epggrab framework including epggrab channel save/load...
authorAdam Sutton <dev@adamsutton.me.uk>
Thu, 7 Jun 2012 20:46:51 +0000 (21:46 +0100)
committerAdam Sutton <dev@adamsutton.me.uk>
Mon, 30 Jul 2012 14:47:53 +0000 (15:47 +0100)
src/epggrab.c
src/epggrab.h
src/epggrab/pyepg.c
src/epggrab/xmltv.c

index 9b41dd41c1ea5fcf13d8eb8c7635d95b73766d42..9e269cb3fe0468d84945b7d55c05cd7957eac59f 100644 (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: 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
@@ -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);
   }
 }
 
index 41c7e005ee6aa4f42707838e1c12d6dda1cb66aa..93b0f86cf80d9030cddab4078e6ca97a18108bf6 100644 (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 );
-
-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
index bbb532c87560b7fbbc215a68924dfdf58ba50af9..1a52f2d9395733d9b4879d85880e56b95ff441bc 100644 (file)
 #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,38 +55,33 @@ 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 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;
 }
 
@@ -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);
 }
 
index 270707ab3b6315f84411049f4f4a0e10f34da99c..c60145dd11488bc5b803edeadbc0c76ea6fb2c1b 100644 (file)
 
 #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);
 }