diff --git a/src/channels.c b/src/channels.c index dac123b8..72275944 100644 --- a/src/channels.c +++ b/src/channels.c @@ -534,6 +534,14 @@ channel_get_number ( channel_t *ch ) return 0; } +static int +check_file( const char *url ) +{ + if (url && !strncmp(url, "file://", 7)) + return access(url + 7, R_OK) == 0; + return 1; +} + const char * channel_get_icon ( channel_t *ch ) { @@ -543,56 +551,73 @@ channel_get_icon ( channel_t *ch ) *picon = config_get_picon_path(), *icon = ch->ch_icon, *chname; - uint32_t id; + uint32_t id, i, pick, prefer = config_get_prefer_picon() ? 1 : 0; if (icon && *icon == '\0') icon = NULL; - /* No user icon - try to get the channel icon by name */ - if (!icon && chicon && chicon[0] >= ' ' && chicon[0] <= 122 && - (chname = channel_get_name(ch)) != NULL && chname[0]) { - const char *send, *sname, *s; - chicon = strdup(chicon); - send = strstr(chicon, "%C"); - if (send == NULL) { - buf[0] = '\0'; - sname = ""; - } else { - *(char *)send = '\0'; - send += 2; - sname = intlconv_utf8safestr(intlconv_charset_id("ASCII", 1, 1), - chname, strlen(chname) * 2); - /* Remove problematic characters */ - s = sname; - while (*s) { - if (*s <= ' ' || *s > 122 || - strchr("/:\\<>|*?'\"", *s) != NULL) - *(char *)s = '_'; - s++; + /* + * 4 iterations: + * 0,1: try channel name or picon + * 2,3: force channel name or picon + */ + for (i = 0; icon == NULL && i < 4; i++) { + + pick = (i ^ prefer) & 1; + + /* No user icon - try to get the channel icon by name */ + if (!pick && chicon && chicon[0] >= ' ' && chicon[0] <= 122 && + (chname = channel_get_name(ch)) != NULL && chname[0]) { + const char *chi, *send, *sname, *s; + chi = strdup(chicon); + send = strstr(chi, "%C"); + if (send == NULL) { + buf[0] = '\0'; + sname = ""; + } else { + *(char *)send = '\0'; + send += 2; + sname = intlconv_utf8safestr(intlconv_charset_id("ASCII", 1, 1), + chname, strlen(chname) * 2); + if (sname == NULL) + sname = strdup(chname); + /* Remove problematic characters */ + s = sname; + while (s && *s) { + if (*s <= ' ' || *s > 122 || + strchr("/:\\<>|*?'\"", *s) != NULL) + *(char *)s = '_'; + s++; + } + } + snprintf(buf, sizeof(buf), "%s%s%s", chi, sname ?: "", send ?: ""); + if (send) + free((char *)sname); + free((char *)chi); + + if (i > 1 || check_file(buf)) { + icon = ch->ch_icon = strdup(buf); + channel_save(ch); + idnode_notify_simple(&ch->ch_id); } } - snprintf(buf, sizeof(buf), "%s%s%s", chicon, sname, send); - if (send) - free((char *)sname); - free((char *)chicon); - icon = ch->ch_icon = strdup(buf); - channel_save(ch); - } - - /* No user icon - try access from services */ - if (!icon && picon) { - LIST_FOREACH(csm, &ch->ch_services, csm_chn_link) { - if (!(icon = service_get_channel_icon(csm->csm_svc))) continue; - if (strncmp(icon, "picon://", 8)) { - icon = NULL; - continue; + /* No user icon - try access from services */ + if (pick && picon) { + LIST_FOREACH(csm, &ch->ch_services, csm_chn_link) { + const char *icn; + if (!(icn = service_get_channel_icon(csm->csm_svc))) continue; + if (strncmp(icn, "picon://", 8)) + continue; + snprintf(buf2, sizeof(buf2), "%s/%s", picon, icn+8); + if (i > 1 || check_file(buf2)) { + ch->ch_icon = strdup(icn); + channel_save(ch); + idnode_notify_simple(&ch->ch_id); + } } - sprintf(buf2, "%s/%s", picon, icon+8); - ch->ch_icon = strdup(icon); - channel_save(ch); - idnode_notify_simple(&ch->ch_id); } + } /* Nothing */ diff --git a/src/config.c b/src/config.c index 7f04a545..a26b7768 100644 --- a/src/config.c +++ b/src/config.c @@ -1400,6 +1400,18 @@ int config_set_muxconfpath ( const char *path ) return _config_set_str("muxconfpath", path); } +int config_get_prefer_picon ( void ) +{ + int b = 0; + htsmsg_get_bool(config, "picon_prefer", &b); + return b; +} + +int config_set_prefer_picon ( const char *str ) +{ + return _config_set_str("picon_prefer", str); +} + const char *config_get_chicon_path ( void ) { return htsmsg_get_str(config, "chiconpath"); diff --git a/src/config.h b/src/config.h index 303199ae..c24d5141 100644 --- a/src/config.h +++ b/src/config.h @@ -37,6 +37,10 @@ const char *config_get_language ( void ); int config_set_language ( const char *str ) __attribute__((warn_unused_result)); +int config_get_prefer_picon ( void ); +int config_set_prefer_picon ( const char *str ) + __attribute__((warn_unused_result)); + const char *config_get_chicon_path ( void ); int config_set_chicon_path ( const char *str ) __attribute__((warn_unused_result)); diff --git a/src/webui/extjs.c b/src/webui/extjs.c index 0a27493d..233cfd16 100755 --- a/src/webui/extjs.c +++ b/src/webui/extjs.c @@ -505,6 +505,8 @@ extjs_config(http_connection_t *hc, const char *remain, void *opaque) save |= config_set_muxconfpath(str); if ((str = http_arg_get(&hc->hc_req_args, "language"))) save |= config_set_language(str); + if ((str = http_arg_get(&hc->hc_req_args, "prefer_picon"))) + save |= config_set_prefer_picon(str); if ((str = http_arg_get(&hc->hc_req_args, "chiconpath"))) save |= config_set_chicon_path(str); if ((str = http_arg_get(&hc->hc_req_args, "piconpath"))) diff --git a/src/webui/static/app/config.js b/src/webui/static/app/config.js index 3cc9987f..481febec 100644 --- a/src/webui/static/app/config.js +++ b/src/webui/static/app/config.js @@ -44,6 +44,7 @@ tvheadend.miscconf = function(panel, index) { 'muxconfpath', 'language', 'tvhtime_update_enabled', 'tvhtime_ntp_enabled', 'tvhtime_tolerance', + 'prefer_picon', 'chiconpath', 'piconpath' ]); @@ -132,6 +133,11 @@ tvheadend.miscconf = function(panel, index) { * Picons */ + var preferPicon = new Ext.ux.form.XCheckbox({ + name: 'prefer_picon', + fieldLabel: 'Prefer picons over channel name', + }); + var chiconPath = new Ext.form.TextField({ name: 'chiconpath', fieldLabel: 'Channel icon path
(e.g. file:///tmp/icons/%C.png or http://...)', @@ -150,7 +156,7 @@ tvheadend.miscconf = function(panel, index) { autoHeight: true, collapsible: true, animCollapse: true, - items: [chiconPath, piconPath] + items: [preferPicon, chiconPath, piconPath] }); /*