- controlapi: rework epgsearch code

* /control/epgsearch?<keywords>
 or
* /control/epgsearch?search=<keywords>[&epginfo=false][&format=plain|xml|json]

- add search-function to /control/epg

* /control/epg?search=<keywords>

- mark /control/epgsearchxml as deprecated
This commit is contained in:
svenhoefer
2016-02-15 21:41:10 +01:00
parent 90a3cecb06
commit 5997f42b7e
3 changed files with 180 additions and 174 deletions

View File

@@ -24,8 +24,8 @@
<td><a href="http://box_ip/control/epgsearch">http://box_ip/control/epgsearch</a></td>
</tr>
<tr>
<td><a href="#epgsearchxml">EPG-Suche mit XML Ausgabe</a></td>
<td><a href="http://box_ip/control/epgsearchxml">http://box_ip/control/epgsearchxml</a></td>
<td><a href="#epgsearchxml"><s>EPG-Suche mit XML Ausgabe</s></a></td>
<td><a href="http://box_ip/control/epgsearchxml"><s>http://box_ip/control/epgsearchxml</s></a></td>
</tr>
<tr>
<td><a href="#shutdown">Die Box herunterfahren</a></td>
@@ -415,7 +415,7 @@ Beispiel:<br>
</div>
<br>
<b>Parameter:</b> xml=true&amp;channelid=&lt;channel_id&gt;|channelname=&lt;channel_name&gt;
[&amp;details=true][&amp;max=&lt;max items&gt;][&amp;stoptime=&lt;long:stop time&gt;]<br>
[&amp;details=true][&amp;max=&lt;max items&gt;][&amp;stoptime=&lt;long:stop time&gt;][&amp;search=&lt;keywords&gt;]<br>
<b>R&uuml;ckgabe:</b><br>
Liefert zum angegebenen Sender (angegeben durch channel_id oder channel_name)
das EPG als XML-Liste zur&uuml;ck.<br>
@@ -509,13 +509,17 @@ USA 2005, mit Jerry Stiller, Kevin James, Leah Remini. 20 Min.<br>
fsk:0<br>
Soap/Melodram/Folklore<br>
</div>
<b>Parameter:</b> Suchbegriff;epginfo=false<br>
<br>
<b>Parameter:</b> Suchbegriffe</br>
oder</br>
<b>Parameter:</b> search=Suchbegriffe[&epginfo=false][&format=plain|xml|json]<br>
<b>R&uuml;ckgabe:</b><br>
<br>
Es werden alle Sendungen im EPG zur&uuml;ckgegeben, die den Suchbegriff<br>
im Titel oder Beschreibungstext beinhalten.<br>
Die Treffer lassen sich unter Angabe von epginfo=false auf Treffer im Titel beschr&auml;nken.<br>
Hier werden die Sendungsinhalte (info1 und info2) nicht mitgeliefert.<br>
Die Ausgabe erfolgt im angegebenen Format. Ist kein Format angegeben, wird reiner Text ausgegeben</br>
<br>
<b>R&uuml;ckgabe-Format:</b> Datum Startzeit Monat Wochentag Dauer in Minuten Sender Titel der Sendung<br>
<br>
@@ -538,47 +542,9 @@ Nachrichten<br>
</div>
<!-- ----------------------------------------------------------- -->
<div class="title1"><a name="epgsearchxml"></a><b>EPG-Suche mit XML Ausgabe</b></div>
<div class="URL">Handler: http://box_ip/control/epgsearchxml</div>
<div class="title1"><a name="epgsearchxml"></a><b><s>EPG-Suche mit XML Ausgabe</s> <i>Deprecated!</i></b></div>
<div class="URL"><s>Handler: http://box_ip/control/epgsearchxml</s></div>
<br>
<b>Parameter:</b> keine<br>
<b>R&uuml;ckgabe:</b><br>
<br>
Es werden alle verf&uuml;gbaren EPG-Daten aller Programme in einer XML zur&uuml;ckgegeben. <br>
<div class="example">
Beispiel:<br>
<br>
&gt;&gt;&gt;http://box_ip/control/epgsearchxml<br>
&lt;neutrino commandversion="1"&gt;<br>
&lt;epgsearch&gt;<br>
&lt;channelname&gt;Sparhandy TV&lt;/channelname&gt;<br>
&lt;epgtitle&gt;Homeshopping mit SparhandyTV&lt;/epgtitle&gt;<br>
&lt;info1&gt;SparhandyTV ist der neue Homeshopping-Kanal von Sparhandy und bietet Ihnen
attraktive und g&uuml;nstige Angebote rund um das Thema Mobilfunk.&lt;/info1&gt;<br>
...<br>
</div>
<b>Parameter:</b> Suchbegriff;epginfo=false<br>
<b>R&uuml;ckgabe:</b><br>
<br>
Es werden alle Sendungen im EPG zur&uuml;ckgegeben, die den Suchbegriff<br>
im Titel oder Beschreibungstext beinhalten.<br>
Die Treffer lassen sich unter Angabe von epginfo=false auf Treffer im Titel beschr&auml;nken.<br>
Hier werden die Sendungsinhalte (info1 und info2) nicht mitgeliefert.<br>
<br>
<b>R&uuml;ckgabe-Format:</b> Datum Startzeit Monat Wochentag Dauer in Minuten Sender Titel der Sendung<br>
<br>
<div class="example">
Beispiel:<br>
<br>
&gt;&gt;&gt;http://box_ip/control/epgsearchxml?Nachtmagazin&epginfo=false<br>
&lt;neutrino commandversion="1"&gt;<br>
&lt;epgsearch&gt;<br>
&lt;channelname&gt;Das Erste HD&lt;/channelname&gt;<br>
&lt;epgtitle&gt;Nachtmagazin&lt;/epgtitle&gt;<br>
&lt;fsk&gt;0&lt;/fsk&gt;<br>
&lt;genre&gt;Nachrichten&lt;/genre&gt;<br>
<br>
</div>
<!-- ----------------------------------------------------------- -->
<div class="title1"><a name="shutdown"></a><b>Die Box herunterfahren</b></div>

