From: Jaroslav Kysela Date: Mon, 29 Jun 2015 13:04:47 +0000 (+0200) Subject: ACL/all: handle the per user language settings for all operations X-Git-Tag: v4.2.1~2208 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7cfdff0699d24ab92c00ebd668f7406512666a82;p=thirdparty%2Ftvheadend.git ACL/all: handle the per user language settings for all operations --- diff --git a/src/access.c b/src/access.c index 084c1d3e3..f2e7f7200 100644 --- a/src/access.c +++ b/src/access.c @@ -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; } diff --git a/src/access.h b/src/access.h index 036be1ea9..a6269d315 100644 --- a/src/access.h +++ b/src/access.h @@ -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 diff --git a/src/api/api_dvr.c b/src/api/api_dvr.c index d549f86f0..ab9a5a916 100644 --- a/src/api/api_dvr.c +++ b/src/api/api_dvr.c @@ -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); diff --git a/src/api/api_epg.c b/src/api/api_epg.c index 117ab9d5b..d14e16e61 100644 --- a/src/api/api_epg.c +++ b/src/api/api_epg.c @@ -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(); diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index fc096de58..b07289178 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -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, }, { diff --git a/src/htsp_server.c b/src/htsp_server.c index b37878c61..f64c01f86 100644 --- a/src/htsp_server.c +++ b/src/htsp_server.c @@ -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)", diff --git a/src/lang_codes.c b/src/lang_codes.c index b56d487e7..ec9a7a68c 100644 --- a/src/lang_codes.c +++ b/src/lang_codes.c @@ -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); diff --git a/src/lang_codes.h b/src/lang_codes.h index d036d5eee..89d5457b0 100644 --- a/src/lang_codes.h +++ b/src/lang_codes.h @@ -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 ); diff --git a/src/tvh_locale.c b/src/tvh_locale.c index 783ccbaa0..780cf7f6f 100644 --- a/src/tvh_locale.c +++ b/src/tvh_locale.c @@ -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) diff --git a/src/webui/extjs.c b/src/webui/extjs.c index af5412531..ffd770ef6 100644 --- a/src/webui/extjs.c +++ b/src/webui/extjs.c @@ -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]) {