Skip to content

Commit b0111bb

Browse files
committed
added xml/json/html-output for searchtimers (epgsearch)
1 parent 15dfc3c commit b0111bb

18 files changed

+430
-93
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
5656

5757
### The object files (add further files here):
5858

59-
OBJS = $(PLUGIN).o serverthread.o tools.o info.o channels.o events.o recordings.o remote.o timers.o statusmonitor.o osd.o jsonparser.o epgsearch.o
59+
OBJS = $(PLUGIN).o serverthread.o tools.o info.o channels.o events.o recordings.o remote.o timers.o statusmonitor.o osd.o jsonparser.o epgsearch.o searchtimers.o
6060

6161
### The main target:
6262

channels.cpp

+15-15
Original file line numberDiff line numberDiff line change
@@ -255,25 +255,25 @@ void XmlChannelList::addChannel(cChannel* channel, std::string group, bool image
255255
std::string suffix = (std::string) ".ts";
256256

257257
s->write(" <channel>\n");
258-
s->write((const char*)cString::sprintf(" <param name=\"name\">%s</param>\n", StringExtension::encodeToXml(channel->Name()).c_str()));
259-
s->write((const char*)cString::sprintf(" <param name=\"number\">%i</param>\n", channel->Number()));
260-
s->write((const char*)cString::sprintf(" <param name=\"channel_id\">%s</param>\n", StringExtension::encodeToXml( (std::string)channel->GetChannelID().ToString()).c_str()));
261-
s->write((const char*)cString::sprintf(" <param name=\"image\">%s</param>\n", (image ? "true" : "false")));
262-
s->write((const char*)cString::sprintf(" <param name=\"group\">%s</param>\n", StringExtension::encodeToXml( group ).c_str()));
263-
s->write((const char*)cString::sprintf(" <param name=\"transponder\">%i</param>\n", channel->Transponder()));
264-
s->write((const char*)cString::sprintf(" <param name=\"stream\">%s</param>\n", StringExtension::encodeToXml( ((std::string)channel->GetChannelID().ToString() + (std::string)suffix).c_str()).c_str()));
265-
s->write((const char*)cString::sprintf(" <param name=\"is_atsc\">%s</param>\n", channel->IsAtsc() ? "true" : "false"));
266-
s->write((const char*)cString::sprintf(" <param name=\"is_cable\">%s</param>\n", channel->IsCable() ? "true" : "false"));
267-
s->write((const char*)cString::sprintf(" <param name=\"is_sat\">%s</param>\n", channel->IsSat() ? "true" : "false"));
268-
s->write((const char*)cString::sprintf(" <param name=\"is_terr\">%s</param>\n", channel->IsTerr() ? "true" : "false"));
258+
s->write(cString::sprintf(" <param name=\"name\">%s</param>\n", StringExtension::encodeToXml(channel->Name()).c_str()));
259+
s->write(cString::sprintf(" <param name=\"number\">%i</param>\n", channel->Number()));
260+
s->write(cString::sprintf(" <param name=\"channel_id\">%s</param>\n", StringExtension::encodeToXml( (std::string)channel->GetChannelID().ToString()).c_str()));
261+
s->write(cString::sprintf(" <param name=\"image\">%s</param>\n", (image ? "true" : "false")));
262+
s->write(cString::sprintf(" <param name=\"group\">%s</param>\n", StringExtension::encodeToXml( group ).c_str()));
263+
s->write(cString::sprintf(" <param name=\"transponder\">%i</param>\n", channel->Transponder()));
264+
s->write(cString::sprintf(" <param name=\"stream\">%s</param>\n", StringExtension::encodeToXml( ((std::string)channel->GetChannelID().ToString() + (std::string)suffix).c_str()).c_str()));
265+
s->write(cString::sprintf(" <param name=\"is_atsc\">%s</param>\n", channel->IsAtsc() ? "true" : "false"));
266+
s->write(cString::sprintf(" <param name=\"is_cable\">%s</param>\n", channel->IsCable() ? "true" : "false"));
267+
s->write(cString::sprintf(" <param name=\"is_sat\">%s</param>\n", channel->IsSat() ? "true" : "false"));
268+
s->write(cString::sprintf(" <param name=\"is_terr\">%s</param>\n", channel->IsTerr() ? "true" : "false"));
269269
bool is_radio = VdrExtension::IsRadio(channel);
270-
s->write((const char*)cString::sprintf(" <param name=\"is_radio\">%s</param>\n", is_radio ? "true" : "false"));
270+
s->write(cString::sprintf(" <param name=\"is_radio\">%s</param>\n", is_radio ? "true" : "false"));
271271
s->write(" </channel>\n");
272272
}
273273

