From da682c4507a1b11ceaf714675f833d56c2084157 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Wed, 12 Dec 2018 19:08:00 +0100 Subject: [PATCH] imagecache: big cleanups - let imagecache work also for fanart / recording specific images - let imagecache work for EPG entries - global cleanups (try to have only one function for duplicate things) - fix the local file handling when imagecache is not enabled for external URLs - imagecache code is part of the tvh's core code (cannot be ommited from compilation) --- configure | 8 -- src/api/api_epg.c | 22 +++-- src/api/api_imagecache.c | 11 --- src/channels.c | 46 ++++----- src/channels.h | 2 + src/dvr/dvr.h | 3 +- src/dvr/dvr_db.c | 74 ++++++++------ src/htsp_server.c | 172 +++++++++++++++++++-------------- src/http.c | 7 +- src/http.h | 2 +- src/imagecache.c | 85 +++++++--------- src/imagecache.h | 14 +-- src/main.c | 3 - src/webui/static/app/config.js | 3 - src/webui/webui.c | 79 +++++++-------- src/webui/xmltv.c | 28 +++--- 16 files changed, 284 insertions(+), 275 deletions(-) diff --git a/configure b/configure index 201dfba57..e5f6f593b 100755 --- a/configure +++ b/configure @@ -34,7 +34,6 @@ OPTIONS=( "dvbscan:yes" "timeshift:yes" "trace:yes" - "imagecache:auto" "avahi:auto" "zlib:auto" "libav:auto" @@ -701,13 +700,6 @@ if enabled_or_auto tvhcsa; then fi fi -# -# Icon caching -# -if enabled_or_auto imagecache; then - enable imagecache -fi - # # DVB scan # diff --git a/src/api/api_epg.c b/src/api/api_epg.c index 35a93864d..8a2709cb1 100644 --- a/src/api/api_epg.c +++ b/src/api/api_epg.c @@ -54,7 +54,7 @@ static void api_epg_add_channel ( htsmsg_t *m, channel_t *ch, const char *blank ) { int64_t chnum; - char buf[32]; + char buf[128]; const char *s; htsmsg_add_str(m, "channelName", channel_get_name(ch, blank)); htsmsg_add_uuid(m, "channelUuid", &ch->ch_id.in_uuid); @@ -67,16 +67,20 @@ api_epg_add_channel ( htsmsg_t *m, channel_t *ch, const char *blank ) snprintf(buf, sizeof(buf), "%u", maj); htsmsg_add_str(m, "channelNumber", buf); } - if ((s = channel_get_icon(ch)) != NULL) - htsmsg_add_str(m, "channelIcon", s); + s = channel_get_icon(ch); + if (!strempty(s)) { + s = imagecache_get_propstr(s, buf, sizeof(buf)); + if (s) + htsmsg_add_str(m, "channelIcon", s); + } } static htsmsg_t * api_epg_entry ( epg_broadcast_t *eb, const char *lang, const access_t *perm, const char **blank ) { const char *s, *blank2 = NULL; - char buf[64]; - channel_t *ch = eb->channel; + char buf[32]; + channel_t *ch = eb->channel; htsmsg_t *m, *m2; epg_episode_num_t epnum; epg_genre_t *eg; @@ -170,8 +174,12 @@ api_epg_entry ( epg_broadcast_t *eb, const char *lang, const access_t *perm, con htsmsg_add_str(m, "episodeOnscreen", buf); /* Image */ - if (eb->image) - htsmsg_add_str(m, "image", eb->image); + s = eb->image; + if (!strempty(s)) { + s = imagecache_get_propstr(s, buf, sizeof(buf)); + if (s) + htsmsg_add_str(m, "image", s); + } /* Rating */ if (eb->star_rating) diff --git a/src/api/api_imagecache.c b/src/api/api_imagecache.c index 3e6c585f6..c0894c225 100644 --- a/src/api/api_imagecache.c +++ b/src/api/api_imagecache.c @@ -23,8 +23,6 @@ #include "api.h" #include "imagecache.h" -#if ENABLE_IMAGECACHE - static int api_imagecache_clean ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) @@ -68,12 +66,3 @@ api_imagecache_init ( void ) api_register_all(ah); } - -#else /* ENABLE_IMAGECACHE */ - -void -api_imagecache_init ( void ) -{ -} - -#endif diff --git a/src/channels.c b/src/channels.c index 46bdc2cfe..cff8fe242 100644 --- a/src/channels.c +++ b/src/channels.c @@ -58,6 +58,18 @@ ch_id_cmp ( channel_t *a, channel_t *b ) return channel_get_id(a) - channel_get_id(b); } +static void +channel_load_icon ( channel_t *ch ) +{ + (void)imagecache_get_id(channel_get_icon(ch)); +} + +static void +channel_tag_load_icon ( channel_tag_t *tag ) +{ + (void)imagecache_get_id(channel_tag_get_icon(tag)); +} + /* ************************************************************************** * Class definition * *************************************************************************/ @@ -209,13 +221,15 @@ channel_class_icon_notify ( void *obj, const char *lang ) { channel_t *ch = obj; if (!ch->ch_load) - (void)channel_get_icon(obj); + channel_load_icon(obj); } -static const void * +const void * channel_class_get_icon ( void *obj ) { prop_ptr = channel_get_icon(obj); + if (!strempty(prop_ptr)) + prop_ptr = imagecache_get_propstr(prop_ptr, prop_sbuf, PROP_SBUF_LEN); return &prop_ptr; } @@ -1032,7 +1046,7 @@ channel_get_icon ( channel_t *ch ) *picon = config.picon_path, *icon = ch->ch_icon, *chname, *icn; - int id, i, pick, prefer = config.prefer_picon ? 1 : 0; + int i, pick, prefer = config.prefer_picon ? 1 : 0; char c; if (tvh_str_default(icon, NULL) == NULL) @@ -1170,14 +1184,7 @@ found: icon = buf2; } - /* Lookup imagecache ID */ - if ((id = imagecache_get_id(icon))) { - snprintf(buf, sizeof(buf), "imagecache/%d", id); - } else { - strlcpy(buf, icon, sizeof(buf)); - } - - return buf; + return icon; } int channel_set_icon ( channel_t *ch, const char *icon ) @@ -1259,7 +1266,7 @@ channel_create0 htsp_channel_add(ch); /* determine icon URL */ - (void)channel_get_icon(ch); + channel_load_icon(ch); return ch; } @@ -1634,16 +1641,7 @@ channel_tag_destroy(channel_tag_t *ct, int delconf) const char * channel_tag_get_icon(channel_tag_t *ct) { - static char buf[64]; - const char *icon = ct->ct_icon; - int id; - - /* Lookup imagecache ID */ - if ((id = imagecache_get_id(icon))) { - snprintf(buf, sizeof(buf), "imagecache/%d", id); - return buf; - } - return icon; + return ct->ct_icon; } /** @@ -1720,13 +1718,15 @@ channel_tag_class_get_title static void channel_tag_class_icon_notify ( void *obj, const char *lang ) { - (void)channel_tag_get_icon(obj); + channel_tag_load_icon(obj); } static const void * channel_tag_class_get_icon ( void *obj ) { prop_ptr = channel_tag_get_icon(obj); + if (!strempty(prop_ptr)) + prop_ptr = imagecache_get_propstr(prop_ptr, prop_sbuf, PROP_SBUF_LEN); return &prop_ptr; } diff --git a/src/channels.h b/src/channels.h index 5d4bd79fb..aa97ec316 100644 --- a/src/channels.h +++ b/src/channels.h @@ -155,6 +155,8 @@ channel_t *channel_find_by_number(const char *no); htsmsg_t * channel_class_get_list(void *o, const char *lang); +const void * channel_class_get_icon ( void *obj ); + int channel_set_tags_by_list ( channel_t *ch, htsmsg_t *tags ); channel_tag_t *channel_tag_create(const char *uuid, htsmsg_t *conf); diff --git a/src/dvr/dvr.h b/src/dvr/dvr.h index 73645efad..755b14cfb 100644 --- a/src/dvr/dvr.h +++ b/src/dvr/dvr.h @@ -702,7 +702,8 @@ htsmsg_t * dvr_autorec_entry_class_time_list(void *o, const char *null); htsmsg_t * dvr_autorec_entry_class_weekdays_get(uint32_t weekdays); htsmsg_t * dvr_autorec_entry_class_weekdays_list (void *o, const char *list); char * dvr_autorec_entry_class_weekdays_rend(uint32_t weekdays, const char *lang); -const char *dvr_entry_class_image_url_get(const dvr_entry_t *o); +const char *dvr_entry_get_image(const dvr_entry_t *o); +const char *dvr_entry_get_fanart_image(const dvr_entry_t *o); void dvr_autorec_check_event(epg_broadcast_t *e); diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index 972f1fa21..06d48cb56 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -3855,50 +3855,61 @@ dvr_entry_class_channel_icon_url_get(void *o) dvr_entry_t *de = (dvr_entry_t *)o; channel_t *ch = de->de_channel; if (ch == NULL) { - prop_ptr = NULL; + prop_ptr = ""; } else { - prop_ptr = channel_get_icon(ch); + return channel_class_get_icon(ch); } + return &prop_ptr; +} + +const char * +dvr_entry_get_image(const dvr_entry_t *de) +{ + if (de->de_bcast && de->de_bcast && de->de_bcast->image) + return de->de_bcast->image; + if (de->de_image) + return de->de_image; + return NULL; +} + +const char * +dvr_entry_get_fanart_image(const dvr_entry_t *de) +{ + return de->de_fanart_image; +} + +static const void * +dvr_entry_class_image_get0(dvr_entry_t *de, const char *image) +{ + prop_ptr = imagecache_get_propstr(image, prop_sbuf, PROP_SBUF_LEN); if (prop_ptr == NULL) prop_ptr = ""; return &prop_ptr; } static const void * -dvr_entry_class_image_url_get_as_property(void *o) +dvr_entry_class_image_get(void *o) { - dvr_entry_t *de = (dvr_entry_t *)o; - static const char *s = ""; - /* We prefer the image from the broadcast to the one currently - * persisted. This is because a programme scheduled far in the - * future may have a generic image that will be updated nearer the - * broadcast date with a more specific image. - */ - if (de->de_bcast && de->de_bcast && de->de_bcast->image) { - snprintf(prop_sbuf, PROP_SBUF_LEN, "%s", de->de_bcast->image); - return &prop_sbuf_ptr; - } - - if (de->de_image) { - prop_ptr = de->de_image; - return &prop_ptr; - } - - return &s; + return dvr_entry_class_image_get0(o, dvr_entry_get_image(o)); } -const char * -dvr_entry_class_image_url_get(const dvr_entry_t *o) +static void +dvr_entry_class_image_notify(void *o, const char *lang) { - const void *image = dvr_entry_class_image_url_get_as_property((void*)o); - if (!image) return NULL; - const char *image_str = *(const char**)image; - if (!image_str) return NULL; - if (!*image_str) return NULL; - return image_str; + (void)imagecache_get_id(dvr_entry_get_image(o)); } +static const void * +dvr_entry_class_fanart_image_get(void *o) +{ + return dvr_entry_class_image_get0(o, dvr_entry_get_fanart_image(o)); +} +static void +dvr_entry_class_fanart_image_notify(void *o, const char *lang) +{ + (void)imagecache_get_id(dvr_entry_get_fanart_image(o)); +} static const void * dvr_entry_class_duplicate_get(void *o) @@ -4157,7 +4168,8 @@ const idclass_t dvr_entry_class = { .id = "image", /* Name chosen to be compatible with api_epg */ .name = N_("Episode image"), .desc = N_("Episode image."), - .get = dvr_entry_class_image_url_get_as_property, + .get = dvr_entry_class_image_get, + .notify = dvr_entry_class_image_notify, .off = offsetof(dvr_entry_t, de_image), .opts = PO_HIDDEN, }, @@ -4166,6 +4178,8 @@ const idclass_t dvr_entry_class = { .id = "fanart_image", .name = N_("Fanart image"), .desc = N_("Fanart image."), + .get = dvr_entry_class_fanart_image_get, + .notify = dvr_entry_class_fanart_image_notify, .off = offsetof(dvr_entry_t, de_fanart_image), .opts = PO_HIDDEN, }, diff --git a/src/htsp_server.c b/src/htsp_server.c index 49af61b17..5a6d794df 100644 --- a/src/htsp_server.c +++ b/src/htsp_server.c @@ -56,14 +56,6 @@ static void *htsp_server, *htsp_server_2; #define HTSP_ASYNC_ON 0x01 #define HTSP_ASYNC_EPG 0x02 -#define HTSP_ASYNC_AUX_CH 0x01 -#define HTSP_ASYNC_AUX_CHTAG 0x02 -#define HTSP_ASYNC_AUX_CHTAG_DEL 0x03 -#define HTSP_ASYNC_AUX_DVR 0x04 -#define HTSP_ASYNC_AUX_AUTOREC 0x05 -#define HTSP_ASYNC_AUX_TIMEREC 0x06 -#define HTSP_ASYNC_AUX_EPG 0x07 - #define HTSP_ASYNC_EPG_INTERVAL 30 #define HTSP_PRIV_MASK (ACCESS_HTSP_STREAMING) @@ -344,6 +336,44 @@ htsp_flush_queue(htsp_connection_t *htsp, htsp_msg_q_t *hmq, int dead) tvh_mutex_unlock(&htsp->htsp_out_mutex); } +/* + * + */ +static const char * +htsp_image(htsp_connection_t *htsp, const char *image, char *buf, size_t buflen) +{ + const char *ret = image; + const int id = imagecache_get_id(image); + + /* Handle older clients */ + if (id) { + if (htsp->htsp_version < 8) { + struct sockaddr_storage addr; + socklen_t addrlen; + char abuf[50]; + addrlen = sizeof(addr); + getsockname(htsp->htsp_fd, (struct sockaddr*)&addr, &addrlen); + tcp_get_str_from_ip(&addr, abuf, sizeof(abuf)); + snprintf(buf, buflen, "http://%s%s%s:%d%s/imagecache/%d", + (addr.ss_family == AF_INET6)?"[":"", + abuf, + (addr.ss_family == AF_INET6)?"]":"", + tvheadend_webui_port, + tvheadend_webroot ?: "", + id); + ret = buf; + } else if (htsp->htsp_version < 15) { + /* older clients expects '/imagecache/' */ + snprintf(buf, buflen, "/imagecache/%d", id); + ret = buf; + } else { + snprintf(buf, buflen, "imagecache/%d", id); + ret = buf; + } + } + return ret; +} + /** * */ @@ -827,7 +857,7 @@ htsp_build_channel(channel_t *ch, const char *method, htsp_connection_t *htsp) epg_broadcast_t *now, *next = NULL; int64_t chnum = channel_get_number(ch); const char *icon; - char buf[64]; + char buf[512]; htsmsg_t *out = htsmsg_create_map(); htsmsg_t *tags = htsmsg_create_list(); @@ -839,36 +869,8 @@ htsp_build_channel(channel_t *ch, const char *method, htsp_connection_t *htsp) htsmsg_add_u32(out, "channelNumberMinor", channel_get_minor(chnum)); htsmsg_add_str(out, "channelName", channel_get_name(ch, channel_blank_name)); - if ((icon = channel_get_icon(ch))) { - - /* Handle older clients */ - if ((strstr(icon, "imagecache") == icon) && htsp->htsp_version < 8) { - struct sockaddr_storage addr; - socklen_t addrlen; - char url[256]; - char buf[50]; - addrlen = sizeof(addr); - getsockname(htsp->htsp_fd, (struct sockaddr*)&addr, &addrlen); - tcp_get_str_from_ip(&addr, buf, 50); - snprintf(url, sizeof(url), "http://%s%s%s:%d%s/%s", - (addr.ss_family == AF_INET6)?"[":"", - buf, - (addr.ss_family == AF_INET6)?"]":"", - tvheadend_webui_port, - tvheadend_webroot ?: "", - icon); - htsmsg_add_str(out, "channelIcon", url); - } else { - if (htsp->htsp_version < 15) { - /* older clients expects '/imagecache/' */ - if (strncmp(icon, "imagecache/", 11) == 0) { - snprintf(buf, sizeof(buf), "/%s", icon); - icon = buf; - } - } - htsmsg_add_str(out, "channelIcon", icon); - } - } + if ((icon = channel_get_icon(ch))) + htsmsg_add_str(out, "channelIcon", htsp_image(htsp, icon, buf, sizeof(buf))); now = ch->ch_epg_now; next = ch->ch_epg_next; @@ -915,8 +917,10 @@ htsp_build_channel(channel_t *ch, const char *method, htsp_connection_t *htsp) * */ static htsmsg_t * -htsp_build_tag(channel_tag_t *ct, const char *method, int include_channels) +htsp_build_tag(htsp_connection_t *htsp, channel_tag_t *ct, const char *method, int include_channels) { + char buf[512]; + const char *icon; idnode_list_mapping_t *ilm; htsmsg_t *out = htsmsg_create_map(); htsmsg_t *members = include_channels ? htsmsg_create_list() : NULL; @@ -925,7 +929,9 @@ htsp_build_tag(channel_tag_t *ct, const char *method, int include_channels) htsmsg_add_u32(out, "tagIndex", ct->ct_index); htsmsg_add_str(out, "tagName", ct->ct_name); - htsmsg_add_str(out, "tagIcon", channel_tag_get_icon(ct)); + icon = channel_tag_get_icon(ct); + if (!strempty(icon)) + htsmsg_add_str(out, "tagIcon", htsp_image(htsp, icon, buf, sizeof(buf))); htsmsg_add_u32(out, "tagTitledIcon", ct->ct_titled_icon); if(members != NULL) { @@ -950,6 +956,7 @@ htsp_build_dvrentry(htsp_connection_t *htsp, dvr_entry_t *de, const char *method const char *p, *last; int64_t fsize = -1, start, stop; uint32_t u32; + char buf[512]; char ubuf[UUID_HEX_SIZE]; htsmsg_add_u32(out, "id", idnode_get_short_uuid(&de->de_id)); @@ -1027,13 +1034,13 @@ htsp_build_dvrentry(htsp_connection_t *htsp, dvr_entry_t *de, const char *method * an image from current EPG if recording does not have * an associated image. */ - const char *image = dvr_entry_class_image_url_get(de); - if(image && *image) - htsmsg_add_str(out, "image", image); + const char *image = dvr_entry_get_image(de); + if(!strempty(image)) + htsmsg_add_str(out, "image", htsp_image(htsp, image, buf, sizeof(buf))); /* htsmsg camelcase to be compatible with other names */ image = de->de_fanart_image; - if(image && *image) - htsmsg_add_str(out, "fanartImage", image); + if(!strempty(image)) + htsmsg_add_str(out, "fanartImage", htsp_image(htsp, image, buf, sizeof(buf))); if (de->de_copyright_year) htsmsg_add_u32(out, "copyrightYear", de->de_copyright_year); @@ -1228,6 +1235,7 @@ htsp_build_event epg_genre_t *g; epg_episode_num_t epnum; const char *str; + char buf[512]; /* Ignore? */ if (update && e->updated <= update) return NULL; @@ -1296,8 +1304,8 @@ htsp_build_event htsmsg_add_s64(out, "firstAired", e->first_aired); epg_broadcast_get_epnum(e, &epnum); htsp_serialize_epnum(out, &epnum, NULL); - if (e->image) - htsmsg_add_str(out, "image", e->image); + if (!strempty(e->image)) + htsmsg_add_str(out, "image", htsp_image(htsp, e->image, buf, sizeof(buf))); if (e->channel) { LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link) { @@ -1565,7 +1573,7 @@ htsp_method_async(htsp_connection_t *htsp, htsmsg_t *in) /* Send all enabled and external tags */ TAILQ_FOREACH(ct, &channel_tags, ct_link) if(channel_tag_access(ct, htsp->htsp_granted_access, 0)) - htsp_send_message(htsp, htsp_build_tag(ct, "tagAdd", 0), NULL); + htsp_send_message(htsp, htsp_build_tag(htsp, ct, "tagAdd", 0), NULL); /* Send all channels */ CHANNEL_FOREACH(ch) @@ -1575,7 +1583,7 @@ htsp_method_async(htsp_connection_t *htsp, htsmsg_t *in) /* Send all enabled and external tags (now with channel mappings) */ TAILQ_FOREACH(ct, &channel_tags, ct_link) if(channel_tag_access(ct, htsp->htsp_granted_access, 0)) - htsp_send_message(htsp, htsp_build_tag(ct, "tagUpdate", 1), NULL); + htsp_send_message(htsp, htsp_build_tag(htsp, ct, "tagUpdate", 1), NULL); /* Send all autorecs */ TAILQ_FOREACH(dae, &autorec_entries, dae_link) @@ -3560,21 +3568,39 @@ htsp_done(void) * */ static void -htsp_async_send(htsmsg_t *m, int mode, int aux_type, void *aux) +htsp_async_send(htsmsg_t *m, int mode, void *aux) { htsp_connection_t *htsp; lock_assert(&global_lock); LIST_FOREACH(htsp, &htsp_async_connections, htsp_async_link) - if (htsp->htsp_async_mode & mode) { - if (aux_type == HTSP_ASYNC_AUX_CHTAG && - !channel_tag_access(aux, htsp->htsp_granted_access, 0)) - continue; + if (htsp->htsp_async_mode & mode) htsp_send_message(htsp, htsmsg_copy(m), NULL); - } htsmsg_destroy(m); } +/** + * + */ +typedef htsmsg_t *(*http_async_send_cb_t)(htsp_connection_t *htsp, void *aux); + +static void +htsp_async_send_cb(http_async_send_cb_t cb, int mode, void *aux) +{ + htsp_connection_t *htsp; + htsmsg_t *m; + + lock_assert(&global_lock); + LIST_FOREACH(htsp, &htsp_async_connections, htsp_async_link) + if (htsp->htsp_async_mode & mode) { + m = cb(htsp, aux); + if (m != NULL) { + htsp_send_message(htsp, m, NULL); + htsmsg_destroy(m); + } + } +} + /** * Called from channel.c when a new channel is created */ @@ -3643,9 +3669,19 @@ htsp_channel_delete(channel_t *ch) htsmsg_t *m = htsmsg_create_map(); htsmsg_add_u32(m, "channelId", channel_get_id(ch)); htsmsg_add_str(m, "method", "channelDelete"); - htsp_async_send(m, HTSP_ASYNC_ON, HTSP_ASYNC_AUX_CH, ch); + htsp_async_send(m, HTSP_ASYNC_ON, ch); } +/** + * + */ +static htsmsg_t * +htsp_tag_update_msg(htsp_connection_t *htsp, void *tag) +{ + if (!channel_tag_access(tag, htsp->htsp_granted_access, 0)) + return NULL; + return htsp_build_tag(htsp, tag, "tagUpdate", 1); +} /** * Called from channel.c when a tag is exported @@ -3653,21 +3689,17 @@ htsp_channel_delete(channel_t *ch) void htsp_tag_add(channel_tag_t *ct) { - htsp_async_send(htsp_build_tag(ct, "tagAdd", 1), HTSP_ASYNC_ON, - HTSP_ASYNC_AUX_CHTAG, ct); + htsp_async_send_cb(htsp_tag_update_msg, HTSP_ASYNC_ON, ct); } - /** * Called from channel.c when an exported tag is changed */ void htsp_tag_update(channel_tag_t *ct) { - if (ct->ct_enabled && !ct->ct_internal) { - htsp_async_send(htsp_build_tag(ct, "tagUpdate", 1), HTSP_ASYNC_ON, - HTSP_ASYNC_AUX_CHTAG, ct); - } + if (ct->ct_enabled && !ct->ct_internal) + htsp_async_send_cb(htsp_tag_update_msg, HTSP_ASYNC_ON, ct); else // in case the tag was ever sent to the client htsp_tag_delete(ct); } @@ -3682,7 +3714,7 @@ htsp_tag_delete(channel_tag_t *ct) htsmsg_t *m = htsmsg_create_map(); htsmsg_add_u32(m, "tagId", htsp_channel_tag_get_identifier(ct)); htsmsg_add_str(m, "method", "tagDelete"); - htsp_async_send(m, HTSP_ASYNC_ON, HTSP_ASYNC_AUX_CHTAG_DEL, ct); + htsp_async_send(m, HTSP_ASYNC_ON, ct); } /** @@ -3712,7 +3744,6 @@ htsp_dvr_entry_add(dvr_entry_t *de) _htsp_dvr_entry_update(de, "dvrEntryAdd", NULL); } - /** * Called from dvr_db.c when a DVR entry is updated */ @@ -3739,7 +3770,6 @@ htsp_dvr_entry_update_stats(dvr_entry_t *de) } } - /** * Called from dvr_db.c when a DVR entry is deleted */ @@ -3749,7 +3779,7 @@ htsp_dvr_entry_delete(dvr_entry_t *de) htsmsg_t *m = htsmsg_create_map(); htsmsg_add_u32(m, "id", idnode_get_short_uuid(&de->de_id)); htsmsg_add_str(m, "method", "dvrEntryDelete"); - htsp_async_send(m, HTSP_ASYNC_ON, HTSP_ASYNC_AUX_DVR, de); + htsp_async_send(m, HTSP_ASYNC_ON, de); } /** @@ -3803,7 +3833,7 @@ htsp_autorec_entry_delete(dvr_autorec_entry_t *dae) htsmsg_t *m = htsmsg_create_map(); htsmsg_add_str(m, "id", idnode_uuid_as_str(&dae->dae_id, ubuf)); htsmsg_add_str(m, "method", "autorecEntryDelete"); - htsp_async_send(m, HTSP_ASYNC_ON, HTSP_ASYNC_AUX_AUTOREC, dae); + htsp_async_send(m, HTSP_ASYNC_ON, dae); } /** @@ -3857,7 +3887,7 @@ htsp_timerec_entry_delete(dvr_timerec_entry_t *dte) htsmsg_t *m = htsmsg_create_map(); htsmsg_add_str(m, "id", idnode_uuid_as_str(&dte->dte_id, ubuf)); htsmsg_add_str(m, "method", "timerecEntryDelete"); - htsp_async_send(m, HTSP_ASYNC_ON, HTSP_ASYNC_AUX_TIMEREC, dte); + htsp_async_send(m, HTSP_ASYNC_ON, dte); } /** @@ -3951,7 +3981,7 @@ htsp_event_delete(epg_broadcast_t *ebc) htsmsg_t *m = htsmsg_create_map(); htsmsg_add_str(m, "method", "eventDelete"); htsmsg_add_u32(m, "eventId", ebc->id); - htsp_async_send(m, HTSP_ASYNC_EPG, HTSP_ASYNC_AUX_EPG, ebc); + htsp_async_send(m, HTSP_ASYNC_EPG, ebc); } static const char frametypearray[PKT_NTYPES] = { diff --git a/src/http.c b/src/http.c index dd852047c..a11caf80d 100644 --- a/src/http.c +++ b/src/http.c @@ -909,19 +909,18 @@ http_extra_send_prealloc(http_connection_t *hc, const void *data, * */ char * -http_get_hostpath(http_connection_t *hc) +http_get_hostpath(http_connection_t *hc, char *buf, size_t buflen) { - char buf[256]; const char *host, *proto; host = http_arg_get(&hc->hc_args, "Host") ?: http_arg_get(&hc->hc_args, "X-Forwarded-Host"); proto = http_arg_get(&hc->hc_args, "X-Forwarded-Proto"); - snprintf(buf, sizeof(buf), "%s://%s%s", + snprintf(buf, buflen, "%s://%s%s", proto ?: "http", host ?: "localhost", tvheadend_webroot ?: ""); - return strdup(buf); + return buf; } /** diff --git a/src/http.h b/src/http.h index e193717e9..6c6bb6cd8 100644 --- a/src/http.h +++ b/src/http.h @@ -326,7 +326,7 @@ int http_access_verify_channel(http_connection_t *hc, int mask, void http_parse_args(http_arg_list_t *list, char *args); -char *http_get_hostpath(http_connection_t *hc); +char *http_get_hostpath(http_connection_t *hc, char *buf, size_t buflen); /* * HTTP/RTSP Client diff --git a/src/imagecache.c b/src/imagecache.c index 7188404cd..502c466ab 100644 --- a/src/imagecache.c +++ b/src/imagecache.c @@ -37,7 +37,8 @@ typedef struct imagecache_image { int id; ///< Internal ID const char *url; ///< Upstream URL - int failed; ///< Last update failed + uint8_t failed; ///< Last update failed + uint8_t savepend; ///< Pending save time_t accessed; ///< Last time the file was accessed time_t updated; ///< Last time the file was checked uint8_t sha1[20]; ///< Contents hash @@ -58,7 +59,6 @@ static RB_HEAD(,imagecache_image) imagecache_by_id; static RB_HEAD(,imagecache_image) imagecache_by_url; SKEL_DECLARE(imagecache_skel, imagecache_image_t); -#if ENABLE_IMAGECACHE struct imagecache_config imagecache_conf = { .idnode.in_class = &imagecache_class, }; @@ -128,10 +128,8 @@ const idclass_t imagecache_class = { static tvh_cond_t imagecache_cond; static TAILQ_HEAD(, imagecache_image) imagecache_queue; static mtimer_t imagecache_timer; -#endif -#if ENABLE_IMAGECACHE -static int +static inline int sha1_empty( const uint8_t *sha1 ) { int i; @@ -140,7 +138,6 @@ sha1_empty( const uint8_t *sha1 ) return 0; return 1; } -#endif static int url_cmp ( imagecache_image_t *a, imagecache_image_t *b ) @@ -154,7 +151,6 @@ id_cmp ( imagecache_image_t *a, imagecache_image_t *b ) return (a->id - b->id); } -#if ENABLE_IMAGECACHE static htsmsg_t * imagecache_image_htsmsg ( imagecache_image_t *img ) { @@ -175,6 +171,7 @@ imagecache_image_htsmsg ( imagecache_image_t *img ) static void imagecache_image_save ( imagecache_image_t *img ) { + img->savepend = 1; if (img->state != SAVE && img->state != QUEUED && img->state != FETCHING) { img->state = SAVE; TAILQ_INSERT_TAIL(&imagecache_queue, img, q_link); @@ -182,7 +179,6 @@ imagecache_image_save ( imagecache_image_t *img ) } } - static void imagecache_new_id ( imagecache_image_t *i ) { @@ -199,6 +195,7 @@ static void imagecache_image_add ( imagecache_image_t *img ) { int oldstate = img->state; + if (!imagecache_conf.enabled) return; if (strncasecmp("file://", img->url, 7)) { img->state = QUEUED; if (oldstate != SAVE && oldstate != QUEUED) @@ -380,10 +377,12 @@ imagecache_thread ( void *p ) TAILQ_REMOVE(&imagecache_queue, img, q_link); +retry: if (img->state == SAVE) { /* Do save outside global mutex */ htsmsg_t *m = imagecache_image_htsmsg(img); img->state = IDLE; + img->savepend = 0; tvh_mutex_unlock(&global_lock); hts_settings_save(m, "imagecache/meta/%d", img->id); htsmsg_destroy(m); @@ -391,8 +390,14 @@ imagecache_thread ( void *p ) } else if (img->state == QUEUED) { /* Fetch */ - img->state = FETCHING; - (void)imagecache_image_fetch(img); + if (imagecache_conf.enabled) { + img->state = FETCHING; + (void)imagecache_image_fetch(img); + } + if (img->savepend) { + img->state = SAVE; + goto retry; + } img->state = IDLE; } else { @@ -427,8 +432,6 @@ imagecache_timer_cb ( void *p ) } } -#endif /* ENABLE_IMAGECACHE */ - /* * Initialise */ @@ -444,8 +447,7 @@ imagecache_init ( void ) int id; /* Init vars */ - imagecache_id = 0; -#if ENABLE_IMAGECACHE + imagecache_id = 0; imagecache_conf.enabled = 0; imagecache_conf.expire = 7; // 7 days imagecache_conf.ok_period = 24 * 7; // weekly @@ -453,21 +455,16 @@ imagecache_init ( void ) imagecache_conf.ignore_sslcert = 0; idclass_register(&imagecache_class); -#endif /* Create threads */ -#if ENABLE_IMAGECACHE tvh_cond_init(&imagecache_cond, 1); TAILQ_INIT(&imagecache_queue); -#endif /* Load settings */ -#if ENABLE_IMAGECACHE if ((m = hts_settings_load("imagecache/config"))) { idnode_load(&imagecache_conf.idnode, m); htsmsg_destroy(m); } -#endif if ((m = hts_settings_load("imagecache/meta"))) { HTSMSG_FOREACH(f, m) { if (!(e = htsmsg_get_map_by_field(f))) continue; @@ -491,21 +488,18 @@ imagecache_init ( void ) } i = RB_INSERT_SORTED(&imagecache_by_id, img, id_link, id_cmp); assert(!i); -#if ENABLE_IMAGECACHE if (img->accessed == 0) { img->accessed = gclk(); imagecache_image_save(img); } if (!img->updated) imagecache_image_add(img); -#endif if (imagecache_id <= id) imagecache_id = id + 1; } htsmsg_destroy(m); } -#if ENABLE_IMAGECACHE /* Start threads */ tvh_thread_create(&imagecache_tid, NULL, imagecache_thread, NULL, "imagecache"); @@ -514,7 +508,6 @@ imagecache_init ( void ) // the reality its not necessary and I'd prefer to avoid dumping // 100's of timers into the global pool mtimer_arm_rel(&imagecache_timer, imagecache_timer_cb, NULL, sec2mono(600)); -#endif } @@ -542,22 +535,18 @@ imagecache_done ( void ) { imagecache_image_t *img; -#if ENABLE_IMAGECACHE tvh_mutex_lock(&global_lock); mtimer_disarm(&imagecache_timer); tvh_mutex_unlock(&global_lock); tvh_cond_signal(&imagecache_cond, 1); pthread_join(imagecache_tid, NULL); -#endif tvh_mutex_lock(&global_lock); while ((img = RB_FIRST(&imagecache_by_id)) != NULL) { -#if ENABLE_IMAGECACHE if (img->state == SAVE) { htsmsg_t *m = imagecache_image_htsmsg(img); hts_settings_save(m, "imagecache/meta/%d", img->id); htsmsg_destroy(m); } -#endif imagecache_destroy(img, 0); } tvh_mutex_unlock(&global_lock); @@ -565,8 +554,6 @@ imagecache_done ( void ) } -#if ENABLE_IMAGECACHE - /* * Class save */ @@ -644,20 +631,19 @@ imagecache_trigger( void ) } } -#endif /* ENABLE_IMAGECACHE */ - /* * Fetch a URLs ID + * + * If imagecache is not enabled, just manage the id<->local filename + * mapping database. */ int imagecache_get_id ( const char *url ) { int id = 0; imagecache_image_t *i; -#if ENABLE_IMAGECACHE int save = 0; time_t clk; -#endif lock_assert(&global_lock); @@ -666,10 +652,8 @@ imagecache_get_id ( const char *url ) return 0; /* Disabled */ -#if !ENABLE_IMAGECACHE - if (strncasecmp(url, "file://", 7)) + if (!imagecache_conf.enabled && strncasecmp(url, "file://", 7)) return 0; -#endif /* Skeleton */ SKEL_ALLOC(imagecache_skel); @@ -681,21 +665,15 @@ imagecache_get_id ( const char *url ) i = imagecache_skel; i->url = strdup(url); SKEL_USED(imagecache_skel); -#if ENABLE_IMAGECACHE + save = 1; imagecache_new_id(i); imagecache_image_add(i); - save = 1; -#endif } -#if ENABLE_IMAGECACHE - if (!strncasecmp(url, "file://", 7) || imagecache_conf.enabled) - id = i->id; -#else - if (!strncasecmp(url, "file://", 7)) + + /* Do file:// to imagecache ID mapping even if imagecache is not enabled */ + if (imagecache_conf.enabled || !strncasecmp(url, "file://", 7)) id = i->id; -#endif -#if ENABLE_IMAGECACHE clk = gclk(); if (clk != i->accessed) { i->accessed = clk; @@ -703,10 +681,21 @@ imagecache_get_id ( const char *url ) } if (save) imagecache_image_save(i); -#endif return id; } +/* + * + */ +const char * +imagecache_get_propstr ( const char *image, char *buf, size_t buflen ) +{ + int id = imagecache_get_id(image); + if (id == 0) return image; + snprintf(buf, buflen, "imagecache/%d", id); + return buf; +} + /* * Get data */ @@ -731,7 +720,6 @@ imagecache_filename ( int id, char *name, size_t len ) } /* Remote file */ -#if ENABLE_IMAGECACHE else if (imagecache_conf.enabled) { int e; int64_t mono; @@ -759,7 +747,6 @@ imagecache_filename ( int id, char *name, size_t len ) if (hts_settings_buildpath(name, len, "imagecache/data/%d", i->id)) return -1; } -#endif return 0; } diff --git a/src/imagecache.h b/src/imagecache.h index c0c91d298..5a2d0e19b 100644 --- a/src/imagecache.h +++ b/src/imagecache.h @@ -36,15 +36,17 @@ extern const idclass_t imagecache_class; extern tvh_mutex_t imagecache_mutex; -void imagecache_init ( void ); -void imagecache_done ( void ); +void imagecache_init ( void ); +void imagecache_done ( void ); -void imagecache_clean ( void ); -void imagecache_trigger ( void ); +void imagecache_clean ( void ); +void imagecache_trigger ( void ); // Note: will return 0 if invalid (must serve original URL) -int imagecache_get_id ( const char *url ); +int imagecache_get_id ( const char *url ); -int imagecache_filename ( int id, char *name, size_t len ); +const char *imagecache_get_propstr ( const char *image, char *buf, size_t buflen ); + +int imagecache_filename ( int id, char *name, size_t len ); #endif /* __IMAGE_CACHE_H__ */ diff --git a/src/main.c b/src/main.c index 83331f9e6..87d6f1270 100644 --- a/src/main.c +++ b/src/main.c @@ -165,9 +165,6 @@ const tvh_caps_t tvheadend_capabilities[] = { #if ENABLE_SATIP_SERVER { "satip_server", NULL }, #endif -#if ENABLE_IMAGECACHE - { "imagecache", (uint32_t*)&imagecache_conf.enabled }, -#endif #if ENABLE_TIMESHIFT { "timeshift", (uint32_t *)×hift_conf.enabled }, #endif diff --git a/src/webui/static/app/config.js b/src/webui/static/app/config.js index 5cce15224..8300274e2 100644 --- a/src/webui/static/app/config.js +++ b/src/webui/static/app/config.js @@ -66,9 +66,6 @@ tvheadend.baseconf = function(panel, index) { tvheadend.imgcacheconf = function(panel, index) { - if (tvheadend.capabilities.indexOf('imagecache') === -1) - return; - var cleanButton = { name: 'clean', builder: function() { diff --git a/src/webui/webui.c b/src/webui/webui.c index 3e46221e7..2d7d135e3 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -508,9 +508,10 @@ http_m3u_playlist_add(htsbuf_queue_t *hq, const char *hostpath, if (urlauth == URLAUTH_TICKET) ticket = access_ticket_create(url_remain, access); htsbuf_append_str(hq, "#EXTINF:-1"); - if (logo) { - if (strncmp(logo, "imagecache/", 11) == 0) { - htsbuf_qprintf(hq, " logo=\"%s/%s", hostpath, logo); + if (!strempty(logo)) { + int id = imagecache_get_id(logo); + if (id) { + htsbuf_qprintf(hq, " logo=\"%s/imagecache/%d", hostpath, id); switch (urlauth) { case URLAUTH_NONE: break; @@ -578,7 +579,7 @@ http_satip_m3u_playlist_add(htsbuf_queue_t *hq, const char *hostpath, const char *name, *logo; idnode_list_mapping_t *ilm; service_t *s = NULL; - int src; + int id, src; LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { /* cannot handle channels with more services for SAT>IP */ @@ -591,16 +592,15 @@ http_satip_m3u_playlist_add(htsbuf_queue_t *hq, const char *hostpath, return; name = channel_get_name(ch, blank); logo = channel_get_icon(ch); + id = imagecache_get_id(logo); snprintf(buf, sizeof(buf), "/stream/channelid/%d", channel_get_id(ch)); htsbuf_append_str(hq, "#EXTINF:-1"); - if (logo) { - if (strncmp(logo, "imagecache/", 11) == 0) { - htsbuf_qprintf(hq, " logo=%s/%s", hostpath, logo); - if (urlauth == URLAUTH_CODE && !strempty(access->aa_auth)) - htsbuf_qprintf(hq, "?auth=%s", access->aa_auth); - } else { - htsbuf_qprintf(hq, " logo=%s", logo); - } + if (id) { + htsbuf_qprintf(hq, " logo=%s/imagecache/%d", hostpath, id); + if (urlauth == URLAUTH_CODE && !strempty(access->aa_auth)) + htsbuf_qprintf(hq, "?auth=%s", access->aa_auth); + } else if (!strempty(logo)) { + htsbuf_qprintf(hq, " logo=%s", logo); } htsbuf_qprintf(hq, ",%s\n%s%s?profile=pass", name, hostpath, buf); if (urlauth == URLAUTH_CODE && !strempty(access->aa_auth)) @@ -615,8 +615,8 @@ static int http_channel_playlist(http_connection_t *hc, int pltype, int urlauth, channel_t *channel) { htsbuf_queue_t *hq; - char buf[255], chnum[32]; - char *profile, *hostpath; + char buf[255], hostpath[512], chnum[32]; + char *profile; const char *name, *blank; const char *lang = hc->hc_access->aa_lang_ui; char ubuf[UUID_HEX_SIZE]; @@ -625,7 +625,7 @@ http_channel_playlist(http_connection_t *hc, int pltype, int urlauth, channel_t return http_noaccess_code(hc); profile = profile_validate_name(http_arg_get(&hc->hc_req_args, "profile")); - hostpath = http_get_hostpath(hc); + http_get_hostpath(hc, hostpath, sizeof(hostpath)); hq = &hc->hc_reply; @@ -654,7 +654,6 @@ http_channel_playlist(http_connection_t *hc, int pltype, int urlauth, channel_t } - free(hostpath); free(profile); return 0; } @@ -667,8 +666,8 @@ static int http_tag_playlist(http_connection_t *hc, int pltype, int urlauth, channel_tag_t *tag) { htsbuf_queue_t *hq; - char buf[255], chnum[32], ubuf[UUID_HEX_SIZE]; - char *profile, *hostpath; + char buf[255], hostpath[512], chnum[32], ubuf[UUID_HEX_SIZE]; + char *profile; const char *name, *blank, *sort, *lang; channel_t *ch; channel_t **chlist; @@ -680,7 +679,7 @@ http_tag_playlist(http_connection_t *hc, int pltype, int urlauth, channel_tag_t lang = hc->hc_access->aa_lang_ui; hq = &hc->hc_reply; profile = profile_validate_name(http_arg_get(&hc->hc_req_args, "profile")); - hostpath = http_get_hostpath(hc); + http_get_hostpath(hc, hostpath, sizeof(hostpath)); sort = http_arg_get(&hc->hc_req_args, "sort"); chlist = channel_get_sorted_list_for_tag(sort, tag, &count); @@ -710,7 +709,6 @@ http_tag_playlist(http_connection_t *hc, int pltype, int urlauth, channel_tag_t } free(chlist); - free(hostpath); free(profile); return 0; } @@ -723,7 +721,7 @@ static int http_tag_list_playlist(http_connection_t *hc, int pltype, int urlauth) { htsbuf_queue_t *hq; - char buf[255]; + char buf[255], hostpath[512]; channel_tag_t *ct; channel_tag_t **ctlist; channel_t *ch; @@ -731,7 +729,7 @@ http_tag_list_playlist(http_connection_t *hc, int pltype, int urlauth) int labelidx = 0; int idx, count = 0; int chidx, chcount = 0; - char *profile, *hostpath; + char *profile; const char *blank, *sort, *lang; idnode_list_mapping_t *ilm; @@ -741,7 +739,7 @@ http_tag_list_playlist(http_connection_t *hc, int pltype, int urlauth) lang = hc->hc_access->aa_lang_ui; hq = &hc->hc_reply; profile = profile_validate_name(http_arg_get(&hc->hc_req_args, "profile")); - hostpath = http_get_hostpath(hc); + http_get_hostpath(hc, hostpath, sizeof(hostpath)); sort = http_arg_get(&hc->hc_req_args, "sort"); ctlist = channel_tag_get_sorted_list(sort, &count); @@ -758,7 +756,8 @@ http_tag_list_playlist(http_connection_t *hc, int pltype, int urlauth) if (pltype == PLAYLIST_M3U) { snprintf(buf, sizeof(buf), "/playlist/tagid/%d", idnode_get_short_uuid(&ct->ct_id)); http_m3u_playlist_add(hq, hostpath, buf, profile, ct->ct_name, NULL, - channel_tag_get_icon(ct), NULL, urlauth, hc->hc_access); + channel_tag_get_icon(ct), + NULL, urlauth, hc->hc_access); } else if (pltype == PLAYLIST_E2) { htsbuf_qprintf(hq, "#SERVICE 1:64:%d:0:0:0:0:0:0:0::%s\n", labelidx++, ct->ct_name); htsbuf_qprintf(hq, "#DESCRIPTION %s\n", ct->ct_name); @@ -784,7 +783,6 @@ http_tag_list_playlist(http_connection_t *hc, int pltype, int urlauth) free(ctlist); free(chlist); - free(hostpath); free(profile); return 0; } @@ -797,11 +795,11 @@ static int http_channel_list_playlist(http_connection_t *hc, int pltype, int urlauth) { htsbuf_queue_t *hq; - char buf[255], chnum[32], ubuf[UUID_HEX_SIZE]; + char buf[255], hostpath[512], chnum[32], ubuf[UUID_HEX_SIZE]; channel_t *ch; channel_t **chlist; int idx = 0, count = 0; - char *profile, *hostpath; + char *profile; const char *name, *blank, *sort, *lang; if (access_verify2(hc->hc_access, ACCESS_STREAMING)) @@ -811,7 +809,7 @@ http_channel_list_playlist(http_connection_t *hc, int pltype, int urlauth) lang = hc->hc_access->aa_lang_ui; profile = profile_validate_name(http_arg_get(&hc->hc_req_args, "profile")); - hostpath = http_get_hostpath(hc); + http_get_hostpath(hc, hostpath, sizeof(hostpath)); sort = http_arg_get(&hc->hc_req_args, "sort"); chlist = channel_get_sorted_list(sort, 0, &count); blank = tvh_gettext_lang(lang, channel_blank_name); @@ -840,7 +838,6 @@ http_channel_list_playlist(http_connection_t *hc, int pltype, int urlauth) } free(chlist); - free(hostpath); free(profile); return 0; } @@ -854,10 +851,9 @@ static int http_dvr_list_playlist(http_connection_t *hc, int pltype, int urlauth) { htsbuf_queue_t *hq; - char buf[255], ubuf[UUID_HEX_SIZE]; + char buf[255], hostpath[512], ubuf[UUID_HEX_SIZE]; dvr_entry_t *de; const char *uuid; - char *hostpath; off_t fsize; time_t durration; struct tm tm; @@ -867,7 +863,7 @@ http_dvr_list_playlist(http_connection_t *hc, int pltype, int urlauth) return HTTP_STATUS_BAD_REQUEST; hq = &hc->hc_reply; - hostpath = http_get_hostpath(hc); + http_get_hostpath(hc, hostpath, sizeof(hostpath)); htsbuf_append_str(hq, "#EXTM3U\n"); LIST_FOREACH(de, &dvrentries, de_global_link) { @@ -909,7 +905,6 @@ http_dvr_list_playlist(http_connection_t *hc, int pltype, int urlauth) htsbuf_append_str(hq, "\n"); } - free(hostpath); return 0; } @@ -920,13 +915,12 @@ static int http_dvr_playlist(http_connection_t *hc, int pltype, int urlauth, dvr_entry_t *de) { htsbuf_queue_t *hq = &hc->hc_reply; - char buf[255], ubuf[UUID_HEX_SIZE]; + char buf[255], hostpath[512], ubuf[UUID_HEX_SIZE]; const char *ticket_id = NULL, *uuid; time_t durration = 0; off_t fsize = 0; int bandwidth = 0, ret = 0; struct tm tm; - char *hostpath; if(pltype != PLAYLIST_M3U) return HTTP_STATUS_BAD_REQUEST; @@ -937,8 +931,8 @@ http_dvr_playlist(http_connection_t *hc, int pltype, int urlauth, dvr_entry_t *d if(dvr_entry_verify(de, hc->hc_access, 1)) return HTTP_STATUS_NOT_FOUND; - hostpath = http_get_hostpath(hc); - durration = dvr_entry_get_stop_time(de) - dvr_entry_get_start_time(de, 0); + http_get_hostpath(hc, hostpath, sizeof(hostpath)); + durration = dvr_entry_get_stop_time(de) - dvr_entry_get_start_time(de, 0); fsize = dvr_get_filesize(de, 0); if(fsize) { @@ -971,7 +965,6 @@ http_dvr_playlist(http_connection_t *hc, int pltype, int urlauth, dvr_entry_t *d ret = HTTP_STATUS_NOT_FOUND; } - free(hostpath); return ret; } @@ -1405,12 +1398,12 @@ static int page_xspf(http_connection_t *hc, const char *remain, void *opaque, int urlauth) { htsbuf_queue_t *hq = &hc->hc_reply; - char buf[80], *hostpath; + char buf[80], hostpath[512]; const char *title, *profile, *ticket, *image, *delim = "?"; if ((title = http_arg_get(&hc->hc_req_args, "title")) == NULL) title = "TVHeadend Stream"; - hostpath = http_get_hostpath(hc); + http_get_hostpath(hc, hostpath, sizeof(hostpath)); htsbuf_qprintf(hq, "\ \r\n\ \r\n\ @@ -1418,7 +1411,6 @@ page_xspf(http_connection_t *hc, const char *remain, void *opaque, int urlauth) \r\n\ %s\r\n\ %s/%s", title, hostpath, remain); - free(hostpath); profile = http_arg_get(&hc->hc_req_args, "profile"); if (profile) { htsbuf_qprintf(hq, "?profile=%s", profile); @@ -1466,17 +1458,16 @@ static int page_m3u(http_connection_t *hc, const char *remain, void *opaque, int urlauth) { htsbuf_queue_t *hq = &hc->hc_reply; - char buf[80], *hostpath; + char buf[80], hostpath[512]; const char *title, *profile, *ticket, *delim = "?"; if ((title = http_arg_get(&hc->hc_req_args, "title")) == NULL) title = "TVHeadend Stream"; - hostpath = http_get_hostpath(hc); + http_get_hostpath(hc, hostpath, sizeof(hostpath)); htsbuf_qprintf(hq, "\ #EXTM3U\r\n\ #EXTINF:-1,%s\r\n\ %s/%s", title, hostpath, remain); - free(hostpath); profile = http_arg_get(&hc->hc_req_args, "profile"); if (profile) { htsbuf_qprintf(hq, "?profile=%s", profile); diff --git a/src/webui/xmltv.c b/src/webui/xmltv.c index d7087c26c..f6ca90a33 100644 --- a/src/webui/xmltv.c +++ b/src/webui/xmltv.c @@ -22,6 +22,7 @@ #include "channels.h" #include "http.h" #include "string_list.h" +#include "imagecache.h" /* * @@ -72,12 +73,14 @@ http_xmltv_channel_add(htsbuf_queue_t *hq, const char *hostpath, channel_t *ch) htsbuf_append_and_escape_xml(hq, channel_get_name(ch, "")); htsbuf_append_str(hq, "\n"); if (icon) { - if (strncmp(icon, "imagecache/", 11) == 0) - htsbuf_qprintf(hq, " \n", hostpath, id); + } else { htsbuf_append_str(hq, " \n"); + htsbuf_append_and_escape_xml(hq, icon); + htsbuf_append_str(hq, "\"/>\n"); + } } htsbuf_append_str(hq, "\n"); } @@ -211,17 +214,16 @@ http_xmltv_programme_add(htsbuf_queue_t *hq, const char *hostpath, channel_t *ch static int http_xmltv_channel(http_connection_t *hc, channel_t *channel) { - char *hostpath; + char hostpath[512]; if (http_access_verify_channel(hc, ACCESS_STREAMING, channel)) return http_noaccess_code(hc); - hostpath = http_get_hostpath(hc); + http_get_hostpath(hc, hostpath, sizeof(hostpath)); http_xmltv_begin(&hc->hc_reply); http_xmltv_channel_add(&hc->hc_reply, hostpath, channel); http_xmltv_programme_add(&hc->hc_reply, hostpath, channel); http_xmltv_end(&hc->hc_reply); - free(hostpath); return 0; } @@ -233,13 +235,13 @@ static int http_xmltv_tag(http_connection_t *hc, channel_tag_t *tag) { idnode_list_mapping_t *ilm; - char *hostpath; + char hostpath[512]; channel_t *ch; if (access_verify2(hc->hc_access, ACCESS_STREAMING)) return http_noaccess_code(hc); - hostpath = http_get_hostpath(hc); + http_get_hostpath(hc, hostpath, sizeof(hostpath)); http_xmltv_begin(&hc->hc_reply); LIST_FOREACH(ilm, &tag->ct_ctms, ilm_in1_link) { @@ -256,7 +258,6 @@ http_xmltv_tag(http_connection_t *hc, channel_tag_t *tag) } http_xmltv_end(&hc->hc_reply); - free(hostpath); return 0; } @@ -267,12 +268,12 @@ static int http_xmltv_channel_list(http_connection_t *hc) { channel_t *ch; - char *hostpath; + char hostpath[512]; if (access_verify2(hc->hc_access, ACCESS_STREAMING)) return http_noaccess_code(hc); - hostpath = http_get_hostpath(hc); + http_get_hostpath(hc, hostpath, sizeof(hostpath)); http_xmltv_begin(&hc->hc_reply); CHANNEL_FOREACH(ch) { @@ -287,7 +288,6 @@ http_xmltv_channel_list(http_connection_t *hc) } http_xmltv_end(&hc->hc_reply); - free(hostpath); return 0; } -- 2.47.2