]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
epggrab: add 'Only one auto channel' feature to EPG channel mapping
authorJaroslav Kysela <perex@perex.cz>
Mon, 26 Oct 2015 08:56:13 +0000 (09:56 +0100)
committerJaroslav Kysela <perex@perex.cz>
Mon, 26 Oct 2015 08:56:13 +0000 (09:56 +0100)
src/epggrab.h
src/epggrab/channel.c
src/epggrab/module/pyepg.c
src/epggrab/module/xmltv.c

index db91bb145a2758b6db071f7b7ceecbbc08ebc400..6e3ecdc3f6abbbe5fbb75dc4ef5d115aceee03de 100644 (file)
@@ -84,6 +84,7 @@ typedef struct epggrab_channel
   RB_ENTRY(epggrab_channel) link;     ///< Global tree link
   epggrab_module_t          *mod;     ///< Linked module
 
+  int                       updated;  ///< EPG channel was updated
   int                       enabled;  ///< Enabled/disabled
   char                      *id;      ///< Grabber's ID
 
@@ -94,6 +95,7 @@ typedef struct epggrab_channel
   char                      *comment; ///< Channel comment (EPG)
   int64_t                   lcn;      ///< Channel number (split)
 
+  int                       only_one; ///< Map to only one channel (auto)
   idnode_list_head_t        channels; ///< Mapped channels (1 = epggrab channel, 2 = channel)
 } epggrab_channel_t;
 
index feb892436750977d474faf94c42f7be1a1fa7815..3be798cc6839a33d5a9a8c767266a321e578fad6 100644 (file)
@@ -43,7 +43,7 @@ int epggrab_channel_match ( epggrab_channel_t *ec, channel_t *ch )
   htsmsg_field_t *f;
 
   if (!ec || !ch || !ch->ch_epgauto || !ch->ch_enabled || !ec->enabled) return 0;
-  if (LIST_FIRST(&ec->channels)) return 0; // ignore already paired
+  if (ec->only_one && LIST_FIRST(&ec->channels)) return 0; // ignore already paired
 
   chid = channel_get_epgid(ch);
   if (ec->name && !strcmp(ec->name, chid)) return 1;
@@ -150,6 +150,7 @@ int epggrab_channel_set_name ( epggrab_channel_t *ec, const char *name )
   if (ec->newnames == NULL)
     ec->newnames = htsmsg_create_list();
   htsmsg_add_str(ec->newnames, NULL, name);
+  ec->updated |= save;
   return save;
 }
 
@@ -172,6 +173,7 @@ int epggrab_channel_set_icon ( epggrab_channel_t *ec, const char *icon )
     }
     save = 1;
   }
+  ec->updated |= save;
   return save;
 }
 
@@ -197,6 +199,7 @@ int epggrab_channel_set_number ( epggrab_channel_t *ec, int major, int minor )
     }
     save = 1;
   }
+  ec->updated |= save;
   return save;
 }
 
@@ -207,7 +210,7 @@ void epggrab_channel_updated ( epggrab_channel_t *ec )
   if (!ec) return;
 
   /* Find a link */
-  if (!LIST_FIRST(&ec->channels))
+  if (!ec->only_one || !LIST_FIRST(&ec->channels))
     CHANNEL_FOREACH(ch)
       if (epggrab_channel_match_and_link(ec, ch)) break;
 
@@ -336,23 +339,35 @@ void epggrab_channel_begin_scan ( epggrab_module_t *mod )
 {
   epggrab_channel_t *ec;
   lock_assert(&global_lock);
-  RB_FOREACH(ec, &mod->channels, link)
+  RB_FOREACH(ec, &mod->channels, link) {
+    ec->updated = 0;
     if (ec->newnames) {
       htsmsg_destroy(ec->newnames);
       ec->newnames = NULL;
     }
+  }
 }
 
 void epggrab_channel_end_scan ( epggrab_module_t *mod )
 {
   epggrab_channel_t *ec;
   lock_assert(&global_lock);
-  RB_FOREACH(ec, &mod->channels, link)
+  RB_FOREACH(ec, &mod->channels, link) {
     if (ec->newnames) {
-      htsmsg_destroy(ec->names);
-      ec->names = ec->newnames;
+      if (htsmsg_cmp(ec->names, ec->newnames)) {
+        htsmsg_destroy(ec->names);
+        ec->names = ec->newnames;
+        ec->updated = 1;
+      } else {
+        htsmsg_destroy(ec->newnames);
+      }
       ec->newnames = NULL;
     }
+    if (ec->updated) {
+      epggrab_channel_updated(ec);
+      ec->updated = 0;
+    }
+  }
 }
 
 /* **************************************************************************
@@ -518,6 +533,25 @@ epggrab_channel_class_channels_rend ( void *obj, const char *lang )
   return idnode_list_get_csv1(&ec->channels, lang);
 }
 
+static void
+epggrab_channel_class_only_one_notify ( void *obj, const char *lang )
+{
+  epggrab_channel_t *ec = obj;
+  channel_t *ch, *first = NULL;
+  idnode_list_mapping_t *ilm1, *ilm2;
+  if (ec->only_one) {
+    for(ilm1 = LIST_FIRST(&ec->channels); ilm1; ilm1 = ilm2) {
+      ilm2 = LIST_NEXT(ilm1, ilm_in2_link);
+      ch = (channel_t *)ilm1->ilm_in2;
+      if (!first)
+        ch = first;
+      else if (ch->ch_epgauto && first)
+        idnode_list_unlink(ilm1, ec);
+    }
+  } else {
+    epggrab_channel_updated(ec);
+  }
+}
 
 const idclass_t epggrab_channel_class = {
   .ic_class      = "epggrab_channel",
@@ -598,6 +632,13 @@ const idclass_t epggrab_channel_class = {
       .list     = channel_class_get_list,
       .rend     = epggrab_channel_class_channels_rend,
     },
+    {
+      .type     = PT_BOOL,
+      .id       = "only_one",
+      .name     = N_("Only one auto channel"),
+      .off      = offsetof(epggrab_channel_t, only_one),
+      .notify   = epggrab_channel_class_only_one_notify,
+    },
     {
       .type     = PT_STR,
       .id       = "comment",
index a606a1aedf6d1b2fa6a430931b1a1d8e72d9a510..c4bfd93f92f05fd0406587594c0076dc95839602 100644 (file)
@@ -87,10 +87,8 @@ static int _pyepg_parse_channel
     save |= epggrab_channel_set_number(ch, u32, 0);
   
   /* Update */
-  if (save) {
-    epggrab_channel_updated(ch);
+  if (save)
     stats->channels.modified++;
-  }
 
   return save;
 }
index f8b00f7cd36a0b9091496f9195ad0cd344a69a59..43412071a469276040ec407a80f50044e4216f9b 100644 (file)
@@ -580,7 +580,6 @@ static int _xmltv_parse_programme
   if((chid    = htsmsg_get_str(attribs, "channel")) == NULL) return 0;
   if((ec      = epggrab_channel_find(mod, chid, 1, &chsave)) == NULL) return 0;
   if (chsave) {
-    epggrab_channel_updated(ec);
     stats->channels.created++;
     stats->channels.modified++;
   }
@@ -631,10 +630,8 @@ static int _xmltv_parse_channel
      (icon    = htsmsg_get_str(attribs, "src"))    != NULL) {
     save |= epggrab_channel_set_icon(ch, icon);
   }
-  if (save) {
-    epggrab_channel_updated(ch);
+  if (save)
     stats->channels.modified++;
-  }
   return save;
 }