274274
void XmlChannelList::finish()
275275
{
276-
s->write((const char*)cString::sprintf(" <count>%i</count><total>%i</total>", Count(), total));
276+
s->write(cString::sprintf(" <count>%i</count><total>%i</total>", Count(), total));
277277
s->write("</channels>");
278278
}
279279

@@ -332,11 +332,11 @@ void XmlChannelGroupList::init()
332332
void XmlChannelGroupList::addGroup(std::string group)
333333
{
334334
if ( filtered() ) return;
335-
s->write((const char*)cString::sprintf(" <group>%s</group>\n", group.c_str()));
335+
s->write(cString::sprintf(" <group>%s</group>\n", group.c_str()));
336336
}
337337

338338
void XmlChannelGroupList::finish()
339339
{
340-
s->write((const char*)cString::sprintf(" <count>%i</count><total>%i</total>", Count(), total));
340+
s->write(cString::sprintf(" <count>%i</count><total>%i</total>", Count(), total));
341341
s->write("</groups>");
342342
}

epgsearch.cpp

+118-14
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,125 @@
1-
#include <vector>
2-
#include <algorithm>
3-
#include <vdr/channels.h>
4-
#include <vdr/plugin.h>
5-
#include <iomanip>
6-
#include "epgsearch/services.h"
71
#include "epgsearch.h"
8-
#include "tools.h"
9-
#include <ostream>
10-
#include <sstream>
11-
#include <istream>
12-
#include <set>
13-
#include <stdexcept>
2+
3+
4+
void operator<<= (cxxtools::SerializationInfo& si, SerSearchTimerContainer s)
5+
{
6+
si.addMember("id") <<= s.timer->Id();
7+
si.addMember("search") <<= StringExtension::UTF8Decode(s.timer->Search());
8+
si.addMember("mode") <<= s.timer->SearchMode();
9+
si.addMember("tolerance") <<= s.timer->Tolerance();
10+
si.addMember("match_case") <<= s.timer->MatchCase();
11+
si.addMember("use_time") <<= s.timer->UseTime();
12+
si.addMember("use_title") <<= s.timer->UseTitle();
13+
si.addMember("use_subtitle") <<= s.timer->UseSubtitle();
14+
si.addMember("use_description") <<= s.timer->UseDescription();
15+
si.addMember("start_time") <<= s.timer->StartTime();
16+
si.addMember("stop_time") <<= s.timer->StopTime();
17+
si.addMember("use_channel") <<= s.timer->UseChannel();
18+
si.addMember("channel_min") <<= (const char*)s.timer->ChannelMin().ToString();
19+
si.addMember("channel_max") <<= (const char*)s.timer->ChannelMax().ToString();
20+
si.addMember("channels") <<= s.timer->ChannelText();
21+
si.addMember("use_as_searchtimer") <<= s.timer->UseAsSearchTimer();
22+
si.addMember("use_duration") <<= s.timer->UseDuration();
23+
si.addMember("duration_min") <<= s.timer->MinDuration();
24+
si.addMember("duration_max") <<= s.timer->MaxDuration();
25+
si.addMember("use_dayofweek") <<= s.timer->UseDayOfWeek();
26+
si.addMember("dayofweek") <<= s.timer->DayOfWeek();
27+
si.addMember("use_in_favorites") <<= s.timer->UseInFavorites();
28+
si.addMember("search_timer_action") <<= s.timer->SearchTimerAction();
29+
si.addMember("use_series_recording") <<= s.timer->UseSeriesRecording();
30+
si.addMember("directory") <<= s.timer->Directory();
31+
si.addMember("del_recs_after_days") <<= s.timer->DelRecsAfterDays();
32+
si.addMember("keep_recs") <<= s.timer->KeepRecs();
33+
si.addMember("pause_on_recs") <<= s.timer->PauseOnRecs();
34+
si.addMember("blacklist_mode") <<= s.timer->BlacklistMode();
35+
si.addMember("switch_min_before") <<= s.timer->SwitchMinBefore();
36+
si.addMember("use_ext_epg_info") <<= s.timer->UseExtEPGInfo();
37+
si.addMember("ext_epg_info") <<= s.timer->ExtEPGInfo();
38+
si.addMember("avoid_repeats") <<= s.timer->AvoidRepeats();
39+
si.addMember("allowed_repeats") <<= s.timer->AllowedRepeats();
40+
si.addMember("repeats_within_days") <<= s.timer->RepeatsWithinDays();
41+
si.addMember("compare_title") <<= s.timer->CompareTitle();
42+
si.addMember("compare_subtitle") <<= s.timer->CompareSubtitle();
43+
si.addMember("compare_summary") <<= s.timer->CompareSummary();
44+
si.addMember("compare_categories") <<= s.timer->CompareCategories();
45+
si.addMember("priority") <<= s.timer->Priority();
46+
si.addMember("lifetime") <<= s.timer->Lifetime();
47+
si.addMember("margin_start") <<= s.timer->MarginStart();
48+
si.addMember("margin_stop") <<= s.timer->MarginStop();
49+
si.addMember("use_vps") <<= s.timer->UseVPS();
50+
si.addMember("del_mode") <<= s.timer->DelMode();
51+
si.addMember("del_after_count_recs") <<= s.timer->DelAfterCountRecs();
52+
si.addMember("del_after_days_of_first_rec") <<= s.timer->DelAfterDaysOfFirstRec();
53+
}
1454

