1 #include <lib/system/http_dyn.h>
2 #include <lib/dvb/service.h>
3 #include <lib/dvb/epgcache.h>
4 #include <lib/dvb/dvb.h>
5 #include <lib/dvb/servicemp3.h>
8 extern eString
httpUnescape(const eString
&string
);
9 extern eString
httpEscape(const eString
&string
);
10 extern std::map
<eString
,eString
> getRequestOptions(eString opt
, char delimiter
= '&');
11 extern eString
ref2string(const eServiceReference
&r
);
12 extern eServiceReference
string2ref(const eString
&service
);
14 eString
xmlEscape(const eString
&string
)
17 for (unsigned int i
=0; i
<string
.length(); ++i
)
30 static const eString xmlversion
="<?xml version=\"1.0\"?>\n";
31 static inline eString
xmlstylesheet(const eString
&ss
)
33 return eString("<?xml-stylesheet type=\"text/xsl\" href=\"/stylesheets/") + ss
+ ".xsl\"?>\n";
36 static eString
web_root(eString request
, eString dirpath
, eString opts
, eHTTPConnection
*content
)
39 content
->local_header
["Content-Type"]="text/xml; charset=utf-8";
42 ret
+=xmlstylesheet("services");
45 for (int i
=0; i
<10; ++i
)
46 ret
+="<service><name>" + eString().sprintf("Service #%d", i
) + "</name></service>\n";
52 class eServiceToXml
: public Object
55 eServiceInterface
&iface
;
57 eServiceToXml(eString
&result
, eServiceInterface
&iface
): result(result
), iface(iface
)
60 void addEntry(const eServiceReference
&e
)
62 result
+="<service>\n";
63 result
+="<reference>" + ref2string(e
) + "</reference>\n";
64 eService
*service
=iface
.addRef(e
);
67 result
+="<name>" + xmlEscape(service
->service_name
) + "</name>\n";
70 result
+="<dvb><namespace>";
71 result
+=eString().setNum(service
->dvb
->dvb_namespace
.get(), 0x10);
72 result
+="</namespace><tsid>";
73 result
+=eString().setNum(service
->dvb
->transport_stream_id
.get(), 0x10);
74 result
+="</tsid><onid>";
75 result
+=eString().setNum(service
->dvb
->original_network_id
.get(), 0x10);
76 result
+="</onid><sid>";
77 result
+=eString().setNum(service
->dvb
->service_id
.get(), 0x10);
78 result
+="</sid><type>";
79 result
+=eString().setNum(service
->dvb
->service_type
, 0x10);
80 result
+="</type><provider>";
81 result
+=xmlEscape(service
->dvb
->service_provider
);
82 result
+="</provider><number>";
83 result
+=eString().setNum(service
->dvb
->service_number
, 10);
84 result
+="</number></dvb>\n";
89 std::map
<eString
, eString
> & tags
= service
->id3
->getID3Tags();
91 for (std::map
<eString
, eString
>::iterator
i(tags
.begin()); i
!= tags
.end(); ++i
)
92 result
+="<tag id=\"" + i
->first
+ "\"><" + i
->second
+ "<tag/>\n";
98 result
+="</service>\n";
102 static eString
xml_services(eString request
, eString dirpath
, eString opt
, eHTTPConnection
*content
)
104 std::map
<eString
,eString
> opts
=getRequestOptions(opt
);
105 eString spath
=opts
["path"];
107 eServiceInterface
*iface
=eServiceInterface::getInstance();
115 if ((pos
=spath
.rfind(';')) != eString::npos
)
117 current
=spath
.mid(pos
+1);
118 spath
=spath
.left(pos
);
125 eServiceReference current_service
=string2ref(current
);
128 current_service
=eServiceReference(eServiceReference::idStructure
,
129 eServiceReference::isDirectory
, 0);
131 eDebug("current_service: %s", current_service
.path
.c_str());
135 eServiceToXml
conv(res
, *iface
);
137 Signal1
<void,const eServiceReference
&> signal
;
138 signal
.connect(slot(conv
, &eServiceToXml::addEntry
));
141 res
+=xmlstylesheet("services");
144 iface
->enterDirectory(current_service
, signal
);
145 iface
->leaveDirectory(current_service
);
147 res
+="</services>\n";
152 class eHTTPLog
: public eHTTPDataSource
, public Object
156 void recvMessage(int lvl
, const eString
&str
);
159 eHTTPLog(eHTTPConnection
*c
, int mask
, int format
);
165 eHTTPLog::eHTTPLog(eHTTPConnection
*c
, int mask
, int format
):
166 eHTTPDataSource(c
), mask(mask
), format(format
), ok(0)
169 connection
->local_header
["Content-Type"]="text/plain";
170 else if (format
== 1)
171 connection
->local_header
["Content-Type"]="text/html";
172 connection
->code
=200;
173 connection
->code_descr
="OK";
174 CONNECT(logOutput
, eHTTPLog::recvMessage
);
178 toWrite
="<html><head>"
179 "<link type=\"text/css\" rel=\"stylesheet\" href=\"/stylesheets/log.css\">"
180 "<title>Enigma Event Log</title>"
181 "</head><body><pre>\n";
185 int eHTTPLog::doWrite(int hm
)
187 // we don't have YET data to send (but there's much to come)
191 connection
->writeBlock(toWrite
.c_str(), toWrite
.size());
197 void eHTTPLog::recvMessage(int lvl
, const eString
&msg
)
202 if (format
== 0) // text/plain
205 res
.strReplace("\n", "\r\n");
210 eString cl
="unknown";
211 if (lvl
== lvlWarning
)
213 else if (lvl
== lvlFatal
)
215 else if (lvl
== lvlDebug
)
220 res
+="<div class=\"" + cl
+ "\">";
224 // res.strReplace("\n", "<br>\n"); <-- we are <pre>, so no need
227 connection
->writeBlock(res
.c_str(), res
.size());
233 eHTTPLog::~eHTTPLog()
237 eHTTPLogResolver::eHTTPLogResolver()
241 eHTTPDataSource
*eHTTPLogResolver::getDataSource(eString request
, eString path
, eHTTPConnection
*conn
)
243 if ((path
=="/log/debug") && (request
=="GET"))
244 return new eHTTPLog(conn
, -1, 0);
245 if ((path
=="/log/warn") && (request
=="GET"))
246 return new eHTTPLog(conn
, 3, 0);
247 if ((path
=="/log/crit") && (request
=="GET"))
248 return new eHTTPLog(conn
, 1, 0);
250 if ((path
=="/log/debug.html") && (request
=="GET"))
251 return new eHTTPLog(conn
, -1, 1);
252 if ((path
=="/log/warn.html") && (request
=="GET"))
253 return new eHTTPLog(conn
, 3, 1);
254 if ((path
=="/log/crit.html") && (request
=="GET"))
255 return new eHTTPLog(conn
, 1, 1);
259 extern eString
filter_string(eString string
);
261 class ERCServiceHandle
: public Object
263 eString
&result
, search
;
264 eServiceInterface
&iface
;
266 ERCServiceHandle(eString
&result
, eServiceInterface
&iface
, eString search
): result(result
), search(search
.upper()), iface(iface
)
269 void addEntry(const eServiceReference
&e
)
271 eService
*service
=iface
.addRef(e
);
274 if (filter_string(service
->service_name
).upper().find(search
) == eString::npos
)
276 result
+= ref2string(e
) + "\n";
277 result
+= service
->service_name
+ "\n";
283 static eString
erc_services(eString request
, eString dirpath
, eString opt
, eHTTPConnection
*content
)
285 std::map
<eString
,eString
> opts
=getRequestOptions(opt
);
287 eServiceInterface
*iface
=eServiceInterface::getInstance();
288 eServiceReference all_services
=eServiceReference(eServiceReference::idDVB
,
289 eServiceReference::flagDirectory
|eServiceReference::shouldSort
,
295 if (opts
.find("name") == opts
.end())
296 return "-specify name=\n";
298 // search "all dvb services":
302 ERCServiceHandle
conv(res
, *iface
, opts
["name"]);
304 Signal1
<void,const eServiceReference
&> signal
;
305 signal
.connect(slot(conv
, &ERCServiceHandle::addEntry
));
307 iface
->enterDirectory(all_services
, signal
);
308 iface
->leaveDirectory(all_services
);
313 static void processEvent(eString
&res
, EITEvent
*ev
, const eString
&search
, int wantext
)
318 led
.getLocalData(ev
, &title
);
320 if (title
.find(search
) != eString::npos
)
323 res
+= eString().setNum(ev
->event_id
, 0x10);
325 res
+= eString().setNum(ev
->start_time
);
327 res
+= eString().setNum(ev
->duration
);
328 res
+= "\nN: " + title
+ "\n";
330 eString tmpname
,tmptext
;
333 led
.getLocalData(ev
, &tmpname
);
334 if (!tmpname
.isNull())
343 led
.getLocalData(ev
, &tmpname
, 0, &tmptext
);
344 if (!tmptext
.isNull())
350 tmptext
.strReplace("\n", eString("\\n"));
355 for (ePtrList
<Descriptor
>::const_iterator
d(ev
->descriptor
); d
!= ev
->descriptor
.end(); ++d
)
357 if (d
->Tag()==DESCR_SHORT_EVENT
)
359 const ShortEventDescriptor
*s
=(const ShortEventDescriptor
*)*d
;
365 } else if (wantext
&& (d
->Tag() == DESCR_EXTENDED_EVENT
))
367 const ExtendedEventDescriptor
*e
=(ExtendedEventDescriptor
*)*d
;
370 t
.strReplace("\n", eString("\\n"));
378 static eString
erc_epg(eString request
, eString dirpath
, eString opt
, eHTTPConnection
*content
)
380 std::map
<eString
,eString
> opts
=getRequestOptions(opt
);
388 if (opts
.find("service") == opts
.end())
389 return "-specify service";
390 if ((opts
.find("text") == opts
.end()) && (opts
.find("begin") == opts
.end()) && (opts
.find("event_id") == opts
.end()))
391 return "-specify text and/or begin or event_id";
392 eString text
= opts
["text"];
393 if (opts
.find("begin") != opts
.end())
394 begin
= atoi(opts
["begin"].c_str());
395 if (opts
.find("duration") != opts
.end())
396 duration
= atoi(opts
["duration"].c_str());
397 search
= opts
["text"];
399 if (opts
.find("extended") != opts
.end())
404 if (opts
.find("event_id") != opts
.end())
405 sscanf(opts
["event_id"].c_str(), "%x", &event_id
);
407 eEPGCache
*epgcache
=eEPGCache::getInstance();
408 eServiceReference
ref(opts
["service"]);
413 const timeMap
*evmap
= epgcache
->getTimeMap((eServiceReferenceDVB
&)ref
);
417 return "-no events for this service";
419 eServiceReferenceDVB
&rref
=(eServiceReferenceDVB
&)ref
;
420 timeMap::const_iterator ibegin
= evmap
->begin(), iend
= evmap
->end();
423 ibegin
= evmap
->lower_bound(begin
);
424 if ((ibegin
!= evmap
->end()) && (ibegin
!= evmap
->begin()))
427 ibegin
=evmap
->begin();
429 timeMap::const_iterator iend
= evmap
->upper_bound(begin
+ duration
);
430 if (iend
!= evmap
->end())
434 (rref
.getTransportStreamID().get()<<16)|rref
.getOriginalNetworkID().get();
435 for (timeMap::const_iterator
event(ibegin
); event
!= iend
; ++event
)
437 EITEvent
*ev
= new EITEvent(*event
->second
, tsidonid
);
438 processEvent(res
, ev
, search
, wantext
);
445 EITEvent
*ev
= epgcache
->lookupEvent((eServiceReferenceDVB
&)ref
, event_id
);
447 return "-service or event_id invalid";
450 processEvent(res
, ev
, search
, wantext
);
458 void ezapInitializeWeb(eHTTPDynPathResolver
*dyn_resolver
)
460 dyn_resolver
->addDyn("GET", "/dyn2/", web_root
);
461 dyn_resolver
->addDyn("GET", "/dyn2/services", xml_services
);
463 dyn_resolver
->addDyn("GET", "/erc/services", erc_services
);
464 dyn_resolver
->addDyn("GET", "/erc/epg", erc_epg
);