diff --git a/src/nhttpd/doc/nhttpd_controlapi.html b/src/nhttpd/doc/nhttpd_controlapi.html index 4a215504f..d7ce3fba6 100644 --- a/src/nhttpd/doc/nhttpd_controlapi.html +++ b/src/nhttpd/doc/nhttpd_controlapi.html @@ -24,8 +24,8 @@ http://box_ip/control/epgsearch - EPG-Suche mit XML Ausgabe - http://box_ip/control/epgsearchxml + EPG-Suche mit XML Ausgabe + http://box_ip/control/epgsearchxml Die Box herunterfahren @@ -415,7 +415,7 @@ Beispiel:

Parameter: xml=true&channelid=<channel_id>|channelname=<channel_name> -[&details=true][&max=<max items>][&stoptime=<long:stop time>]
+[&details=true][&max=<max items>][&stoptime=<long:stop time>][&search=<keywords>]
Rückgabe:
Liefert zum angegebenen Sender (angegeben durch channel_id oder channel_name) das EPG als XML-Liste zurück.
@@ -509,13 +509,17 @@ USA 2005, mit Jerry Stiller, Kevin James, Leah Remini. 20 Min.
fsk:0
Soap/Melodram/Folklore
-Parameter: Suchbegriff;epginfo=false
+
+Parameter: Suchbegriffe
+oder
+Parameter: search=Suchbegriffe[&epginfo=false][&format=plain|xml|json]
Rückgabe:

Es werden alle Sendungen im EPG zurückgegeben, die den Suchbegriff
im Titel oder Beschreibungstext beinhalten.
Die Treffer lassen sich unter Angabe von epginfo=false auf Treffer im Titel beschränken.
Hier werden die Sendungsinhalte (info1 und info2) nicht mitgeliefert.
+Die Ausgabe erfolgt im angegebenen Format. Ist kein Format angegeben, wird reiner Text ausgegeben

Rückgabe-Format: Datum Startzeit Monat Wochentag Dauer in Minuten Sender Titel der Sendung

@@ -538,47 +542,9 @@ Nachrichten
-
EPG-Suche mit XML Ausgabe
-
Handler: http://box_ip/control/epgsearchxml
+
EPG-Suche mit XML Ausgabe Deprecated!
+
Handler: http://box_ip/control/epgsearchxml