1555
namespace vdrlive {
1656

1757
using namespace std;
1858

59+
std::string SearchTimer::ToXml()
60+
{
61+
std::ostringstream s;
62+
s << "<searchtimer>\n"
63+
<< "<id>" << Id() << "</id>\n"
64+
<< "<search>" << StringExtension::encodeToXml(Search()) << "</search>\n"
65+
<< "<mode>" << SearchMode() << "</mode>\n"
66+
<< "<tolerance>" << Tolerance() << "</tolerance>\n"
67+
<< "<match_case>" << MatchCase() << "</match_case>\n"
68+
<< "<use_time>" << UseTime() << "</use_time>\n"
69+
<< "<use_title>" << UseTitle() << "</use_title>\n"
70+
<< "<use_subtitle>" << UseSubtitle() << "</use_subtitle>\n"
71+
<< "<start_time>" << StartTime() << "</start_time>\n"
72+
<< "<stop_time>" << StopTime() << "</stop_time>\n"
73+
<< "<use_channel>" << UseChannel() << "</use_channel>\n"
74+
<< "<channel_min>" << ChannelMin() << "</channel_min>\n"
75+
<< "<channel_max>" << ChannelMax() << "</channel_max>\n"
76+
<< "<channels>" << ChannelText() << "</channels>\n"
77+
<< "<use_as_searchtimer>" << UseAsSearchTimer() << "</use_as_searchtimer>\n"
78+
<< "<use_duration>" << UseDuration() << "</use_duration>\n"
79+
<< "<duration_min>" << MinDuration() << "</duration_min>\n"
80+
<< "<duration_max>" << MaxDuration() << "</duration_max>\n"
81+
<< "<use_dayofweek>" << UseDayOfWeek() << "</use_dayofweek>\n"
82+
<< "<dayofweek>" << DayOfWeek() << "</dayofweek>\n"
83+
<< "<use_in_favorites>" << UseInFavorites() << "</use_in_favorites>\n"
84+
<< "<directory>" << Directory() << "</directory>\n"
85+
<< "<del_recs_after_days>" << DelRecsAfterDays() << "</del_recs_after_days>\n"
86+
<< "<keep_recs>" << KeepRecs() << "</keep_recs>\n"
87+
<< "<pause_on_recs>" << PauseOnRecs() << "</pause_on_recs>\n"
88+
<< "<blacklist_mode>" << BlacklistMode() << "</blacklist_mode>\n"
89+
<< "<switch_min_before>" << SwitchMinBefore() << "</switch_min_before>\n"
90+
<< "<use_ext_epg_info>" << UseExtEPGInfo() << "</use_ext_epg_info>\n"
91+
<< "<ext_epg_info>\n";
92+
std::vector< std::string > epg_infos = ExtEPGInfo();
93+
for (int i=0;i<(int)epg_infos.size();i++)
94+
{
95+
s << " <info>" << epg_infos[i] << "</info>\n";
96+
}
97+
s << "</ext_epg_info>\n"
98+
<< "<avoid_repeats>" << AvoidRepeats() << "</avoid_repeats>\n"
99+
<< "<allowed_repeats>" << AllowedRepeats() << "</allowed_repeats>\n"
100+
<< "<repeats_within_days>" << RepeatsWithinDays() << "</repeats_within_days>\n"
101+
<< "<compare_title>" << CompareTitle() << "</compare_title>\n"
102+
<< "<compare_subtitle>" << CompareSubtitle() << "</compare_subtitle>\n"
103+
<< "<compare_summary>" << CompareSummary() << "</compare_summary>\n"
104+
<< "<compare_categories>" << CompareCategories() << "</compare_categories>\n"
105+
<< "<priority>" << Priority() << "</priority>\n"
106+
<< "<lifetime>" << Lifetime() << "</lifetime>\n"
107+
<< "<margin_start>" << MarginStart() << "</margin_start>\n"
108+
<< "<margin_stop>" << MarginStop() << "</margin_stop>\n"
109+
<< "<use_vps>" << UseVPS() << "</use_vps>\n"
110+
<< "<del_mode>" << DelMode() << "</del_mode>\n"
111+
<< "<del_after_count_recs>" << DelAfterCountRecs() << "</del_after_count_recs>\n"
112+
<< "<del_after_days_of_first_rec>" << DelAfterDaysOfFirstRec() << "</del_after_days_of_first_rec>\n"
113+
<< "</searchtimer>\n";
114+
115+
return s.str();
116+
}
117+
118+
std::string SearchTimer::ToHtml()
119+
{
120+
return Search();
121+
}
122+
19123
istream& operator>>( istream& is, tChannelID& ret )
20124
{
21125
string line;
@@ -338,7 +442,7 @@ SearchTimers::SearchTimers()
338442
bool SearchTimers::Reload()
339443
{
340444
Epgsearch_services_v1_0 service;
341-
445+
cPluginManager::CallFirstService(ServiceInterface, &service);
342446
ReadLock channelsLock( Channels, 0 );
343447
list< string > timers = service.handler->SearchTimerList();
344448
m_timers.assign( timers.begin(), timers.end() );
@@ -608,5 +712,5 @@ std::string EPGSearchExpr::EvaluateExpr(const std::string& expr, const cEvent* e
608712
}
609713

610714

611-
} // namespace vdrlivea
715+
} // namespace vdrlive
612716

epgsearch.h

+36-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,32 @@
1-
#ifndef VDR_LIVE_EPGSEARCH_H
2-
#define VDR_LIVE_EPGSEARCH_H
3-
41
#include <vector>
52
#include <list>
63
#include <set>
74
#include <string>
5+
#include <vector>
6+
#include <algorithm>
7+
#include <iomanip>
8+
#include <ostream>
9+
#include <sstream>
10+
#include <istream>
11+
#include <stdexcept>
12+
13+
#include <cxxtools/serializationinfo.h>
814
#include <vdr/channels.h>
915
#include <vdr/epg.h>
16+
#include <vdr/plugin.h>
17+
18+
#include "epgsearch/services.h"
1019
#include "tools.h"
1120

21+
#ifndef VDR_LIVE_EPGSEARCH_H
22+
#define VDR_LIVE_EPGSEARCH_H
23+
24+
25+
26+
1227
namespace vdrlive {
1328

29+
1430
// --- VDR-PLUGIN-LIVE-TOOLS ----------------------------
1531

1632
std::istream& operator>>( std::istream& is, tChannelID& ret );
@@ -67,6 +83,8 @@ class SearchTimer
6783
SearchTimer( std::string const& data );
6884
void Init();
6985
std::string ToText();
86+
std::string ToXml();
87+
std::string ToHtml();
7088
friend bool operator<( SearchTimer const& left, SearchTimer const& right );
7189

7290
int Id() const { return m_id; }
@@ -167,7 +185,7 @@ class SearchTimer
167185
void SetDelAfterCountRecs(int delAfterCountRecs) { m_delAfterCountRecs = delAfterCountRecs; }
168186
int DelAfterDaysOfFirstRec() const { return m_delAfterDaysOfFirstRec; }
169187
void SetDelAfterDaysOfFirstRec(int delAfterDaysOfFirstRec) { m_delAfterDaysOfFirstRec = delAfterDaysOfFirstRec; }
170-
188+
171189
private:
172190
int m_id;
173191
std::string m_search;
@@ -446,8 +464,22 @@ class EPGSearchExpr
446464
static std::string EvaluateExpr(const std::string& expr, const cEvent* event);
447465
};
448466

467+
468+
469+
449470
}
450471

