summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorFrank Schmirler <vdr@schmirler.de>2013-02-02 23:28:55 +0100
committerFrank Schmirler <vdr@schmirler.de>2013-02-02 23:28:55 +0100
commit9bbb74b7fd15cecd3256ce9035b3c2505baded5c (patch)
tree1a88edf2220e5a82c36945fa3dbf262ec7a50c94 /server
parent176df8341ddb62049d34a3bb601b0c4e0c1dbeaa (diff)
downloadvdr-plugin-streamdev-9bbb74b7fd15cecd3256ce9035b3c2505baded5c.tar.gz
vdr-plugin-streamdev-9bbb74b7fd15cecd3256ce9035b3c2505baded5c.tar.bz2
Added RSS format for HTTP menus
Diffstat (limited to 'server')
-rw-r--r--server/connectionHTTP.c34
-rw-r--r--server/menuHTTP.c70
-rw-r--r--server/menuHTTP.h20
3 files changed, 108 insertions, 16 deletions
diff --git a/server/connectionHTTP.c b/server/connectionHTTP.c
index 48febe7..940517b 100644
--- a/server/connectionHTTP.c
+++ b/server/connectionHTTP.c
@@ -417,23 +417,35 @@ cChannelList* cConnectionHTTP::ChannelListFromString(const std::string& Path, co
}
if (iterator) {
+ // assemble base url: http://host/path/
+ std::string base;
+ const static std::string HOST("HTTP_HOST");
+ tStrStrMap::const_iterator it = Headers().find(HOST);
+ if (it != Headers().end())
+ base = "http://" + it->second + "/";
+ else
+ base = (std::string) "http://" + LocalIp() + ":" +
+ (const char*) itoa(StreamdevServerSetup.HTTPServerPort) + "/";
+ base += Path;
+
if (Filebase.empty() || Fileext.compare(".htm") == 0 || Fileext.compare(".html") == 0) {
std::string self = Filebase + Fileext;
+ std::string rss = Filebase + ".rss";
tStrStrMap::const_iterator it = Headers().find("QUERY_STRING");
- if (it != Headers().end() && !it->second.empty())
+ if (it != Headers().end() && !it->second.empty()) {
self += '?' + it->second;
- return new cHtmlChannelList(iterator, m_StreamType, self.c_str(), groupTarget.c_str());
+ rss += '?' + it->second;
+ }
+ return new cHtmlChannelList(iterator, m_StreamType, self.c_str(), rss.c_str(), groupTarget.c_str());
} else if (Fileext.compare(".m3u") == 0) {
- std::string base;
- const static std::string HOST("HTTP_HOST");
- tStrStrMap::const_iterator it = Headers().find(HOST);
- if (it != Headers().end())
- base = "http://" + it->second + "/";
- else
- base = (std::string) "http://" + LocalIp() + ":" +
- (const char*) itoa(StreamdevServerSetup.HTTPServerPort) + "/";
- base += Path;
return new cM3uChannelList(iterator, base.c_str());
+ } else if (Fileext.compare(".rss") == 0) {
+ std::string html = Filebase + ".html";
+ tStrStrMap::const_iterator it = Headers().find("QUERY_STRING");
+ if (it != Headers().end() && !it->second.empty()) {
+ html += '?' + it->second;
+ }
+ return new cRssChannelList(iterator, base.c_str(), html.c_str());
} else {
delete iterator;
}
diff --git a/server/menuHTTP.c b/server/menuHTTP.c
index d7fb817..7839527 100644
--- a/server/menuHTTP.c
+++ b/server/menuHTTP.c
@@ -119,8 +119,8 @@ const cChannel* cChannelList::GetGroup(int Index)
const char* cHtmlChannelList::menu =
"[<a href=\"/\">Home</a> (<a href=\"all.html\" tvid=\"RED\">no script</a>)] "
"[<a href=\"tree.html\" tvid=\"GREEN\">Tree View</a>] "
- "[<a href=\"groups.html\" tvid=\"YELLOW\">Groups</a> (<a href=\"groups.m3u\">Playlist</a>)] "
- "[<a href=\"channels.html\" tvid=\"BLUE\">Channels</a> (<a href=\"channels.m3u\">Playlist</a>)] ";
+ "[<a href=\"groups.html\" tvid=\"YELLOW\">Groups</a> (<a href=\"groups.m3u\">Playlist</a> | <a href=\"groups.rss\">RSS</a>)] "
+ "[<a href=\"channels.html\" tvid=\"BLUE\">Channels</a> (<a href=\"channels.m3u\">Playlist</a> | <a href=\"channels.rss\">RSS</a>)] ";
const char* cHtmlChannelList::css =
"<style type=\"text/css\">\n"
@@ -215,10 +215,11 @@ std::string cHtmlChannelList::StreamTypeMenu()
return typeMenu;
}
-cHtmlChannelList::cHtmlChannelList(cChannelIterator *Iterator, eStreamType StreamType, const char *Self, const char *GroupTarget): cChannelList(Iterator)
+cHtmlChannelList::cHtmlChannelList(cChannelIterator *Iterator, eStreamType StreamType, const char *Self, const char *Rss, const char *GroupTarget): cChannelList(Iterator)
{
streamType = StreamType;
self = strdup(Self);
+ rss = strdup(Rss);
groupTarget = (GroupTarget && *GroupTarget) ? strdup(GroupTarget) : NULL;
htmlState = hsRoot;
current = NULL;
@@ -227,6 +228,7 @@ cHtmlChannelList::cHtmlChannelList(cChannelIterator *Iterator, eStreamType Strea
cHtmlChannelList::~cHtmlChannelList()
{
free((void *) self);
+ free((void *) rss);
free((void *) groupTarget);
}
@@ -311,7 +313,7 @@ std::string cHtmlChannelList::Next()
std::string cHtmlChannelList::HtmlHead()
{
- return (std::string) "";
+ return (std::string) "<link rel=\"alternate\" type=\"application/rss+xml\" title=\"RSS\" href=\"" + rss + "\"/>";
}
std::string cHtmlChannelList::PageTop()
@@ -432,3 +434,63 @@ std::string cM3uChannelList::Next()
}
}
+// ******************** cRssChannelList ******************
+cRssChannelList::cRssChannelList(cChannelIterator *Iterator, const char *Base, const char *Html)
+: cChannelList(Iterator),
+ m_IConv(cCharSetConv::SystemCharacterTable(), "UTF-8")
+{
+ base = strdup(Base);
+ html = strdup(Html);
+ rssState = msFirst;
+}
+
+cRssChannelList::~cRssChannelList()
+{
+ free(base);
+ free(html);
+}
+
+bool cRssChannelList::HasNext()
+{
+ return rssState != msLast;
+}
+
+std::string cRssChannelList::Next()
+{
+ std::string type_ext;
+
+ if (rssState == msFirst)
+ {
+ rssState = msContinue;
+ return (std::string) "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<rss version=\"2.0\">\n\t<channel>\n"
+ "\t\t<title>VDR</title>\n"
+ "\t\t<link>" + base + html + "</link>\n"
+ "\t\t<description>VDR channel list</description>\n"
+ ;
+ }
+
+ const cChannel *channel = NextChannel();
+ if (!channel)
+ {
+ rssState = msLast;
+ return "\t</channel>\n</rss>\n";
+ }
+
+ std::string name = (std::string) m_IConv.Convert(channel->Name());
+
+ if (channel->GroupSep())
+ {
+ return (std::string) "\t\t<item>\n\t\t\t<title>" +
+ name + "</title>\n\t\t\t<link>" +
+ base + "group.rss?group=" + (const char*) itoa(cChannelList::GetGroupIndex(channel)) + "</link>\n\t\t</item>\n";
+ }
+ else
+ {
+ return (std::string) "\t\t<item>\n\t\t\t<title>" +
+ (const char*) itoa(channel->Number()) + " " + name + "</title>\n\t\t\t<link>" +
+ base + (std::string) channel->GetChannelID().ToString() + "</link>\n\t\t\t<enclosure url=\"" +
+ base + (std::string) channel->GetChannelID().ToString() + "\" type=\"video/mpeg\" />\n\t\t</item>\n";
+ }
+}
+
+
diff --git a/server/menuHTTP.h b/server/menuHTTP.h
index 4ef6363..b025598 100644
--- a/server/menuHTTP.h
+++ b/server/menuHTTP.h
@@ -107,6 +107,7 @@ class cHtmlChannelList: public cChannelList
const cChannel *current;
eStreamType streamType;
const char* self;
+ const char* rss;
const char* groupTarget;
std::string StreamTypeMenu();
@@ -124,7 +125,7 @@ class cHtmlChannelList: public cChannelList
}
virtual bool HasNext();
virtual std::string Next();
- cHtmlChannelList(cChannelIterator *Iterator, eStreamType StreamType, const char *Self, const char *GroupTarget);
+ cHtmlChannelList(cChannelIterator *Iterator, eStreamType StreamType, const char *Self, const char *Rss, const char *GroupTarget);
virtual ~cHtmlChannelList();
};
@@ -143,6 +144,23 @@ class cM3uChannelList: public cChannelList
virtual ~cM3uChannelList();
};
+class cRssChannelList: public cChannelList
+{
+ private:
+ char *base;
+ char *html;
+ enum eRssState { msFirst, msContinue, msLast };
+ eRssState rssState;
+ cCharSetConv m_IConv;
+ public:
+ virtual std::string HttpHeader() { return cChannelList::HttpHeader() + "Content-type: application/rss+xml\r\n"; };
+ virtual bool HasNext();
+ virtual std::string Next();
+
+ cRssChannelList(cChannelIterator *Iterator, const char *Base, const char *Html);
+ virtual ~cRssChannelList();
+};
+
inline const cChannel* cChannelIterator::SkipFakeGroups(const cChannel* Group)
{
while (Group && Group->GroupSep() && !*Group->Name())