-Parameter: keine
-Rückgabe:
-
-Es werden alle verfügbaren EPG-Daten aller Programme in einer XML zurückgegeben.
-
-Beispiel:
-
->>>http://box_ip/control/epgsearchxml
-<neutrino commandversion="1">
-<epgsearch>
-<channelname>Sparhandy TV</channelname>
-<epgtitle>Homeshopping mit SparhandyTV</epgtitle>
-<info1>SparhandyTV ist der neue Homeshopping-Kanal von Sparhandy und bietet Ihnen -attraktive und günstige Angebote rund um das Thema Mobilfunk.</info1>
-...
-
-Parameter: Suchbegriff;epginfo=false
-Rückgabe:
-
-Es werden alle Sendungen im EPG zurückgegeben, die den Suchbegriff
-im Titel oder Beschreibungstext beinhalten.
-Die Treffer lassen sich unter Angabe von epginfo=false auf Treffer im Titel beschränken.
-Hier werden die Sendungsinhalte (info1 und info2) nicht mitgeliefert.
-
-Rückgabe-Format: Datum Startzeit Monat Wochentag Dauer in Minuten Sender Titel der Sendung
-
-
-Beispiel:
-
->>>http://box_ip/control/epgsearchxml?Nachtmagazin&epginfo=false
-<neutrino commandversion="1">
-<epgsearch>
-<channelname>Das Erste HD</channelname>
-<epgtitle>Nachtmagazin</epgtitle>
-<fsk>0</fsk>
-<genre>Nachrichten</genre>
-
-
Die Box herunterfahren
diff --git a/src/nhttpd/tuxboxapi/controlapi.cpp b/src/nhttpd/tuxboxapi/controlapi.cpp index 2f2150406..6671dff1a 100644 --- a/src/nhttpd/tuxboxapi/controlapi.cpp +++ b/src/nhttpd/tuxboxapi/controlapi.cpp @@ -1414,156 +1414,190 @@ extern const char * GetGenre(const unsigned char contentClassification); // UTF- void CControlAPI::EpgSearchXMLCGI(CyhookHandler *hh) { - EpgSearchCGI(hh, true); //xml_format = true + SendFoundEvents(hh, true); } +//------------------------------------------------------------------------- +/** Return EPG search data + * @param hh CyhookHandler + * + * @par nhttpd-usage + * @code + * /control/epgsearch? + * or + * /control/epgsearch?search=[&epginfo=false][&format=plain|xml|json] + * @endcode + */ + +//------------------------------------------------------------------------- void CControlAPI::EpgSearchTXTCGI(CyhookHandler *hh) { - EpgSearchCGI(hh, false); //xml_format = false + SendFoundEvents(hh); } -void CControlAPI::EpgSearchCGI(CyhookHandler *hh, bool xml_format ) +void CControlAPI::SendFoundEvents(CyhookHandler *hh, bool xml_format) { + if (hh->ParamList.empty()) + { + hh->SendError(); + return; + } + + std::string result; + std::string epgsearch = ""; t_channel_id channel_id; CChannelEventList evtlist; - if (!hh->ParamList.empty()) { - bool search_epginfo = true; - if (hh->ParamList["epginfo"] == "false") - search_epginfo = false; + bool search_epginfo = (hh->ParamList["epginfo"] != "false"); - const int m_search_epg_item = search_epginfo ? 5 /*SEARCH_EPG_ALL*/ : 1 /*SEARCH_EPG_TITLE*/; - std::string m_search_keyword = hh->ParamList["1"]; + std::string search_keyword = (hh->ParamList["search"].empty()) ? hh->ParamList["1"] : hh->ParamList["search"]; + const int search_epg_item = search_epginfo ? 5 /*SEARCH_EPG_ALL*/ : 1 /*SEARCH_EPG_TITLE*/; - if(xml_format){ - hh->SetHeader(HTTP_OK, "text/xml; charset=UTF-8"); - hh->WriteLn(""); - hh->WriteLn(""); - } - else{ - hh->SetHeader(HTTP_OK, "text/plain; charset=UTF-8"); // default - } - - std::vector v; - int channel_nr = CNeutrinoApp::getInstance ()->channelList->getSize();//unique channelList TV or Radio - for(int channel = 0; channel < channel_nr; channel++){ - channel_id = CNeutrinoApp::getInstance ()->channelList->getChannelFromIndex(channel)->getChannelID(); - v.push_back(channel_id); - } - std::map ch_id_map; - std::vector::iterator it; - for (it = v.begin(); it != v.end(); ++it){ - ch_id_map[*it & 0xFFFFFFFFFFFFULL] = *it; - } - CEitManager::getInstance()->getEventsServiceKey(0,evtlist, m_search_epg_item,m_search_keyword, true);//all_chann + if (xml_format) // to stay backward compatible :/ + hh->ParamList["format"] = "xml"; + TOutType outType = hh->outStart(); - if(!evtlist.empty()){ - std::map::iterator map_it; - CChannelEventList::iterator e; - for ( e=evtlist.begin(); e!=evtlist.end();++e){ - map_it = ch_id_map.find(e->channelID); - if (map_it != ch_id_map.end()){ - e->channelID = map_it->second;//map channelID48 to channelID - } - else{ - evtlist.erase(e--);// remove event for not found channels in channelList - } + /* TODO: maybe add following options as in tuxbox neutrino + hh->ParamList["epgitem"] + hh->ParamList["mode"] + hh->ParamList["channelid"] + hh->ParamList["channelname"] + hh->ParamList["bouquet"] + */ + + std::vector v; + int channel_nr = CNeutrinoApp::getInstance()->channelList->getSize(); //unique channelList TV or Radio + for (int channel = 0; channel < channel_nr; channel++) + { + channel_id = CNeutrinoApp::getInstance()->channelList->getChannelFromIndex(channel)->getChannelID(); + v.push_back(channel_id); + } + std::map ch_id_map; + std::vector::iterator it; + for (it = v.begin(); it != v.end(); ++it) + { + ch_id_map[*it & 0xFFFFFFFFFFFFULL] = *it; + } + + CEitManager::getInstance()->getEventsServiceKey(0, evtlist, search_epg_item, search_keyword, true); + + if (!evtlist.empty()) + { + std::map::iterator map_it; + CChannelEventList::iterator e; + for (e = evtlist.begin(); e != evtlist.end(); ++e) + { + map_it = ch_id_map.find(e->channelID); + if (map_it != ch_id_map.end()) + { + e->channelID = map_it->second;//map channelID48 to channelID + } + else + { + evtlist.erase(e--);// remove event for not found channels in channelList } } - if(!evtlist.empty()){ - sort(evtlist.begin(),evtlist.end(),sortByDateTime); - } + } + if (!evtlist.empty()) + { + sort(evtlist.begin(), evtlist.end(), sortByDateTime); + } - time_t azeit=time(NULL); - CShortEPGData epg; - CEPGData longepg; - char tmpstr[256] ={0}; - std::string genere; - CChannelEventList::iterator eventIterator; - unsigned int u_azeit = ( azeit > -1)? azeit:0; - for (eventIterator = evtlist.begin(); eventIterator != evtlist.end(); ++eventIterator){ - if (CEitManager::getInstance()->getEPGidShort(eventIterator->eventID, &epg)) { - if( (eventIterator->startTime+eventIterator->duration) < u_azeit) - continue; - struct tm *tmStartZeit = localtime(&eventIterator->startTime); - if(xml_format){ - hh->printf("\t"); - hh->printf("\t\t%s\n",ZapitTools::UTF8_to_UTF8XML(NeutrinoAPI->GetServiceName(eventIterator->channelID).c_str()).c_str());; - hh->printf("\t\t%s\n",ZapitTools::UTF8_to_UTF8XML(epg.title.c_str()).c_str()); - if (search_epginfo) { - hh->printf("\t\t%s\n",ZapitTools::UTF8_to_UTF8XML(epg.info1.c_str()).c_str()); - hh->printf("\t\t%s\n",ZapitTools::UTF8_to_UTF8XML(epg.info2.c_str()).c_str()); - } - if (CEitManager::getInstance()->getEPGid(eventIterator->eventID, eventIterator->startTime, &longepg)) { - hh->printf("\t\t%u\n", longepg.fsk); -#ifdef FULL_CONTENT_CLASSIFICATION - if (!longepg.contentClassification.empty()){ - genere = GetGenre(longepg.contentClassification[0]); - genere = ZapitTools::UTF8_to_UTF8XML(genere.c_str()); - hh->printf("\t\t%s\n", genere.c_str()); - } -#else - if (longepg.contentClassification) { - genere = GetGenre(longepg.contentClassification); - genere = ZapitTools::UTF8_to_UTF8XML(genere.c_str()); - hh->printf("\t\t%s\n", genere.c_str()); - } -#endif - } - strftime(tmpstr, sizeof(tmpstr), "%Y-%m-%d", tmStartZeit ); - hh->printf("\t\t%s\n", tmpstr); - strftime(tmpstr, sizeof(tmpstr), "%H:%M", tmStartZeit ); - hh->printf("\t\t\n", tmpstr); - hh->printf("\t\t%d\n", eventIterator->duration); - hh->printf("\t\t\t" PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS "\n",eventIterator->channelID); - hh->printf("\t\t\t%ld\n",eventIterator->eventID); - hh->printf("\t"); - }else{ - std::string datetimer_str ; - strftime(tmpstr, sizeof(tmpstr), "%Y-%m-%d %H:%M", tmStartZeit ); - datetimer_str = tmpstr; - datetimer_str += " "; - datetimer_str += g_Locale->getText(CLocaleManager::getMonth(tmStartZeit)); - datetimer_str += " "; - datetimer_str += g_Locale->getText(CLocaleManager::getWeekday(tmStartZeit)); - snprintf(tmpstr, sizeof(tmpstr)," [%d min]",eventIterator->duration / 60); - datetimer_str += tmpstr; - - hh->WriteLn(datetimer_str); - hh->WriteLn(NeutrinoAPI->GetServiceName(eventIterator->channelID)); - hh->WriteLn(epg.title); - if (search_epginfo) { - if(!epg.info1.empty()) - hh->WriteLn(epg.info1); - if(!epg.info2.empty()) - hh->WriteLn(epg.info2); - } - if (CEitManager::getInstance()->getEPGid(eventIterator->eventID, eventIterator->startTime, &longepg)) { - hh->printf("fsk:%u\n", longepg.fsk); -#ifdef FULL_CONTENT_CLASSIFICATION - if (!longepg.contentClassification.empty()){ - genere = GetGenre(longepg.contentClassification[0]); - genere = ZapitTools::UTF8_to_UTF8XML(genere.c_str()); - hh->WriteLn(genere); - } -#else - if (longepg.contentClassification) { - genere = GetGenre(longepg.contentClassification); - genere = ZapitTools::UTF8_to_UTF8XML(genere.c_str()); - hh->WriteLn(genere); - } -#endif - } - hh->WriteLn("----------------------------------------------------------"); + time_t azeit=time(NULL); + CShortEPGData epg; + CEPGData longepg; + char tmpstr[256] ={0}; + std::string genre; + CChannelEventList::iterator eventIterator; + unsigned int u_azeit = ( azeit > -1)? azeit:0; + for (eventIterator = evtlist.begin(); eventIterator != evtlist.end(); ++eventIterator) + { + if (CEitManager::getInstance()->getEPGidShort(eventIterator->eventID, &epg)) + { + if( (eventIterator->startTime+eventIterator->duration) < u_azeit) + continue; + struct tm *tmStartZeit = localtime(&eventIterator->startTime); + result.clear(); + if (hh->outType == json || hh->outType == xml) + { + result += hh->outPair("channelname", NeutrinoAPI->GetServiceName(eventIterator->channelID), true); + result += hh->outPair("epgtitle", epg.title, true); + if (search_epginfo) { + result += hh->outPair("info1", hh->outValue(epg.info1), true); + result += hh->outPair("info2", hh->outValue(epg.info2), true); } + if (CEitManager::getInstance()->getEPGid(eventIterator->eventID, eventIterator->startTime, &longepg)) + { + result += hh->outPair("fsk", string_printf("%c", longepg.fsk), true); + genre = ""; +#ifdef FULL_CONTENT_CLASSIFICATION + if (!longepg.contentClassification.empty()) + genre = GetGenre(longepg.contentClassification[0]); +#else + if (longepg.contentClassification) + genre = GetGenre(longepg.contentClassification); +#endif + result += hh->outPair("genre", ZapitTools::UTF8_to_UTF8XML(genre.c_str()), true); + } + strftime(tmpstr, sizeof(tmpstr), "%Y-%m-%d", tmStartZeit ); + result += hh->outPair("date", tmpstr, true); + strftime(tmpstr, sizeof(tmpstr), "%H:%M", tmStartZeit ); + result += hh->outPair("time", tmpstr, true); + result += hh->outPair("duration", string_printf("%d", eventIterator->duration / 60), true); + result += hh->outPair("channel_id", string_printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, eventIterator->channelID), true); + result += hh->outPair("eventid", string_printf("%ld", eventIterator->eventID), false); + + epgsearch += hh->outCollection("epgsearch", result); + } + else // outType == plain + { + std::string datetimer_str ; + strftime(tmpstr, sizeof(tmpstr), "%Y-%m-%d %H:%M", tmStartZeit ); + datetimer_str = tmpstr; + datetimer_str += " "; + datetimer_str += g_Locale->getText(CLocaleManager::getMonth(tmStartZeit)); + datetimer_str += " "; + datetimer_str += g_Locale->getText(CLocaleManager::getWeekday(tmStartZeit)); + snprintf(tmpstr, sizeof(tmpstr)," [%d min]",eventIterator->duration / 60); + datetimer_str += tmpstr; + + hh->WriteLn(datetimer_str); + hh->WriteLn(NeutrinoAPI->GetServiceName(eventIterator->channelID)); + hh->WriteLn(epg.title); + if (search_epginfo) { + if(!epg.info1.empty()) + hh->WriteLn(epg.info1); + if(!epg.info2.empty()) + hh->WriteLn(epg.info2); + } + if (CEitManager::getInstance()->getEPGid(eventIterator->eventID, eventIterator->startTime, &longepg)) { + hh->printf("fsk:%u\n", longepg.fsk); +#ifdef FULL_CONTENT_CLASSIFICATION + if (!longepg.contentClassification.empty()){ + genre = GetGenre(longepg.contentClassification[0]); + genre = ZapitTools::UTF8_to_UTF8XML(genre.c_str()); + hh->WriteLn(genre); + } +#else + if (longepg.contentClassification) { + genre = GetGenre(longepg.contentClassification); + genre = ZapitTools::UTF8_to_UTF8XML(genre.c_str()); + hh->WriteLn(genre); + } +#endif + } + hh->WriteLn("----------------------------------------------------------"); } } - if(xml_format) - hh->printf(""); - }else - hh->SendError(); - + } + if (outType == json) { + hh->WriteLn(json_out_success(epgsearch)); + } + else if (outType == xml) { + epgsearch = hh->outCollection("neutrino", epgsearch); // to stay backward compatible :/ + hh->WriteLn(epgsearch); + } } //------------------------------------------------------------------------- @@ -1575,6 +1609,7 @@ void CControlAPI::EpgSearchCGI(CyhookHandler *hh, bool xml_format ) * /control/epg * /control/epg? 64Bit, hex * /control/epg?id= + * /control/epg?search= * /control/epg?eventid= * /control/epg?ext * /control/epg?xml=true&channelid=|channelname=[&details=true][&max=][&stoptime=] @@ -1618,6 +1653,10 @@ void CControlAPI::EpgCGI(CyhookHandler *hh) { } } } + else if (!hh->ParamList["search"].empty()) + { + SendFoundEvents(hh, (!hh->ParamList["xml"].empty() || hh->ParamList["format"] == "xml")); + } // query details for given eventid else if (!hh->ParamList["eventid"].empty()) { //special epg query diff --git a/src/nhttpd/tuxboxapi/controlapi.h b/src/nhttpd/tuxboxapi/controlapi.h index 33287b6e0..23a95e61b 100644 --- a/src/nhttpd/tuxboxapi/controlapi.h +++ b/src/nhttpd/tuxboxapi/controlapi.h @@ -31,6 +31,7 @@ private: // send functions for ExecuteCGI (controld api) void SendEventList(CyhookHandler *hh,t_channel_id channel_id); + void SendFoundEvents(CyhookHandler *hh, bool xml_format = false); void SendcurrentVAPid(CyhookHandler *hh); void SendAllCurrentVAPid(CyhookHandler *hh); void SendStreamInfo(CyhookHandler *hh);