451472
// namespace vdrlive
452473

474+
475+
// --- JSON RELATED -------------------------------------
476+
struct SerSearchTimerContainer
477+
{
478+
vdrlive::SearchTimer* timer;
479+
};
480+
481+
482+
void operator<<= (cxxtools::SerializationInfo& si, SerSearchTimerContainer s);
483+
484+
453485
#endif // VDR_LIVE_EPGSEARCH_H

events.cpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -311,22 +311,22 @@ void XmlEventList::addEvent(cEvent* event)
311311
if ( event->Description() == NULL ) { eventDescription = ""; } else { eventDescription = event->Description(); }
312312

313313
s->write(" <event>\n");
314-
s->write((const char*)cString::sprintf(" <param name=\"id\">%i</param>\n", event->EventID()));
315-
s->write((const char*)cString::sprintf(" <param name=\"title\">%s</param>\n", StringExtension::encodeToXml(eventTitle).c_str()));
316-
s->write((const char*)cString::sprintf(" <param name=\"short_text\">%s</param>\n", StringExtension::encodeToXml(eventShortText).c_str()));
317-
s->write((const char*)cString::sprintf(" <param name=\"description\">%s</param>\n", StringExtension::encodeToXml(eventDescription).c_str()));
318-
s->write((const char*)cString::sprintf(" <param name=\"start_time\">%i</param>\n", (int)event->StartTime()));
319-
s->write((const char*)cString::sprintf(" <param name=\"duration\">%i</param>\n", event->Duration()));
314+
s->write(cString::sprintf(" <param name=\"id\">%i</param>\n", event->EventID()));
315+
s->write(cString::sprintf(" <param name=\"title\">%s</param>\n", StringExtension::encodeToXml(eventTitle).c_str()));
316+
s->write(cString::sprintf(" <param name=\"short_text\">%s</param>\n", StringExtension::encodeToXml(eventShortText).c_str()));
317+
s->write(cString::sprintf(" <param name=\"description\">%s</param>\n", StringExtension::encodeToXml(eventDescription).c_str()));
318+
s->write(cString::sprintf(" <param name=\"start_time\">%i</param>\n", (int)event->StartTime()));
319+
s->write(cString::sprintf(" <param name=\"duration\">%i</param>\n", event->Duration()));
320320

