diff options
author | Frank Schmirler <vdr@schmirler.de> | 2013-02-02 23:28:55 +0100 |
---|---|---|
committer | Frank Schmirler <vdr@schmirler.de> | 2013-02-02 23:28:55 +0100 |
commit | 9bbb74b7fd15cecd3256ce9035b3c2505baded5c (patch) | |
tree | 1a88edf2220e5a82c36945fa3dbf262ec7a50c94 /server | |
parent | 176df8341ddb62049d34a3bb601b0c4e0c1dbeaa (diff) | |
download | vdr-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.c | 34 | ||||
-rw-r--r-- | server/menuHTTP.c | 70 | ||||
-rw-r--r-- | server/menuHTTP.h | 20 |
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()) |