]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
channel: Allow HD/UHD suffix on channels to be stripped. (#4715)
authorE.Smith <31170571+azlm8t@users.noreply.github.com>
Wed, 15 Nov 2017 23:42:10 +0000 (23:42 +0000)
committerJaroslav Kysela <perex@perex.cz>
Thu, 16 Nov 2017 13:53:06 +0000 (14:53 +0100)
Issue: #4715.

src/bouquet.c
src/bouquet.h
src/service_mapper.c
src/service_mapper.h

index b4ed69e6b6402efca422fddcd1aa41f86bb27bb4..53d397c18c9cb6d83c8c1be0b7ae52c1d8c4923b 100644 (file)
@@ -292,6 +292,7 @@ bouquet_map_channel(bouquet_t *bq, service_t *t)
     .encrypted          = 1,
     .merge_same_name    = 0,
     .merge_same_name_fuzzy = 0,
+    .tidy_channel_name  = 0,
     .type_tags          = 0,
     .provider_tags      = 0,
     .network_tags       = 0
@@ -315,6 +316,7 @@ bouquet_map_channel(bouquet_t *bq, service_t *t)
     sm_conf.encrypted = bq->bq_mapencrypted;
     sm_conf.merge_same_name = bq->bq_mapmergename;
     sm_conf.merge_same_name_fuzzy = bq->bq_mapmergefuzzy;
+    sm_conf.tidy_channel_name = bq->bq_tidychannelname;
     sm_conf.type_tags = bq->bq_chtag_type_tags;
     sm_conf.provider_tags = bq->bq_chtag_provider_tags;
     sm_conf.network_tags = bq->bq_chtag_network_tags;
@@ -755,6 +757,11 @@ static idnode_slist_t bouquest_class_mapopt_slist[] = {
     .name = N_("Use fuzzy mapping if merging same name"),
     .off  = offsetof(bouquet_t, bq_mapmergefuzzy),
   },
+  {
+    .id   = "tidy_channel_name",
+    .name = N_("Tidy channel name (e.g., stripping HD/UHD suffix)"),
+    .off  = offsetof(bouquet_t, bq_tidychannelname),
+  },
   {}
 };
 
index d8c0e517ad3507f7810b84b9124c4c64cff4a242..ceba6ec3d044f7dfd5e047a7018a33288dec66d3 100644 (file)
@@ -41,6 +41,7 @@ typedef struct bouquet {
   int           bq_mapencrypted;
   int           bq_mapmergename;
   int           bq_mapmergefuzzy;
+  int           bq_tidychannelname;
   int           bq_chtag;
   int           bq_chtag_type_tags;
   int           bq_chtag_provider_tags;
index 4d30dc6836571c9fd04c957c0f09f2fb40f61e69..97abf336644f08deeea41578a8d48aee2ac6aeaf 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <assert.h>
+#include <ctype.h>
 #include <pthread.h>
 #include <stdio.h>
 #include <unistd.h>
@@ -206,6 +207,7 @@ service_mapper_process
 {
   channel_t *chn = NULL;
   const char *name, *tagname;
+  char *tidy_name = NULL;
   htsmsg_field_t *f;
   htsmsg_t *m;
 
@@ -224,6 +226,40 @@ service_mapper_process
 
   /* Find existing channel */
   name = service_get_channel_name(s);
+
+  if (conf->tidy_channel_name && name) {
+    size_t len = strlen(name);
+    if (len > 2) {
+      // E.g.,
+      // 012345
+      // 5 UHD\0 len=5, UHD at pos 2 (5-3)
+      // 5 HD\0  len=4,  HD at pos 2 (4-2)
+      // 4HD\0   len=3,  HD at pos 1 (3-2)
+      // 4\0     len=1
+      if (name[len-2] == 'H' && name[len-1] == 'D') {
+        /* Ends in HD but does it end in UHD? */
+        tidy_name = tvh_strdupa(name);
+        if (len > 3 && name[len-3] == 'U')
+          tidy_name[len-3] = 0;
+        else
+          tidy_name[len-2] = 0;
+        len = strlen(tidy_name);
+        /* Strip any trailing space such as '5 HD' should become
+         * '5'  not '5 '.
+         */
+        if (len && isspace(tidy_name[len-1]))
+          tidy_name[len-1] = 0;
+
+        tvhdebug(bq ? LS_BOUQUET : LS_SERVICE_MAPPER,
+                 "%s: generated tidy_name [%s] from [%s]",
+                 s->s_nicename, tidy_name, name);
+
+        /* Assign tidy_name so we use it for rest of function */
+        name = tidy_name;
+      }
+    }
+  }
+
   if (conf->merge_same_name && name && *name) {
     /* Try exact match first */
     chn = channel_find_by_name_and_bouquet(name, bq);
@@ -250,6 +286,22 @@ service_mapper_process
     const char *prov;
     service_mapper_link(s, chn, chn);
 
+    /* We have to set tidy name here (not in channel_create) because
+     * the service_mapper_link alters the detected channel name when
+     * we merge a channel. So, on the initial create the
+     * channel_create could be given a channel name (such as mapping
+     * "5 HD" to "5") and a subsequent merge of "5" would be ok since
+     * we wanted HD stripped. But if the order were reversed and we
+     * found "5" first and then "5 HD" then we don't channel_create
+     * for "5 HD" and the service_mapper_link then uses "5 HD" as the
+     * name.
+     *
+     * We only set the name if we explicitly have a tidy name.
+     * Otherwise we let channel use the defaults.
+     */
+    if (tidy_name && *tidy_name)
+      channel_set_name(chn, tidy_name);
+
     /* Type tags */
     if (conf->type_tags) {
       if (service_is_uhdtv(s)) {
@@ -555,6 +607,17 @@ static const idclass_t service_mapper_conf_class = {
                    "depends on the order the channels are mapped."),
       .off    = offsetof(service_mapper_t, d.merge_same_name_fuzzy),
     },
+    {
+      .type   = PT_BOOL,
+      .id     = "tidy_channel_name",
+      .name   = N_("Tidy the channel name such as removing trailing HD text"),
+      .desc   = N_("Some broadcasters distinguish channels by appending "
+                   "descriptors such as 'HD'. This option strips those "
+                   "so 'Channel 4 HD' would be named 'Channel 4'. "
+                   "Note that xmltv settings may try and match by channel name "
+                   "so changing a channel name may require manual xmltv mapping."),
+      .off    = offsetof(service_mapper_t, d.tidy_channel_name),
+    },
     {
       .type   = PT_BOOL,
       .id     = "type_tags",
index f205e66a4bdd2e75488383b4383ac36f28e2add4..64166253b8c76916feb23b6ffbee64e13ba67e48 100644 (file)
@@ -27,6 +27,7 @@ typedef struct service_mapper_conf
   int encrypted;          ///< Include encrypted services
   int merge_same_name;    ///< Merge entries with the same name
   int merge_same_name_fuzzy;    ///< Merge entries with the same name with fuzzy matching (ignore case, etc)
+  int tidy_channel_name;  ///< Tidy channel name by removing trailing HD/UHD.
   int type_tags;          ///< Create tags based on the service type (SDTV/HDTV/Radio)
   int provider_tags;      ///< Create tags based on provider name
   int network_tags;       ///< Create tags based on network name (useful for multi adapter equipments)