diff --git a/epg_events.cpp b/epg_events.cpp index 967f30e..c1898d5 100644 --- a/epg_events.cpp +++ b/epg_events.cpp @@ -499,7 +499,7 @@ void AppendScraperData(cToSvConcat<0> &target, cScraperVideo *scraperVideo) { cOrientations(eOrientation::landscape, eOrientation::portrait, eOrientation::banner), false); AppendScraperData(target, s_IMDB_ID, s_image, scraperVideo->getVideoType(), s_title, scraperVideo->getSeasonNumber(), scraperVideo->getEpisodeNumber(), s_episode_name, s_runtime, s_release_date); } -bool appendEpgItem(cToSvConcat<0> &epg_item, RecordingsItemRecPtr &recItem, const cEvent *Event, const cChannel *Channel, bool withChannel, bool form) { +bool appendEpgItem(cToSvConcat<0> &epg_item, RecordingsItemRecPtr &recItem, const cEvent *Event, const cChannel *Channel, bool withChannel) { cGetScraperVideo getScraperVideo(Event, NULL); getScraperVideo.call(LiveSetup().GetPluginScraper()); @@ -512,7 +512,6 @@ bool appendEpgItem(cToSvConcat<0> &epg_item, RecordingsItemRecPtr &recItem, cons epg_item.append(EpgEvents::EncodeDomId(Channel->GetChannelID(), Event->EventID()).c_str() + 6); epg_item.append("\",\""); // [1] : Timer ID - if (form) epg_item.append("-"); // timer id starts with - to indicate that history.back is not working const cTimer* timer = LiveTimerManager().GetTimer(Event->EventID(), Channel->GetChannelID() ); if (timer) epg_item.append(vdrlive::EncodeDomId(LiveTimerManager().GetTimers().GetTimerId(*timer), ".-:", "pmc")); epg_item.append("\","); diff --git a/epg_events.h b/epg_events.h index d4a698c..83572bc 100644 --- a/epg_events.h +++ b/epg_events.h @@ -254,8 +254,7 @@ namespace vdrlive mutable bool m_checkedArchived; mutable std::string m_archived; }; -bool appendEpgItem(cToSvConcat<0> &epg_item, RecordingsItemRecPtr &recItem, const cEvent *Event, const cChannel *Channel, bool withChannel, bool form = false); -// set form = true if history.back is not working because the list of epg items is a result of an html form +bool appendEpgItem(cToSvConcat<0> &epg_item, RecordingsItemRecPtr &recItem, const cEvent *Event, const cChannel *Channel, bool withChannel); }; // namespace vdrlive #endif // VDR_LIVE_EPG_EVENTS_H diff --git a/epgsearch.cpp b/epgsearch.cpp index 93d4c12..16dfc4c 100644 --- a/epgsearch.cpp +++ b/epgsearch.cpp @@ -577,7 +577,7 @@ const cEvent* SearchResult::GetEvent(const cChannel* Channel) return Schedule->GetEvent(m_eventId); } -std::set SearchResults::querySet; +std::vector SearchResults::queryList; void SearchResults::GetByID(int id) { @@ -587,7 +587,7 @@ void SearchResults::GetByID(int id) std::list list = service.handler->QuerySearchTimer(id); m_list.assign( list.begin(), list.end() ); - m_list.sort(); + m_list.sort(); } void SearchResults::GetByQuery(std::string const& query) @@ -601,29 +601,50 @@ void SearchResults::GetByQuery(std::string const& query) m_list.sort(); } -std::string SearchResults::AddQuery(std::string const& query) +std::string SearchResults::AddQuery(cSv query) { - querySet.insert(query); + for (auto it = queryList.begin(); it != queryList.end(); ++it) if (it->Value() == query) { + it->Used(); + return std::string(cToSvXxHash128(query)); + } + queryList.emplace_back(query); return std::string(cToSvXxHash128(query)); } -std::string SearchResults::PopQuery(cSv md5) +std::string SearchResults::GetQuery(cSv md5) { if (md5.empty()) return std::string(); std::string query; - std::set::iterator it; - for (it = querySet.begin(); it != querySet.end(); it++) + for (auto it = queryList.begin(); it != queryList.end(); ++it) { - if(md5 == cSv(cToSvXxHash128(*it))) + if(md5 == cSv(cToSvXxHash128(it->Value() ))) { - query = *it; - querySet.erase(it); + query = it->Value() ; + it->Used(); break; } } return query; } +void SearchResults::CleanQuery() { + time_t now = time(NULL); + size_t old_s = queryList.size(); + for (auto it = queryList.begin(); it != queryList.end();) + { + if(it->IsOutdated(now)) + it = queryList.erase(it); + else + ++it; + } + if (old_s != queryList.size() ) { + size_t mem = 0; + for (auto it = queryList.begin(); it != queryList.end(); ++it) mem += it->Value().length(); + + dsyslog("live, cleanup queryList, size was %zu, is %zu, requ. mem %zu", old_s, queryList.size(), mem); + } +} + RecordingDirs::RecordingDirs(bool shortList) { if (shortList) diff --git a/epgsearch.h b/epgsearch.h index 5c4a63f..f88f866 100644 --- a/epgsearch.h +++ b/epgsearch.h @@ -373,9 +373,21 @@ class SearchResult int m_timerMode; }; +#define QUERYLIFETIME 60*20 // seconds. If a query is not used in this timeframe, it is deleted +class cQueryEntry { +public: + cQueryEntry(cSv queryString): + value(queryString) { Used(); } + bool IsOutdated(time_t now) { return now > outdated_at; } + cSv Value() { return value; } + void Used() { outdated_at = time(NULL) + QUERYLIFETIME; } +private: + time_t outdated_at; + std::string value; +}; class SearchResults { - static std::set querySet; + static std::vector queryList; public: typedef std::list searchresults; typedef searchresults::size_type size_type; @@ -394,8 +406,9 @@ class SearchResults const_iterator end() const { return m_list.end(); } void merge(SearchResults& r) {m_list.merge(r.m_list); m_list.sort();} - static std::string AddQuery(std::string const& query); - static std::string PopQuery(cSv md5); + static std::string AddQuery(cSv query); + static std::string GetQuery(cSv md5); + static void CleanQuery(); private: searchresults m_list; }; diff --git a/live.cpp b/live.cpp index 3f14cf9..0deb412 100644 --- a/live.cpp +++ b/live.cpp @@ -14,6 +14,7 @@ #include "preload.h" #include "users.h" #include "services_live.h" +#include "epgsearch.h" namespace vdrlive { @@ -78,6 +79,10 @@ void Plugin::MainThreadHook(void) LiveTaskManager().DoScheduledTasks(); } +void Plugin::Housekeeping(void) { + SearchResults::CleanQuery(); +} + cString Plugin::Active(void) { return NULL; diff --git a/live.h b/live.h index 228d8a6..650c7a9 100644 --- a/live.h +++ b/live.h @@ -29,6 +29,7 @@ class Plugin : public cPlugin { virtual bool Initialize(void); virtual void Stop(void); virtual void MainThreadHook(void); + virtual void Housekeeping(void); virtual cString Active(void); virtual cMenuSetupPage *SetupMenu(void); virtual bool SetupParse(const char *Name, const char *Value); diff --git a/pages/edit_searchtimer.ecpp b/pages/edit_searchtimer.ecpp index e55e811..50936b7 100644 --- a/pages/edit_searchtimer.ecpp +++ b/pages/edit_searchtimer.ecpp @@ -219,13 +219,29 @@ const char *TNT_ARRAY = ""; if (!testmode) { searchtimers.Save(&searchtimer); - return reply.redirect("searchtimers.html"); + + + + + +<%cpp> +// return reply.redirect("searchtimers.html"); } else { searchtimer.SetId(0); std::string md5 = SearchResults::AddQuery(searchtimer.ToText()); - return reply.redirect("searchresults.html?searchtimerquery=" + md5); + + + + + +<%cpp> +// return reply.redirect("searchresults.html?searchtimerquery=" + md5); } } pageTitle = !searchtimerid.empty() ? tr("Edit search timer") : tr("New search timer"); diff --git a/pages/edit_timer.ecpp b/pages/edit_timer.ecpp index 1ef3359..8da3f21 100644 --- a/pages/edit_timer.ecpp +++ b/pages/edit_timer.ecpp @@ -41,7 +41,6 @@ using namespace vdrlive; std::string aux = ""; std::string directory = ""; int nav_back = 1; - std::string navigate_back = ""; <%session scope="global"> bool logged_in(false); @@ -102,7 +101,6 @@ const cTimer* timer; // dsyslog("live: remote '%s'", remote); LiveTimerManager().UpdateTimer( timerId, remote, oldRemote, flags, channel, weekdays, date, start, stop, priority, lifetime, file, aux ); timerNotifier.SetTimerModification(); - if (navigate_back.empty() ) { @@ -111,10 +109,6 @@ const cTimer* timer; <%cpp> - } else { - timerid.clear(); - return reply.redirect(navigate_back); - } // return reply.redirect("html/back.html"); // return reply.redirect(!edit_timerreferer.empty()?edit_timerreferer:"timers.html"); } else { @@ -209,7 +203,6 @@ const cTimer* timer; - @@ -360,11 +353,7 @@ const cTimer* timer; diff --git a/pages/pageelems.ecpp b/pages/pageelems.ecpp index 9e326a8..530cba2 100644 --- a/pages/pageelems.ecpp +++ b/pages/pageelems.ecpp @@ -157,21 +157,13 @@ function addEvent(s, bottomrow_i, obj) { let bottomrow = '' if (bottomrow_i != 0) bottomrow = 'bottomrow' s.a += `
<$ timer ? tr("Edit timer") : tr("New timer") $>
-% if (navigate_back.empty() ) { -% } else { - -% }
` - if (obj[1].length > 1) { + if (obj[1].length != 0) { s.a += '"; + + +<%cpp> + +// return reply.redirect("searchresults.html?searchtimerquery=" + md5); } pageTitle = tr("Search"); diff --git a/pages/searchresults.ecpp b/pages/searchresults.ecpp index 0da3d80..3cc35fb 100644 --- a/pages/searchresults.ecpp +++ b/pages/searchresults.ecpp @@ -34,7 +34,7 @@ bool logged_in(false); if (!searchtimerid.empty()) results.GetByID(parse_int< int >(searchtimerid)); if (!searchtimerquery.empty()) - results.GetByQuery(SearchResults::PopQuery(searchtimerquery)); + results.GetByQuery(SearchResults::GetQuery(searchtimerquery)); if (!searchplain.empty()) { SearchTimer s; @@ -102,7 +102,7 @@ bool logged_in(false); } StateKey.Remove(); // release channels read lock before calling event_timer which make a timers read lock - recItemFound = appendEpgItem(epg_itemS, recItem, event, channel, true, !searchtimerquery.empty() ); + recItemFound = appendEpgItem(epg_itemS, recItem, event, channel, true); int col_span = 4; if (display_pictures) col_span++; if (current_day != day) {