]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
ACL/all: handle the per user language settings for all operations
authorJaroslav Kysela <perex@perex.cz>
Mon, 29 Jun 2015 13:04:47 +0000 (15:04 +0200)
committerJaroslav Kysela <perex@perex.cz>
Mon, 29 Jun 2015 13:04:47 +0000 (15:04 +0200)
src/access.c
src/access.h
src/api/api_dvr.c
src/api/api_epg.c
src/dvr/dvr_db.c
src/htsp_server.c
src/lang_codes.c
src/lang_codes.h
src/tvh_locale.c
src/webui/extjs.c

index 084c1d3e37912492fc72a44eda3da3d4a1c659a5..f2e7f720098a5f280f87cf7b94236c0b813bff94 100644 (file)
@@ -39,6 +39,7 @@
 #include "channels.h"
 #include "dvr/dvr.h"
 #include "tcp.h"
+#include "lang_codes.h"
 
 struct access_entry_queue access_entries;
 struct access_ticket_queue access_tickets;
@@ -225,6 +226,21 @@ access_copy(access_t *src)
   return dst;
 }
 
+/**
+ *
+ */
+char *
+access_get_lang(access_t *a, const char *lang)
+{
+  if (lang == NULL) {
+    if (a->aa_lang == NULL)
+      return NULL;
+    return strdup(a->aa_lang);
+  } else {
+    return lang_code_user(lang);
+  }
+}
+
 /**
  *
  */
@@ -531,7 +547,7 @@ access_update(access_t *a, access_entry_t *ae)
   }
 
   if (!a->aa_lang && ae->ae_lang)
-    a->aa_lang = strdup(ae->ae_lang);
+    a->aa_lang = lang_code_user(ae->ae_lang);
 
   a->aa_rights |= ae->ae_rights;
 }
index 036be1ea9d69f3a9690d2a9b2d38329338651208..a6269d3159b064b965955cd547a18780d1fe9938 100644 (file)
@@ -187,6 +187,12 @@ void access_destroy(access_t *a);
  */
 access_t *access_copy(access_t *src);
 
+/**
+ *
+ */
+char *
+access_get_lang(access_t *a, const char *lang);
+
 /**
  * Verifies that the given user in combination with the source ip
  * complies with the requested mask
index d549f86f0de3d43484cd04c798c0c53931bade9b..ab9a5a91648770683700ed60e18c9f5431699f00 100644 (file)
@@ -132,7 +132,8 @@ api_dvr_entry_create
 {
   dvr_entry_t *de;
   dvr_config_t *cfg;
-  htsmsg_t *conf;
+  htsmsg_t *conf, *m;
+  char *s, *lang;
   const char *s1;
   int res = EPERM;
 
@@ -147,10 +148,31 @@ api_dvr_entry_create
     htsmsg_set_str(conf, "owner", perm->aa_username ?: "");
     htsmsg_set_str(conf, "creator", perm->aa_representative ?: "");
 
+    lang = access_get_lang(perm, htsmsg_get_str(conf, "lang"));
+    if (lang) {
+      for (s = lang; *s && *s != ','; s++);
+      *s = '\0';
+    }
+
+    s1 = htsmsg_get_str(conf, "disp_title");
+    if (s1 && !htsmsg_get_map(conf, "title")) {
+      m = htsmsg_create_map();
+      htsmsg_add_str(m, lang, s1);
+      htsmsg_add_msg(conf, "title", m);
+    }
+
+    s1 = htsmsg_get_str(conf, "disp_subtitle");
+    if (s1 && !htsmsg_get_map(conf, "subtitle")) {
+      m = htsmsg_create_map();
+      htsmsg_add_str(m, lang, s1);
+      htsmsg_add_msg(conf, "subtitle", m);
+    }
+
     if ((de = dvr_entry_create(NULL, conf)))
       dvr_entry_save(de);
 
     res = 0;
+    free(lang);
   }
   pthread_mutex_unlock(&global_lock);
 
index 117ab9d5b537795e08e52f99861c6bda84c4e344..d14e16e61d4620a0c1db28d630a007e2e693d13d 100644 (file)
@@ -24,6 +24,7 @@
 #include "epg.h"
 #include "imagecache.h"
 #include "dvr/dvr.h"
+#include "lang_codes.h"
 
 static htsmsg_t *
 api_epg_get_list ( const char *s )
@@ -280,7 +281,8 @@ api_epg_grid
 {
   int i;
   epg_query_t eq;
-  const char *lang, *str;
+  const char *str;
+  char *lang;
   uint32_t start, limit, end, genre;
   int64_t duration_min, duration_max;
   htsmsg_field_t *f, *f2;
@@ -288,9 +290,7 @@ api_epg_grid
 
   memset(&eq, 0, sizeof(eq));
 
-  lang = htsmsg_get_str(args, "lang");
-  if (lang)
-    eq.lang = strdup(lang);
+  eq.lang = lang = access_get_lang(perm, htsmsg_get_str(args, "lang"));
   str = htsmsg_get_str(args, "title");
   if (str)
     eq.stitle = strdup(str);
@@ -471,17 +471,19 @@ api_epg_alternative
   uint32_t id, entries = 0;
   htsmsg_t *l = htsmsg_create_list();
   epg_broadcast_t *e;
-  const char *lang = htsmsg_get_str(args, "lang");
+  char *lang;
 
   if (!htsmsg_get_u32(args, "eventId", &id))
     return -EINVAL;
 
   /* Main Job */
   pthread_mutex_lock(&global_lock);