View File

@@ -1414,111 +1414,144 @@ 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?<keywords>
* or
* /control/epgsearch?search=<keywords>[&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("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
hh->WriteLn("<neutrino commandversion=\"1\">");
}
else{
hh->SetHeader(HTTP_OK, "text/plain; charset=UTF-8"); // default
}
if (xml_format) // to stay backward compatible :/
hh->ParamList["format"] = "xml";
TOutType outType = hh->outStart();
/* 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<t_channel_id> 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();
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<t_channel_id, t_channel_id> ch_id_map;
std::vector<t_channel_id>::iterator it;
for (it = v.begin(); it != v.end(); ++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(!evtlist.empty()){
CEitManager::getInstance()->getEventsServiceKey(0, evtlist, search_epg_item, search_keyword, true);
if (!evtlist.empty())
{
std::map<t_channel_id, t_channel_id>::iterator map_it;
CChannelEventList::iterator e;
for ( e=evtlist.begin(); e!=evtlist.end();++e){
for (e = evtlist.begin(); e != evtlist.end(); ++e)
{
map_it = ch_id_map.find(e->channelID);
if (map_it != ch_id_map.end()){
if (map_it != ch_id_map.end())
{
e->channelID = map_it->second;//map channelID48 to channelID
}
else{
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;
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)) {
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<epgsearch>");
hh->printf("\t\t<channelname>%s</channelname>\n",ZapitTools::UTF8_to_UTF8XML(NeutrinoAPI->GetServiceName(eventIterator->channelID).c_str()).c_str());;
hh->printf("\t\t<epgtitle>%s</epgtitle>\n",ZapitTools::UTF8_to_UTF8XML(epg.title.c_str()).c_str());
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) {
hh->printf("\t\t<info1>%s</info1>\n",ZapitTools::UTF8_to_UTF8XML(epg.info1.c_str()).c_str());
hh->printf("\t\t<info2>%s</info2>\n",ZapitTools::UTF8_to_UTF8XML(epg.info2.c_str()).c_str());
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)) {
hh->printf("\t\t<fsk>%u</fsk>\n", longepg.fsk);
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()){
genere = GetGenre(longepg.contentClassification[0]);
genere = ZapitTools::UTF8_to_UTF8XML(genere.c_str());
hh->printf("\t\t<genre>%s</genre>\n", genere.c_str());
}
if (!longepg.contentClassification.empty())
genre = GetGenre(longepg.contentClassification[0]);
#else
if (longepg.contentClassification) {
genere = GetGenre(longepg.contentClassification);
genere = ZapitTools::UTF8_to_UTF8XML(genere.c_str());
hh->printf("\t\t<genre>%s</genre>\n", genere.c_str());
}
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 );
hh->printf("\t\t<date>%s</date>\n", tmpstr);
result += hh->outPair("date", tmpstr, true);
strftime(tmpstr, sizeof(tmpstr), "%H:%M", tmStartZeit );
hh->printf("\t\t<time>%s</time>\n", tmpstr);
hh->printf("\t\t<duration>%d</duration>\n", eventIterator->duration);
hh->printf("\t\t\t<channel_id>" PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS "</channel_id>\n",eventIterator->channelID);
hh->printf("\t\t\t<eventid>%ld</eventid>\n",eventIterator->eventID);
hh->printf("\t</epgsearch>");
}else{
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;
@@ -1542,28 +1575,29 @@ void CControlAPI::EpgSearchCGI(CyhookHandler *hh, bool xml_format )
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);
genre = GetGenre(longepg.contentClassification[0]);
genre = ZapitTools::UTF8_to_UTF8XML(genre.c_str());
hh->WriteLn(genre);
}
#else
if (longepg.contentClassification) {
genere = GetGenre(longepg.contentClassification);
genere = ZapitTools::UTF8_to_UTF8XML(genere.c_str());
hh->WriteLn(genere);
genre = GetGenre(longepg.contentClassification);
genre = ZapitTools::UTF8_to_UTF8XML(genre.c_str());
hh->WriteLn(genre);
}
#endif
}
hh->WriteLn("----------------------------------------------------------");
}
}
}
if(xml_format)
hh->printf("</neutrino>");
}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?<channelid64> 64Bit, hex
* /control/epg?id=<channelid>
* /control/epg?search=<keywords>
* /control/epg?eventid=<eventid>
* /control/epg?ext
* /control/epg?xml=true&channelid=<channelid>|channelname=<channel name>[&details=true][&max=<max items>][&stoptime=<long:stop time>]
@@ -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

View File

@@ -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);