From 60f959ba59c2449d70efc90b33b4e12a472026bb Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Sat, 17 Jan 2015 22:43:14 +0100 Subject: [PATCH] EPG: implement fulltext search (title, subtitle, summary, description) --- src/api/api_epg.c | 5 +++-- src/epg.c | 27 +++++++++++++++++++++------ src/epg.h | 1 + src/webui/static/app/epg.js | 19 ++++++++++++++++++- 4 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/api/api_epg.c b/src/api/api_epg.c index dac92579..80200b2c 100644 --- a/src/api/api_epg.c +++ b/src/api/api_epg.c @@ -289,11 +289,12 @@ api_epg_grid memset(&eq, 0, sizeof(eq)); lang = htsmsg_get_str(args, "lang"); - eq.lang = lang ? strdup(lang) : NULL; - + if (lang) + eq.lang = strdup(lang); str = htsmsg_get_str(args, "title"); if (str) eq.stitle = strdup(str); + eq.fulltext = htsmsg_get_bool_or_default(args, "fulltext", 0); str = htsmsg_get_str(args, "channel"); if (str) eq.channel = strdup(str); diff --git a/src/epg.c b/src/epg.c index 82f69808..95e596f7 100644 --- a/src/epg.c +++ b/src/epg.c @@ -2263,6 +2263,7 @@ _eq_add ( epg_query_t *eq, epg_broadcast_t *e ) { const char *s, *lang = eq->lang; epg_episode_t *ep; + int fulltext = eq->stitle && eq->fulltext; /* Filtering */ if (e == NULL) return; @@ -2292,22 +2293,36 @@ _eq_add ( epg_query_t *eq, epg_broadcast_t *e ) } if (!r) return; } - if (eq->title.comp != EC_NO || eq->stitle) { + if (fulltext) { + if ((s = epg_episode_get_title(ep, lang)) == NULL || + regexec(&eq->stitle_re, s, 0, NULL, 0)) { + if ((s = epg_episode_get_subtitle(ep, lang)) == NULL || + regexec(&eq->stitle_re, s, 0, NULL, 0)) { + if ((s = epg_broadcast_get_summary(e, lang)) == NULL || + regexec(&eq->stitle_re, s, 0, NULL, 0)) { + if ((s = epg_broadcast_get_description(e, lang)) == NULL || + regexec(&eq->stitle_re, s, 0, NULL, 0)) { + return; + } + } + } + } + } + if (eq->title.comp != EC_NO || (eq->stitle && !fulltext)) { if ((s = epg_episode_get_title(ep, lang)) == NULL) return; - if (eq->stitle) - if (regexec(&eq->stitle_re, s, 0, NULL, 0)) return; - if (_eq_comp_str(&eq->title, s)) return; + if (eq->stitle && !fulltext && regexec(&eq->stitle_re, s, 0, NULL, 0)) return; + if (eq->title.comp != EC_NO && _eq_comp_str(&eq->title, s)) return; } if (eq->subtitle.comp != EC_NO) { if ((s = epg_episode_get_subtitle(ep, lang)) == NULL) return; if (_eq_comp_str(&eq->subtitle, s)) return; } if (eq->summary.comp != EC_NO) { - if ((s = epg_episode_get_summary(ep, lang)) == NULL) return; + if ((s = epg_broadcast_get_summary(e, lang)) == NULL) return; if (_eq_comp_str(&eq->summary, s)) return; } if (eq->description.comp != EC_NO) { - if ((s = epg_episode_get_description(ep, lang)) == NULL) return; + if ((s = epg_broadcast_get_description(e, lang)) == NULL) return; if (_eq_comp_str(&eq->description, s)) return; } diff --git a/src/epg.h b/src/epg.h index 28c5791e..a93e64b6 100644 --- a/src/epg.h +++ b/src/epg.h @@ -579,6 +579,7 @@ typedef struct epg_query { epg_filter_num_t channel_num; char *stitle; regex_t stitle_re; + int fulltext; char *channel; char *channel_tag; uint32_t genre_count; diff --git a/src/webui/static/app/epg.js b/src/webui/static/app/epg.js index 36a36318..6bde5223 100644 --- a/src/webui/static/app/epg.js +++ b/src/webui/static/app/epg.js @@ -562,6 +562,10 @@ tvheadend.epg = function() { width: 200 }); + var epgFilterFulltext = new Ext.form.Checkbox({ + width: 20 + }); + // Channels, uses global store var epgFilterChannels = new Ext.form.ComboBox({ @@ -662,6 +666,11 @@ tvheadend.epg = function() { epgFilterTitle.setValue(""); }; + clearFulltextFilter = function() { + delete epgStore.baseParams.fulltext; + epgFilterFulltext.setValue(0); + }; + clearChannelFilter = function() { delete epgStore.baseParams.channel; epgFilterChannels.setValue(""); @@ -685,6 +694,7 @@ tvheadend.epg = function() { function epgQueryClear() { clearTitleFilter(); + clearFulltextFilter(); clearChannelFilter(); clearChannelTagsFilter(); clearDurationFilter(); @@ -752,6 +762,13 @@ tvheadend.epg = function() { } }); + epgFilterFulltext.on('check', function(c, value) { + if (epgStore.baseParams.fulltext !== value) { + epgStore.baseParams.fulltext = value; + epgView.reset(); + } + }); + var epgView = new Ext.ux.grid.livegrid.GridView({ nearLimit: 100, loadMask: { @@ -777,7 +794,7 @@ tvheadend.epg = function() { }); var tbar = [ - epgFilterTitle, '-', + epgFilterTitle, { text: 'Fulltext' }, epgFilterFulltext, '-', epgFilterChannels, '-', epgFilterChannelTags, '-', epgFilterContentGroup, '-',