+  lang = access_get_lang(perm, htsmsg_get_str(args, "lang"));
   e = epg_broadcast_find_by_id(id);
   if (e && e->episode)
     api_epg_episode_broadcasts(perm, l, lang, e->episode, &entries, e);
   pthread_mutex_unlock(&global_lock);
+  free(lang);
 
   /* Build response */
   *resp = htsmsg_create_map();
@@ -499,13 +501,14 @@ api_epg_related
   htsmsg_t *l = htsmsg_create_list();
   epg_broadcast_t *e;
   epg_episode_t *ep, *ep2;
-  const char *lang = htsmsg_get_str(args, "lang");
+  char *lang;
   
   if (!htsmsg_get_u32(args, "eventId", &id))
     return -EINVAL;
 
   /* Main Job */
   pthread_mutex_lock(&global_lock);
+  lang = access_get_lang(perm, htsmsg_get_str(args, "lang"));
   e = epg_broadcast_find_by_id(id);
   ep = e ? e->episode : NULL;
   if (ep && ep->brand) {
@@ -523,6 +526,7 @@ api_epg_related
     }
   }
   pthread_mutex_unlock(&global_lock);
+  free(lang);
 
   /* Build response */
   *resp = htsmsg_create_map();
@@ -540,7 +544,7 @@ api_epg_load
   htsmsg_t *l = htsmsg_create_list(), *ids = NULL, *m;
   htsmsg_field_t *f;
   epg_broadcast_t *e;
-  const char *lang = htsmsg_get_str(args, "lang");
+  char *lang;
 
   if (!(f = htsmsg_field_find(args, "eventId")))
     return -EINVAL;
@@ -550,6 +554,7 @@ api_epg_load
 
   /* Main Job */
   pthread_mutex_lock(&global_lock);
+  lang = access_get_lang(perm, htsmsg_get_str(args, "lang"));
   if (ids) {
     HTSMSG_FOREACH(f, ids) {
       if (htsmsg_field_get_u32(f, &id)) continue;
@@ -567,6 +572,7 @@ api_epg_load
     }
   }
   pthread_mutex_unlock(&global_lock);
+  free(lang);
 
   /* Build response */
   *resp = htsmsg_create_map();
index fc096de58e034486c4279f543e57cebdaa1d23cc..b07289178d8000d0a2c9c7ec782544b58ebc451d 100644 (file)
@@ -44,8 +44,6 @@ static void dvr_entry_destroy(dvr_entry_t *de, int delconf);
 static void dvr_timer_expire(void *aux);
 static void dvr_timer_start_recording(void *aux);
 static void dvr_timer_stop_recording(void *aux);