321321
std::vector< std::string > images;
322322
FileCaches::get()->searchEventImages((int)event->EventID(), images);
323-
s->write((const char*)cString::sprintf(" <param name=\"images\">%i</param>\n", (int)images.size()));
323+
s->write(cString::sprintf(" <param name=\"images\">%i</param>\n", (int)images.size()));
324324

325325
s->write(" </event>\n");
326326
}
327327

328328
void XmlEventList::finish()
329329
{
330-
s->write((const char*)cString::sprintf(" <count>%i</count><total>%i</total>", Count(), total));
330+
s->write(cString::sprintf(" <count>%i</count><total>%i</total>", Count(), total));
331331
s->write("</events>");
332332
}

events.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
#include <cxxtools/jsonserializer.h>
66
#include <cxxtools/serializationinfo.h>
77
#include <cxxtools/utf8codec.h>
8-
#include "tools.h"
9-
#include "epgsearch/services.h"
10-
118
#include <vdr/epg.h>
129
#include <vdr/plugin.h>
1310

11+
#include "tools.h"
12+
#include "epgsearch/services.h"
13+
1414
class EventsResponder : public cxxtools::http::Responder
1515
{
1616
public:

info.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,12 @@ void InfoResponder::replyXml(StreamExtension& se)
8585
se.writeXmlHeader();
8686
se.write("<info xmlns=\"http://www.domain.org/restfulapi/2011/info-xml\">\n");
8787
se.write(" <version>0.0.1</version>\n");
88-
se.write((const char*)cString::sprintf(" <time>%i</time>\n", (int)now));
88+
se.write(cString::sprintf(" <time>%i</time>\n", (int)now));
8989
se.write(" <services>\n");
9090

9191
std::vector< RestfulService* > restful_services = RestfulServices::get()->Services(true, true);
9292
for (size_t i = 0; i < restful_services.size(); i++) {
93-
se.write((const char*)cString::sprintf(" <service path=\"%s\" version=\"%i\" internal=\"%s\" />\n",
93+
se.write(cString::sprintf(" <service path=\"%s\" version=\"%i\" internal=\"%s\" />\n",
9494
restful_services[i]->Path().c_str(),
9595
restful_services[i]->Version(),
9696
restful_services[i]->Internal() ? "true" : "false"));
@@ -99,9 +99,9 @@ void InfoResponder::replyXml(StreamExtension& se)
9999

100100

101101
if ( statm->getRecordingName().length() > 0 || statm->getRecordingFile().length() > 0 ) {
102-
se.write((const char*)cString::sprintf(" <video name=\"%s\">%s</video>\n", StringExtension::encodeToXml(statm->getRecordingName()).c_str(), StringExtension::encodeToXml(statm->getRecordingFile()).c_str()));
102+
se.write(cString::sprintf(" <video name=\"%s\">%s</video>\n", StringExtension::encodeToXml(statm->getRecordingName()).c_str(), StringExtension::encodeToXml(statm->getRecordingFile()).c_str()));
103103
} else {
104-
se.write((const char*)cString::sprintf(" <channel>%i</channel>\n", statm->getChannel()));
104+
se.write(cString::sprintf(" <channel>%i</channel>\n", statm->getChannel()));
105105
}
106106

107107
se.write(" <vdr>\n");
@@ -110,7 +110,7 @@ void InfoResponder::replyXml(StreamExtension& se)
110110
cPlugin* p = NULL;
111111
int counter = 0;
112112
while ( (p = cPluginManager::GetPlugin(counter) ) != NULL ) {
113-
se.write((const char*)cString::sprintf(" <plugin name=\"%s\" version=\"%s\" />\n", p->Name(), p->Version()));
113+
se.write(cString::sprintf(" <plugin name=\"%s\" version=\"%s\" />\n", p->Name(), p->Version()));
114114
counter++;
115115
}
116116

jsonparser.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ JsonObject* JsonParser::ParseJsonObject(const char* data, long size, long* posit
261261
{
262262
SkipEmpty(data, size, position);
263263
if ( data[*position] != '{' ) return NULL;
264-
(*position)++;
264+
(*position)++; //skip '{'
265265
bool finished = false;
266266
std::string error = "";
267267
JsonObject* jsonObject = new JsonObject();
@@ -270,7 +270,7 @@ JsonObject* JsonParser::ParseJsonObject(const char* data, long size, long* posit
270270
SkipEmpty(data, size, position);
271271
if ( data[*position] == '}' || data[*position] == 0 ) {
272272
finished = true;
273-
(*position)++;
273+
(*position)++; // skip '}'
274274
} else {
275275
std::string name = ParseString(data, size, position);
276276
SkipEmpty(data, size, position);

0 commit comments

Comments
 (0)