]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
IPTV: autonet - add contents charset specification
authorJaroslav Kysela <perex@perex.cz>
Thu, 15 Oct 2015 15:24:14 +0000 (17:24 +0200)
committerJaroslav Kysela <perex@perex.cz>
Thu, 15 Oct 2015 15:24:14 +0000 (17:24 +0200)
src/input/mpegts/iptv/iptv.c
src/input/mpegts/iptv/iptv_auto.c
src/input/mpegts/iptv/iptv_private.h
src/intlconv.c
src/intlconv.h

index 0c17ce8cf82b6881245119accc14c6af1f7898a6..7de7bbcc25cebbf999df97a95461e3deb9fea44c 100644 (file)
@@ -495,6 +495,7 @@ iptv_network_delete ( mpegts_network_t *mn, int delconf )
 
   /* delete */
   free(in->in_remove_args);
+  free(in->in_ctx_charset);
   mpegts_network_delete(mn, delconf);
 
   free(icon_url_sane);
@@ -589,6 +590,15 @@ iptv_auto_network_class_notify_url( void *in, const char *lang )
   iptv_auto_network_trigger(in);
 }
 
+static htsmsg_t *
+iptv_auto_network_class_charset_list(void *o, const char *lang)
+{
+  htsmsg_t *m = htsmsg_create_map();
+  htsmsg_add_str(m, "type",  "api");
+  htsmsg_add_str(m, "uri",   "intlconv/charsets");
+  return m;
+}
+
 const idclass_t iptv_auto_network_class = {
   .ic_super      = &iptv_network_class,
   .ic_class      = "iptv_auto_network",
@@ -603,6 +613,14 @@ const idclass_t iptv_auto_network_class = {
       .notify   = iptv_auto_network_class_notify_url,
       .opts     = PO_MULTILINE
     },
+    {
+      .type     = PT_STR,
+      .id       = "ctx_charset",
+      .name     = N_("Contents character set"),
+      .off      = offsetof(iptv_network_t, in_ctx_charset),
+      .list     = iptv_auto_network_class_charset_list,
+      .notify   = iptv_auto_network_class_notify_url,
+    },
     {
       .type     = PT_S64,
       .intsplit = CHANNEL_SPLIT,
index 14bdeb703f1aba437d6a3d4548b1b8f7e89c30b7..85008f57be502f528db9b63f288364fcffea43a1 100644 (file)
@@ -22,6 +22,7 @@
 #include "iptv_private.h"
 #include "channels.h"
 #include "download.h"
+#include "intlconv.h"
 
 #include <fcntl.h>
 #include <sys/stat.h>
@@ -66,12 +67,32 @@ static char *until_eol(char *d)
   return d;
 }
 
+/*
+ *
+ */
+static int replace_string(char **s, const char *n, const char *charset_id)
+{
+  char *c;
+
+  if (charset_id && n) {
+    c = intlconv_to_utf8safestr(charset_id, n, strlen(n)*2);
+  } else
+    c = n ? strdup(n) : NULL;
+  if (strcmp(*s ?: "", n ?: "") == 0) {
+    free(c);
+    return 0;
+  }
+  free(*s);
+  *s = c;
+  return 1;
+}
+
 /*
  *
  */
 static void
 iptv_auto_network_process_m3u_item(iptv_network_t *in,
-                                   const char *last_url,
+                                   const char *last_url, const char *charset_id,
                                    const http_arg_list_t *remove_args,
                                    const char *url, const char *name,
                                    const char *logo, const char *epgid,
@@ -86,7 +107,7 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in,
   http_arg_t *ra1, *ra2, *ra2_next;
   htsbuf_queue_t q;
   size_t l = 0;
-  char url2[512], name2[128], *n;
+  char url2[512], name2[128], *n, *x = NULL;
 
   if (url == NULL ||
       (strncmp(url, "file://", 7) &&
@@ -150,6 +171,10 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in,
   }
 
   if (last_url) {
+    if (charset_id) {
+      x = intlconv_to_utf8safestr(charset_id, name, strlen(name)*2);
+      name = x;
+    }
     snprintf(n = name2, sizeof(name2), "%s - %s", last_url, name);
   } else {
     n = (char *)name;
@@ -161,7 +186,7 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in,
       im->im_delete_flag = 0;
       if (strcmp(im->mm_iptv_svcname ?: "", name ?: "")) {
         free(im->mm_iptv_svcname);
-        im->mm_iptv_svcname = name ? strdup(name) : NULL;
+        im->mm_iptv_svcname = strdup(name);
         change = 1;
       }
       if (im->mm_iptv_chnum != chnum) {
@@ -178,11 +203,7 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in,
         im->mm_iptv_icon = logo ? strdup(logo) : NULL;
         change = 1;
       }
-      if (strcmp(im->mm_iptv_epgid ?: "", epgid ?: "")) {
-        free(im->mm_iptv_epgid);
-        im->mm_iptv_epgid = epgid ? strdup(epgid) : NULL;
-        change = 1;
-      }
+      change |= replace_string(&im->mm_iptv_epgid, epgid, charset_id);
       if (change)
         idnode_notify_changed(&im->mm_id);
       (*total)++;
@@ -205,6 +226,7 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in,
   }
 
 end:
+  free(x);
   urlreset(&u);
 }
 
@@ -218,6 +240,7 @@ iptv_auto_network_process_m3u(iptv_network_t *in, char *data,
                               int64_t chnum)
 {
   char *url, *name = NULL, *logo = NULL, *epgid = NULL;
+  char *charset_id = intlconv_charset_id(in->in_ctx_charset, 0, 1);
   int total = 0, count = 0;
 
   while (*data && *data != '\n') data++;
@@ -263,8 +286,9 @@ iptv_auto_network_process_m3u(iptv_network_t *in, char *data,
     url = data;
     data = until_eol(data);
     if (*url && *url > ' ')
-      iptv_auto_network_process_m3u_item(in, last_url, remove_args,
-                                         url, name, logo, epgid,
+      iptv_auto_network_process_m3u_item(in, last_url, charset_id,
+                                         remove_args, url, name,
+                                         logo, epgid,
                                          chnum, &total, &count);
   }
 
@@ -317,7 +341,8 @@ iptv_auto_network_process(void *aux, const char *last_url, char *data, size_t le
         mm->mm_delete(mm, 1);
         count++;
       }
-    tvhinfo("iptv", "removed %d mux(es) from network '%s'", count, in->mn_network_name);
+    if (count > 0)
+      tvhinfo("iptv", "removed %d mux(es) from network '%s'", count, in->mn_network_name);
   } else {
     LIST_FOREACH(mm, &in->mn_muxes, mm_network_link)
       ((iptv_mux_t *)mm)->im_delete_flag = 0;
index f1273480975505c8fb44b0140067cf062d5a30d7..2714a9f224be14195be351ed0f562e07e6f37550 100644 (file)
@@ -81,6 +81,7 @@ struct iptv_network
 
   char    *in_url;
   char    *in_url_sane;
+  char    *in_ctx_charset;
   int64_t  in_channel_number;
   uint32_t in_refetch_period;
   char    *in_icon_url;
index 0856ab7ed58852cf8162481e4b767ad30443cf5c..ec0fbae25a19a54b6ef26fc838c4cfe85373dc1a 100644 (file)
@@ -250,6 +250,27 @@ found:
   return res;
 }
 
+char *
+intlconv_to_utf8safestr( const char *src_charset_id,
+                         const char *src_str,
+                         size_t max_size )
+{
+  char *str;
+  ssize_t r;
+
+  if (max_size == 0 || *src_str == '\0')
+    return strdup("");
+
+  str = alloca(max_size);
+  r = intlconv_to_utf8(str, max_size, src_charset_id, src_str, strlen(src_str));
+  if (r <= 0)
+    return NULL;
+  if (r >= max_size)
+    r--;
+  str[r++] = '\0';
+  return strdup(str);
+}
+
 /*
  *
  */
index 53decb7105cbbb5c6a12cd1aac1bbfb3365be8ef..f28781eb059c8efa545a4c82e3fa00b2c087e36e 100644 (file)
@@ -43,4 +43,9 @@ intlconv_to_utf8( char *dst, size_t dst_size,
                   const char *src_charset_id,
                   const char *src, size_t src_size );
 
+char *
+intlconv_to_utf8safestr( const char *src_charset_id,
+                         const char *src_str,
+                         size_t max_size );
+
 #endif /* INTLCONV_H_ */