-static int dvr_entry_class_disp_title_set(void *o, const void *v);
-static int dvr_entry_class_disp_subtitle_set(void *o, const void *v);
 
 /*
  *
@@ -477,7 +475,6 @@ dvr_entry_create(const char *uuid, htsmsg_t *conf)
   dvr_entry_t *de, *de2;
   int64_t start, stop;
   htsmsg_t *m;
-  const char *s;
 
   if (conf) {
     if (htsmsg_get_s64(conf, "start", &start))
@@ -510,16 +507,6 @@ dvr_entry_create(const char *uuid, htsmsg_t *conf)
   if (m)
     de->de_files = htsmsg_copy(m);
 
-  /* special case, because PO_NOSAVE, load ignores it */
-  if (de->de_title == NULL &&
-      (s = htsmsg_get_str(conf, "disp_title")) != NULL)
-    dvr_entry_class_disp_title_set(de, s);
-
-  /* special case, because PO_NOSAVE, load ignores it */
-  if (de->de_subtitle == NULL &&
-          (s = htsmsg_get_str(conf, "disp_subtitle")) != NULL)
-    dvr_entry_class_disp_subtitle_set(de, s);
-
   de->de_refcnt = 1;
 
   LIST_INSERT_HEAD(&dvrentries, de, de_global_link);
@@ -1746,64 +1733,30 @@ dvr_entry_class_broadcast_get(void *o)
   return &id;
 }
 
-static int
-dvr_entry_class_disp_title_set(void *o, const void *v)
-{
-  dvr_entry_t *de = (dvr_entry_t *)o;
-  const char *s = "";
-  if (v == NULL || *((char *)v) == '\0')
-    v = "UnknownTitle";
-  if (de->de_title)
-    s = lang_str_get(de->de_title, NULL);
-  if (strcmp(s, v)) {
-    lang_str_destroy(de->de_title);
-    de->de_title = lang_str_create();
-    lang_str_add(de->de_title, v, NULL, 0);
-    return 1;
-  }
-  return 0;
-}
-
 static const void *
 dvr_entry_class_disp_title_get(void *o)
 {
   dvr_entry_t *de = (dvr_entry_t *)o;
   static const char *s;
+  const char *lang = de->de_id.in_access ? de->de_id.in_access->aa_lang : NULL;
   s = "";
   if (de->de_title) {
-    s = lang_str_get(de->de_title, NULL);
+    s = lang_str_get(de->de_title, lang);
     if (s == NULL)
       s = "";
   }
   return &s;
 }
 
