From 93cd142c0c97a95dad09e1e67d21ba3dad76b31d Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Wed, 14 Mar 2018 20:12:35 +0000 Subject: [PATCH] MHD connection timeouts, take 2 at save/load EPG filters, new call for: search for other half of programme --- httpdclient.c | 1 + vdrclient.c | 148 ++++++++++++++++++++++++++++++++++++++++++-------- vdrclient.h | 7 +-- 3 files changed, 129 insertions(+), 27 deletions(-) diff --git a/httpdclient.c b/httpdclient.c index 81641f6..e85af17 100644 --- a/httpdclient.c +++ b/httpdclient.c @@ -27,6 +27,7 @@ bool HTTPDClient::StartServer(std::string _docRoot, int port) &HTTPDClient::handle_connection, NULL, MHD_OPTION_NOTIFY_CONNECTION, &HTTPDClient::connection_notify, NULL, MHD_OPTION_NOTIFY_COMPLETED, &HTTPDClient::request_completed, NULL, + MHD_OPTION_CONNECTION_TIMEOUT, 70, MHD_OPTION_END); if (httpdserver == NULL) { logger.reset(); return false; } logger->info("HTTPDClient: Started"); diff --git a/vdrclient.c b/vdrclient.c index f49c96f..04d05e0 100644 --- a/vdrclient.c +++ b/vdrclient.c @@ -28,7 +28,6 @@ VDRClient::VDRClient() VDRClient::~VDRClient() { logger->debug("VDRClient destructor"); - saveEpgFilter(); } bool VDRClient::process(std::string& request, PFMap& postFields, std::string& returnString) @@ -51,6 +50,7 @@ bool VDRClient::process(std::string& request, PFMap& postFields, std::string& re else if (request == "getscheduleevent") success = getscheduleevent(postFields, returnJSON); else if (request == "epgsearch") success = epgsearch(postFields, returnJSON); else if (request == "epgsearchsame") success = epgsearchsame(postFields, returnJSON); + else if (request == "epgsearchotherhalf")success = epgsearchotherhalf(postFields, returnJSON); else if (request == "timerset") success = timerset(postFields, returnJSON); else if (request == "recinfo") success = recinfo(postFields, returnJSON); else if (request == "recstop") success = recstop(postFields, returnJSON); @@ -465,6 +465,97 @@ bool VDRClient::epgsearchsame(PFMap& postFields, Json::Value& js) // RETHROWS return true; } +bool VDRClient::epgsearchotherhalf(PFMap& postFields, Json::Value& js) // RETHROWS +{ + logger->debug("epgsearchotherhalf"); + int channelNumber = getVarInt(postFields, "channelnumber"); + int eventID = getVarInt(postFields, "eventid"); + + cChannel* channel = NULL; + for (channel = Channels.First(); channel; channel = Channels.Next(channel)) + { + if (channel->GroupSep()) continue; + if (channel->Number() == channelNumber) break; + } + + if (!channel) + { + logger->error("epgsearchotherhalf: Could not find requested channel: {}", channelNumber); + js["Result"] = false; + js["Error"] = "Could not find channel"; + return true; + } + + cSchedulesLock MutexLock; + const cSchedules *Schedules = cSchedules::Schedules(MutexLock); + if (!Schedules) + { + logger->error("epgsearchotherhalf: Could not find requested channel: {}", channelNumber); + js["Result"] = false; + js["Error"] = "Internal schedules error (1)"; + return true; + } + const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID()); + if (!Schedule) + { + logger->error("epgsearchotherhalf: Could not find requested channel: {}", channelNumber); + js["Result"] = false; + js["Error"] = "Internal schedules error (2)"; + return true; + } + + js["OtherEventFound"] = false; + + const cEvent* eventM1 = NULL; + const cEvent* eventM2 = NULL; + const cEvent* otherEvent = NULL; + + for (const cEvent* event = Schedule->Events()->First(); event; event = Schedule->Events()->Next(event)) + { + if (event->EventID() == (unsigned long)eventID) + { + if ((eventM2 != NULL) && (!strcmp(eventM2->Title(), event->Title()))) + { + otherEvent = eventM2; + } + else + { + const cEvent* eventP1 = Schedule->Events()->Next(event); + if (eventP1) + { + const cEvent* eventP2 = Schedule->Events()->Next(eventP1); + + if (eventP2 && (!strcmp(eventP2->Title(), event->Title()))) + { + otherEvent = eventP2; + } + } + } + + if (otherEvent) + { + Json::Value oneEvent; + oneEvent["ID"] = otherEvent->EventID(); + oneEvent["ChannelNumber"] = channel->Number(); + oneEvent["Time"] = (Json::UInt)otherEvent->StartTime(); + oneEvent["Duration"] = otherEvent->Duration(); + oneEvent["Title"] = otherEvent->Title() ? otherEvent->Title() : ""; + oneEvent["HasTimer"] = otherEvent->HasTimer(); + js["Event"] = oneEvent; + js["OtherEventFound"] = true; + } + + break; + } + + eventM2 = eventM1; + eventM1 = event; + } + + js["Result"] = true; + return true; +} + bool VDRClient::tunersstatus(PFMap& postFields, Json::Value& js) { logger->debug("tunerstatus"); @@ -1332,7 +1423,8 @@ bool VDRClient::epgfilteradd(PFMap& postFields, Json::Value& js) // RETHROWS logger->debug("epgFilterAdd: {} {}", channel, programme); - if (!loadEpgFilter()) + libconfig::Config epgFilter; + if (!loadEpgFilter(epgFilter)) { js["Result"] = false; js["Error"] = "Error initialising EPG filter"; @@ -1346,6 +1438,13 @@ bool VDRClient::epgfilteradd(PFMap& postFields, Json::Value& js) // RETHROWS libconfig::Setting& newProgramme = newPair.add("p", libconfig::Setting::Type::TypeString); newProgramme = programme; + if (!saveEpgFilter(epgFilter)) + { + js["Result"] = false; + js["Error"] = "Failed to save EPG filter"; + return true; + } + js["Result"] = true; return true; } @@ -1357,7 +1456,8 @@ bool VDRClient::epgfilterdel(PFMap& postFields, Json::Value& js) // RETHROWS logger->debug("epgFilterDel: {} {}", channel, programme); - if (!loadEpgFilter()) + libconfig::Config epgFilter; + if (!loadEpgFilter(epgFilter)) { js["Result"] = false; js["Error"] = "Error initialising EPG filter"; @@ -1384,16 +1484,23 @@ bool VDRClient::epgfilterdel(PFMap& postFields, Json::Value& js) // RETHROWS if ((c == channel) && (p == programme)) { setting.remove(x); + + if (!saveEpgFilter(epgFilter)) + { + js["Result"] = false; + js["Error"] = "Failed to save EPG filter"; + return true; + } + logger->debug("Found and deleted: {} {}", c, p); - break; + js["Result"] = true; + return true; } } - if (x == numFilters) - { - js["Result"] = false; - js["Error"] = "Channel/Programme not found"; - return true; - } + + js["Result"] = false; + js["Error"] = "Channel/Programme not found"; + return true; } catch (std::exception e) { @@ -1401,16 +1508,14 @@ bool VDRClient::epgfilterdel(PFMap& postFields, Json::Value& js) // RETHROWS js["Error"] = "Unknown error"; return true; } - - js["Result"] = true; - return true; } bool VDRClient::epgfilterget(PFMap& postFields, Json::Value& js) // RETHROWS { logger->debug("epgFilterget"); - if (!loadEpgFilter()) + libconfig::Config epgFilter; + if (!loadEpgFilter(epgFilter)) { js["Result"] = false; js["Error"] = "Error initialising EPG filter"; @@ -1440,7 +1545,7 @@ bool VDRClient::epgfilterget(PFMap& postFields, Json::Value& js) // RETHROWS oneFilter["p"] = p; jsfilters.append(oneFilter); } - js["EPG Filters"] = jsfilters; + js["EPGFilters"] = jsfilters; } catch (std::exception e) { @@ -1590,10 +1695,8 @@ std::string VDRClient::getVarString(PFMap& postFields, const char* paramName) // return i->second; } -bool VDRClient::loadEpgFilter() +bool VDRClient::loadEpgFilter(libconfig::Config& epgFilter) { - if (epgFilterLoaded) return true; - const char* configDir = cPlugin::ConfigDirectory("jsonserver"); if (!configDir) { @@ -1641,19 +1744,16 @@ bool VDRClient::loadEpgFilter() setting.add("filters", libconfig::Setting::Type::TypeList); } - epgFilterLoaded = true; return true; } -void VDRClient::saveEpgFilter() +bool VDRClient::saveEpgFilter(libconfig::Config& epgFilter) { - if (!epgFilterLoaded) return; - const char* configDir = cPlugin::ConfigDirectory("jsonserver"); if (!configDir) { logger->error("saveEpgFilter: Error: Could not get config dir from VDR"); - return; + return false; } std::string epgFilterFile(std::string(configDir) + std::string("/epgfilter.conf")); @@ -1661,9 +1761,11 @@ void VDRClient::saveEpgFilter() { epgFilter.writeFile(epgFilterFile.c_str()); logger->debug("saveEpgFilter: EPG filter saved"); + return true; } catch (const libconfig::FileIOException& e) { logger->error("saveEpgFilter: Error: File write error"); + return false; } } diff --git a/vdrclient.h b/vdrclient.h index 2897864..72f160a 100644 --- a/vdrclient.h +++ b/vdrclient.h @@ -38,6 +38,7 @@ class VDRClient bool getscheduleevent(PFMap& postFields, Json::Value& returnJSON); // throws BadParamException bool epgsearch(PFMap& postFields, Json::Value& returnJSON); // throws BadParamException bool epgsearchsame(PFMap& postFields, Json::Value& returnJSON); // throws BadParamException + bool epgsearchotherhalf(PFMap& postFields, Json::Value& returnJSON); // throws BadParamException bool timerset(PFMap& postFields, Json::Value& returnJSON); // throws BadParamException bool recinfo(PFMap& postFields, Json::Value& returnJSON); // throws BadParamException bool recstop(PFMap& postFields, Json::Value& returnJSON); // throws BadParamException @@ -66,10 +67,8 @@ class VDRClient int getVarInt(PFMap& postFields, const char* paramName); // THROWS std::string getVarString(PFMap& postFields, const char* paramName); // THROWS - libconfig::Config epgFilter; - bool epgFilterLoaded = false; - bool loadEpgFilter(); - void saveEpgFilter(); + bool loadEpgFilter(libconfig::Config& epgFilter); + bool saveEpgFilter(libconfig::Config& epgFilter); class BadParamException : public std::exception { -- 2.39.2