-static int
-dvr_entry_class_disp_subtitle_set(void *o, const void *v)
-{
-  dvr_entry_t *de = (dvr_entry_t *)o;
-  const char *s = "";
-  if (v == NULL || *((char *)v) == '\0')
-    v = "UnknownSubtitle";
-  if (de->de_subtitle)
-    s = lang_str_get(de->de_subtitle, NULL);
-  if (strcmp(s, v)) {
-    lang_str_destroy(de->de_subtitle);
-    de->de_subtitle = lang_str_create();
-    lang_str_add(de->de_subtitle, v, NULL, 0);
-    return 1;
-  }
-  return 0;
-}
-
 static const void *
 dvr_entry_class_disp_subtitle_get(void *o)
 {
   dvr_entry_t *de = (dvr_entry_t *)o;
   static const char *s;
+  const char *lang = de->de_id.in_access ? de->de_id.in_access->aa_lang : NULL;
   s = "";
   if (de->de_subtitle) {
-    s = lang_str_get(de->de_subtitle, NULL);
+    s = lang_str_get(de->de_subtitle, lang);
     if (s == NULL)
       s = "";
   }
@@ -1815,9 +1768,10 @@ dvr_entry_class_disp_description_get(void *o)
 {
   dvr_entry_t *de = (dvr_entry_t *)o;
   static const char *s;
+  const char *lang = de->de_id.in_access ? de->de_id.in_access->aa_lang : NULL;
   s = "";
   if (de->de_desc) {
-    s = lang_str_get(de->de_desc, NULL);
+    s = lang_str_get(de->de_desc, lang);
     if (s == NULL)
       s = "";
   }
@@ -2084,7 +2038,6 @@ const idclass_t dvr_entry_class = {
       .id       = "disp_title",
       .name     = N_("Title"),
       .get      = dvr_entry_class_disp_title_get,
-      .set      = dvr_entry_class_disp_title_set,
       .opts     = PO_NOSAVE,
     },
     {
@@ -2099,7 +2052,6 @@ const idclass_t dvr_entry_class = {
       .id       = "disp_subtitle",
       .name     = N_("Subtitle"),
       .get      = dvr_entry_class_disp_subtitle_get,
-      .set      = dvr_entry_class_disp_subtitle_set,
       .opts     = PO_NOSAVE,
     },
     {
index b37878c6144777650d495dc611369d9122b7e098..f64c01f86b765a873cbd9024e9fffa436e03e783 100644 (file)
@@ -34,6 +34,7 @@
 #include "descrambler/caid.h"
 #include "notify.h"
 #include "htsmsg_json.h"
+#include "lang_codes.h"
 #if ENABLE_TIMESHIFT
 #include "timeshift.h"
 #endif
@@ -2602,6 +2603,9 @@ htsp_authenticate(htsp_connection_t *htsp, htsmsg_t *m)
     access_destroy(htsp->htsp_granted_access);
     htsp->htsp_granted_access = rights;
 
+    if (htsp->htsp_language == NULL && rights->aa_lang)
+      htsp->htsp_language = strdup(rights->aa_lang);
+
   } else {
 
     tvhlog(LOG_INFO, "htsp", "%s: Identified as user '%s' (unverified)",
index b56d487e78a50b8e10a3dc70193648797c03fdbd..ec9a7a68c4777e8ee190c7210f54f78d0908a831 100644 (file)
@@ -696,6 +696,32 @@ const char *lang_code_preferred( void )
   return ret;
 }
 
+char *lang_code_user( const char *ucode )
+{
+  const char *codes = config_get_language(), *s;
+  char *ret;
+
+  if (!codes)
+    return ucode ? strdup(ucode) : NULL;
+  if (!ucode)
+    return codes ? strdup(codes) : NULL;
+  ret = malloc(strlen(codes) + strlen(ucode ?: "") + 1);
+  strcpy(ret, ucode);
+  while (codes && *codes) {
+    s = codes;
+    while (*s && *s != ',')
+      s++;
+    if (strncmp(codes, ucode ?: "", s - codes)) {
+      strcat(ret, ",");
+      strncat(ret, codes, s - codes);
+    }
+    if (*s && *s == ',')
+      s++;
+    codes = s;
+  }
+  return ret;
+}
+
 void lang_code_done( void )
 {
   lang_code_free(lang_codes_code2b);
index d036d5eee2a2788d077ccd5ffc4555a85e749533..89d5457b05c174ceeb3944329b714e9dde479b97 100644 (file)
@@ -38,6 +38,7 @@ const char *lang_code_get2 ( const char *code, size_t len );
 const lang_code_t *lang_code_get3 ( const char *code );
 
 const char *lang_code_preferred( void );
+char *lang_code_user( const char *ucode );
 
 /* Split list of codes as per HTTP Language-Accept spec */
 const char **lang_code_split ( const char *codes );
index 783ccbaa0767cd0cc998dea666af7bce5ae58993..780cf7f6f2ec31838e68c10ed1f47660bbb4dbe3 100644 (file)
@@ -127,9 +127,14 @@ static void lng_init(struct lng *l)
 static struct lng *lng_get(const char *tvh_lang)
 {
   struct lng *l, ls;
+  char *s;
 
   if (tvh_lang != NULL && tvh_lang[0] != '\0') {
-    ls.tvh_lang = tvh_lang;
+    s = alloca(strlen(tvh_lang) + 1);
+    ls.tvh_lang = s;
+    for ( ; *tvh_lang && *tvh_lang != ','; s++, tvh_lang++)
+      *s = *tvh_lang;
+    *s = '\0';
     l = RB_FIND(&lngs, &ls, link, lng_cmp);
     if (l) {
       if (!l->msgs_initialized)
index af541253187d878392f1f5a88ba00fd105050654..ffd770ef6218477c4f22cb0e1f9c8bc4925b6dab 100644 (file)
@@ -410,7 +410,7 @@ extjs_languages(http_connection_t *hc, const char *remain, void *opaque)
     out = htsmsg_create_map();
     array = htsmsg_create_list();
 
-    const lang_code_t **c = lang_code_split2(NULL);
+    const lang_code_t **c = lang_code_split2(hc->hc_access->aa_lang);
     if(c) {
       int i = 0;
       while (c[i]) {