summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorFrank Schmirler <vdr@schmirler.de>2013-02-03 11:02:25 +0100
committerFrank Schmirler <vdr@schmirler.de>2013-02-03 11:02:25 +0100
commitd3dd72072c88c83271aae98f5f1a695f802feefa (patch)
treeb7c0450b4c3b917790e2b542b50ea1f8cec69e4f /server
parent9bbb74b7fd15cecd3256ce9035b3c2505baded5c (diff)
downloadvdr-plugin-streamdev-d3dd72072c88c83271aae98f5f1a695f802feefa.tar.gz
vdr-plugin-streamdev-d3dd72072c88c83271aae98f5f1a695f802feefa.tar.bz2
Restructured menuHTTP classes
Diffstat (limited to 'server')
-rw-r--r--server/connectionHTTP.c40
-rw-r--r--server/connectionHTTP.h6
-rw-r--r--server/menuHTTP.c238
-rw-r--r--server/menuHTTP.h83
4 files changed, 202 insertions, 165 deletions
diff --git a/server/connectionHTTP.c b/server/connectionHTTP.c
index 940517b..a8a8c8f 100644
--- a/server/connectionHTTP.c
+++ b/server/connectionHTTP.c
@@ -25,7 +25,7 @@ cConnectionHTTP::cConnectionHTTP(void):
m_StreamType((eStreamType)StreamdevServerSetup.HTTPStreamType),
m_Channel(NULL),
m_Recording(NULL),
- m_ChannelList(NULL)
+ m_MenuList(NULL)
{
Dprintf("constructor hsRequest\n");
m_Apid[0] = m_Apid[1] = 0;
@@ -169,8 +169,8 @@ bool cConnectionHTTP::ProcessRequest(void)
// should never happen
esyslog("streamdev-server connectionHTTP: Missing method or pathinfo");
} else if (it_method->second.compare("GET") == 0 && ProcessURI(it_pathinfo->second)) {
- if (m_ChannelList)
- return Respond("%s", true, m_ChannelList->HttpHeader().c_str());
+ if (m_MenuList)
+ return Respond("%s", true, m_MenuList->HttpHeader().c_str());
else if (m_Channel != NULL) {
cDevice *device = NULL;
if (ProvidesChannel(m_Channel, StreamdevServerSetup.HTTPPriority))
@@ -217,9 +217,9 @@ bool cConnectionHTTP::ProcessRequest(void)
return HttpResponse(404, true);
}
} else if (it_method->second.compare("HEAD") == 0 && ProcessURI(it_pathinfo->second)) {
- if (m_ChannelList) {
+ if (m_MenuList) {
DeferClose();
- return Respond("%s", true, m_ChannelList->HttpHeader().c_str());
+ return Respond("%s", true, m_MenuList->HttpHeader().c_str());
}
else if (m_Channel != NULL) {
if (ProvidesChannel(m_Channel, StreamdevServerSetup.HTTPPriority)) {
@@ -363,13 +363,13 @@ void cConnectionHTTP::Flushed(void)
if (m_Status != hsBody)
return;
- if (m_ChannelList) {
- if (m_ChannelList->HasNext()) {
- if (!Respond("%s", true, m_ChannelList->Next().c_str()))
+ if (m_MenuList) {
+ if (m_MenuList->HasNext()) {
+ if (!Respond("%s", true, m_MenuList->Next().c_str()))
DeferClose();
}
else {
- DELETENULL(m_ChannelList);
+ DELETENULL(m_MenuList);
m_Status = hsFinished;
DeferClose();
}
@@ -387,28 +387,22 @@ void cConnectionHTTP::Flushed(void)
}
}
-cChannelList* cConnectionHTTP::ChannelListFromString(const std::string& Path, const std::string& Filebase, const std::string& Fileext) const
+cMenuList* cConnectionHTTP::MenuListFromString(const std::string& Path, const std::string& Filebase, const std::string& Fileext) const
{
std::string groupTarget;
- cChannelIterator *iterator = NULL;
+ cItemIterator *iterator = NULL;
const static std::string GROUP("group");
if (Filebase.compare("tree") == 0) {
- const cChannel* c = NULL;
tStrStrMap::const_iterator it = m_Params.find(GROUP);
- if (it != m_Params.end())
- c = cChannelList::GetGroup(atoi(it->second.c_str()));
- iterator = new cListTree(c);
+ iterator = new cListTree(it == m_Params.end() ? NULL : it->second.c_str());
groupTarget = Filebase + Fileext;
} else if (Filebase.compare("groups") == 0) {
iterator = new cListGroups();
groupTarget = (std::string) "group" + Fileext;
} else if (Filebase.compare("group") == 0) {
- const cChannel* c = NULL;
tStrStrMap::const_iterator it = m_Params.find(GROUP);
- if (it != m_Params.end())
- c = cChannelList::GetGroup(atoi(it->second.c_str()));
- iterator = new cListGroup(c);
+ iterator = new cListGroup(it == m_Params.end() ? NULL : it->second.c_str());
} else if (Filebase.compare("channels") == 0) {
iterator = new cListChannels();
} else if (Filebase.compare("all") == 0 ||
@@ -436,16 +430,16 @@ cChannelList* cConnectionHTTP::ChannelListFromString(const std::string& Path, co
self += '?' + it->second;
rss += '?' + it->second;
}
- return new cHtmlChannelList(iterator, m_StreamType, self.c_str(), rss.c_str(), groupTarget.c_str());
+ return new cHtmlMenuList(iterator, m_StreamType, self.c_str(), rss.c_str(), groupTarget.c_str());
} else if (Fileext.compare(".m3u") == 0) {
- return new cM3uChannelList(iterator, base.c_str());
+ return new cM3uMenuList(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());
+ return new cRssMenuList(iterator, base.c_str(), html.c_str());
} else {
delete iterator;
}
@@ -520,7 +514,7 @@ bool cConnectionHTTP::ProcessURI(const std::string& PathInfo)
Dprintf("before channelfromstring: type(%s) filespec(%s) fileext(%s)\n", type.c_str(), filespec.c_str(), fileext.c_str());
- if ((m_ChannelList = ChannelListFromString(PathInfo.substr(1, file_pos), filespec.c_str(), fileext.c_str())) != NULL) {
+ if ((m_MenuList = MenuListFromString(PathInfo.substr(1, file_pos), filespec.c_str(), fileext.c_str())) != NULL) {
Dprintf("Channel list requested\n");
return true;
} else if ((m_Recording = RecordingFromString(filespec.c_str(), fileext.c_str())) != NULL) {
diff --git a/server/connectionHTTP.h b/server/connectionHTTP.h
index 91f4a0e..e946242 100644
--- a/server/connectionHTTP.h
+++ b/server/connectionHTTP.h
@@ -13,7 +13,7 @@
#include <tools/select.h>
class cChannel;
-class cChannelList;
+class cMenuList;
class cConnectionHTTP: public cServerConnection {
private:
@@ -36,9 +36,9 @@ private:
// job: replay
cRecording *m_Recording;
// job: listing
- cChannelList *m_ChannelList;
+ cMenuList *m_MenuList;
- cChannelList* ChannelListFromString(const std::string &PathInfo, const std::string &Filebase, const std::string &Fileext) const;
+ cMenuList* MenuListFromString(const std::string &PathInfo, const std::string &Filebase, const std::string &Fileext) const;
cRecording* RecordingFromString(const char* FileBase, const char* FileExt) const;
bool ProcessURI(const std::string &PathInfo);
diff --git a/server/menuHTTP.c b/server/menuHTTP.c
index 7839527..ca44579 100644
--- a/server/menuHTTP.c
+++ b/server/menuHTTP.c
@@ -2,16 +2,60 @@
#include "server/menuHTTP.h"
//**************************** cChannelIterator **************
-cChannelIterator::cChannelIterator(const cChannel *First): channel(First)
-{}
+cChannelIterator::cChannelIterator(const cChannel *First)
+{
+ first = First;
+ current = NULL;
+}
-const cChannel* cChannelIterator::Next()
+bool cChannelIterator::Next()
{
- const cChannel *current = channel;
- channel = NextChannel(channel);
+ if (first)
+ {
+ current = first;
+ first = NULL;
+ }
+ else
+ current = NextChannel(current);
return current;
}
+const cString cChannelIterator::ItemId() const
+{
+ if (current)
+ {
+ if (current->GroupSep())
+ {
+ int index = 0;
+ for (int curr = Channels.GetNextGroup(-1); curr >= 0; curr = Channels.GetNextGroup(curr))
+ {
+ if (Channels.Get(curr) == current)
+ return itoa(index);
+ index++;
+ }
+ }
+ else
+ {
+ return itoa(current->Number());
+ }
+ }
+ return cString("-1");
+}
+
+const cChannel* cChannelIterator::GetGroup(const char* GroupId)
+{
+ int group = -1;
+ if (GroupId)
+ {
+ int Index = atoi(GroupId);
+ group = Channels.GetNextGroup(-1);
+ while (Index-- && group >= 0)
+ group = Channels.GetNextGroup(group);
+ }
+ return group >= 0 ? Channels.Get(group) : NULL;
+}
+
+
//**************************** cListAll **************
cListAll::cListAll(): cChannelIterator(Channels.First())
{}
@@ -46,7 +90,7 @@ const cChannel* cListGroups::NextChannel(const cChannel *Channel)
}
//
// ********************* cListGroup ****************
-cListGroup::cListGroup(const cChannel *Group): cChannelIterator(GetNextChannelInGroup(Group))
+cListGroup::cListGroup(const char *GroupId): cChannelIterator(GetNextChannelInGroup(GetGroup(GroupId)))
{}
const cChannel* cListGroup::GetNextChannelInGroup(const cChannel *Channel)
@@ -62,9 +106,9 @@ const cChannel* cListGroup::NextChannel(const cChannel *Channel)
}
//
// ********************* cListTree ****************
-cListTree::cListTree(const cChannel *SelectedGroup): cChannelIterator(Channels.Get(Channels.GetNextGroup(-1)))
+cListTree::cListTree(const char *SelectedGroupId): cChannelIterator(Channels.Get(Channels.GetNextGroup(-1)))
{
- selectedGroup = SelectedGroup;
+ selectedGroup = GetGroup(SelectedGroupId);
currentGroup = Channels.Get(Channels.GetNextGroup(-1));
}
@@ -86,43 +130,23 @@ const cChannel* cListTree::NextChannel(const cChannel *Channel)
return Channel;
}
-// ******************** cChannelList ******************
-cChannelList::cChannelList(cChannelIterator *Iterator) : iterator(Iterator)
+// ******************** cMenuList ******************
+cMenuList::cMenuList(cItemIterator *Iterator) : iterator(Iterator)
{}
-cChannelList::~cChannelList()
+cMenuList::~cMenuList()
{
delete iterator;
}
-int cChannelList::GetGroupIndex(const cChannel *Group)
-{
- int index = 0;
- for (int curr = Channels.GetNextGroup(-1); curr >= 0; curr = Channels.GetNextGroup(curr))
- {
- if (Channels.Get(curr) == Group)
- return index;
- index++;
- }
- return -1;
-}
-
-const cChannel* cChannelList::GetGroup(int Index)
-{
- int group = Channels.GetNextGroup(-1);
- while (Index-- && group >= 0)
- group = Channels.GetNextGroup(group);
- return group >= 0 ? Channels.Get(group) : NULL;
-}
-
-// ******************** cHtmlChannelList ******************
-const char* cHtmlChannelList::menu =
+// ******************** cHtmlMenuList ******************
+const char* cHtmlMenuList::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=\"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 =
+const char* cHtmlMenuList::css =
"<style type=\"text/css\">\n"
"<!--\n"
"a:link, a:visited, a:hover, a:active, a:focus { color:#333399; }\n"
@@ -138,7 +162,7 @@ const char* cHtmlChannelList::css =
"-->\n"
"</style>";
-const char* cHtmlChannelList::js =
+const char* cHtmlMenuList::js =
"<script language=\"JavaScript\">\n"
"<!--\n"
@@ -199,7 +223,7 @@ const char* cHtmlChannelList::js =
"</script>";
-std::string cHtmlChannelList::StreamTypeMenu()
+std::string cHtmlMenuList::StreamTypeMenu()
{
std::string typeMenu;
typeMenu += (streamType == stTS ? (std::string) "[TS] " :
@@ -215,29 +239,29 @@ std::string cHtmlChannelList::StreamTypeMenu()
return typeMenu;
}
-cHtmlChannelList::cHtmlChannelList(cChannelIterator *Iterator, eStreamType StreamType, const char *Self, const char *Rss, const char *GroupTarget): cChannelList(Iterator)
+cHtmlMenuList::cHtmlMenuList(cItemIterator *Iterator, eStreamType StreamType, const char *Self, const char *Rss, const char *GroupTarget): cMenuList(Iterator)
{
streamType = StreamType;
self = strdup(Self);
rss = strdup(Rss);
groupTarget = (GroupTarget && *GroupTarget) ? strdup(GroupTarget) : NULL;
htmlState = hsRoot;
- current = NULL;
+ onItem = true;
}
-cHtmlChannelList::~cHtmlChannelList()
+cHtmlMenuList::~cHtmlMenuList()
{
free((void *) self);
free((void *) rss);
free((void *) groupTarget);
}
-bool cHtmlChannelList::HasNext()
+bool cHtmlMenuList::HasNext()
{
return htmlState != hsPageBottom;
}
-std::string cHtmlChannelList::Next()
+std::string cHtmlMenuList::Next()
{
switch (htmlState)
{
@@ -254,39 +278,39 @@ std::string cHtmlChannelList::Next()
htmlState = hsPageTop;
break;
case hsPageTop:
- current = NextChannel();
- htmlState = current ? (current->GroupSep() ? hsGroupTop : hsPlainTop) : hsPageBottom;
+ onItem = NextItem();
+ htmlState = onItem ? (IsGroup() ? hsGroupTop : hsPlainTop) : hsPageBottom;
break;
case hsPlainTop:
htmlState = hsPlainItem;
break;
case hsPlainItem:
- current = NextChannel();
- htmlState = current && !current->GroupSep() ? hsPlainItem : hsPlainBottom;
+ onItem = NextItem();
+ htmlState = onItem && !IsGroup() ? hsPlainItem : hsPlainBottom;
break;
case hsPlainBottom:
- htmlState = current ? hsGroupTop : hsPageBottom;
+ htmlState = onItem ? hsGroupTop : hsPageBottom;
break;
case hsGroupTop:
- current = NextChannel();
- htmlState = current && !current->GroupSep() ? hsItemsTop : hsGroupBottom;
+ onItem = NextItem();
+ htmlState = onItem && !IsGroup() ? hsItemsTop : hsGroupBottom;
break;
case hsItemsTop:
htmlState = hsItem;
break;
case hsItem:
- current = NextChannel();
- htmlState = current && !current->GroupSep() ? hsItem : hsItemsBottom;
+ onItem = NextItem();
+ htmlState = onItem && !IsGroup() ? hsItem : hsItemsBottom;
break;
case hsItemsBottom:
htmlState = hsGroupBottom;
break;
case hsGroupBottom:
- htmlState = current ? hsGroupTop : hsPageBottom;
+ htmlState = onItem ? hsGroupTop : hsPageBottom;
break;
case hsPageBottom:
default:
- esyslog("streamdev-server cHtmlChannelList: invalid call to Next()");
+ esyslog("streamdev-server cHtmlMenuList: invalid call to Next()");
break;
}
switch (htmlState)
@@ -311,36 +335,35 @@ std::string cHtmlChannelList::Next()
}
}
-std::string cHtmlChannelList::HtmlHead()
+std::string cHtmlMenuList::HtmlHead()
{
return (std::string) "<link rel=\"alternate\" type=\"application/rss+xml\" title=\"RSS\" href=\"" + rss + "\"/>";
}
-std::string cHtmlChannelList::PageTop()
+std::string cHtmlMenuList::PageTop()
{
return (std::string) "<div class=\"menu\"><div>" + menu + "</div><div>" + StreamTypeMenu() + "</div></div>";
}
-std::string cHtmlChannelList::PageBottom()
+std::string cHtmlMenuList::PageBottom()
{
return (std::string) "";
}
-std::string cHtmlChannelList::GroupTitle()
+std::string cHtmlMenuList::GroupTitle()
{
if (groupTarget)
{
- return (std::string) "<a href=\"" + groupTarget + "?group=" +
- (const char*) itoa(cChannelList::GetGroupIndex(current)) +
- "\">" + current->Name() + "</a>";
+ return (std::string) "<a href=\"" + groupTarget + "?group=" + (const char*) ItemId() + "\">" +
+ ItemTitle() + "</a>";
}
else
{
- return (std::string) current->Name();
+ return (std::string) ItemTitle();
}
}
-std::string cHtmlChannelList::ItemText()
+std::string cHtmlMenuList::ItemText()
{
std::string line;
std::string suffix;
@@ -352,58 +375,58 @@ std::string cHtmlChannelList::ItemText()
case stPES: suffix = (std::string) ".vdr"; break;
default: suffix = "";
}
- line += (std::string) "<li value=\"" + (const char*) itoa(current->Number()) + "\">";
- line += (std::string) "<a href=\"" + (std::string) current->GetChannelID().ToString() + suffix + "\"";
+ line += (std::string) "<li value=\"" + (const char*) ItemId() + "\">";
+ line += (std::string) "<a href=\"" + (const char*) ItemRessource() + suffix + "\"";
// for Network Media Tank
line += (std::string) " vod ";
- if (current->Number() < 1000)
- line += (std::string) " tvid=\"" + (const char*) itoa(current->Number()) + "\"";
-
- line += (std::string) ">" + current->Name() + "</a>";
+ if (strlen(ItemId()) < 4)
+ line += (std::string) " tvid=\"" + (const char*) ItemId() + "\"";
- int count = 0;
- for (int i = 0; current->Apid(i) != 0; ++i, ++count)
- ;
- for (int i = 0; current->Dpid(i) != 0; ++i, ++count)
- ;
+ line += (std::string) ">" + ItemTitle() + "</a>";
- if (count > 1)
+ // TS always streams all PIDs
+ if (streamType != stTS)
{
int index = 1;
- for (int i = 0; current->Apid(i) != 0; ++i, ++index) {
- line += (std::string) " <a href=\"" + (std::string) current->GetChannelID().ToString() +
- "+" + (const char*)itoa(index) + suffix + "\" class=\"apid\" vod>" + current->Alang(i) + "</a>";
- }
- for (int i = 0; current->Dpid(i) != 0; ++i, ++index) {
- line += (std::string) " <a href=\"" + (std::string) current->GetChannelID().ToString() +
- "+" + (const char*)itoa(index) + suffix + "\" class=\"dpid\" vod>" + current->Dlang(i) + "</a>";
- }
+ const char* lang;
+ std::string pids;
+ for (int i = 0; (lang = Alang(i)) != NULL; ++i, ++index) {
+ pids += (std::string) " <a href=\"" + (const char*) ItemRessource() +
+ "+" + (const char*)itoa(index) + suffix + "\" class=\"apid\" vod>" + (const char*) lang + "</a>";
+ }
+ for (int i = 0; (lang = Dlang(i)) != NULL; ++i, ++index) {
+ pids += (std::string) " <a href=\"" + (const char*) ItemRessource() +
+ "+" + (const char*)itoa(index) + suffix + "\" class=\"dpid\" vod>" + (const char*) lang + "</a>";
+ }
+ // always show audio PIDs for stES to select audio only
+ if (index > 2 || streamType == stES)
+ line += pids;
}
line += "</li>";
return line;
}
-// ******************** cM3uChannelList ******************
-cM3uChannelList::cM3uChannelList(cChannelIterator *Iterator, const char* Base)
-: cChannelList(Iterator),
+// ******************** cM3uMenuList ******************
+cM3uMenuList::cM3uMenuList(cItemIterator *Iterator, const char* Base)
+: cMenuList(Iterator),
m_IConv(cCharSetConv::SystemCharacterTable(), "UTF-8")
{
base = strdup(Base);
m3uState = msFirst;
}
-cM3uChannelList::~cM3uChannelList()
+cM3uMenuList::~cM3uMenuList()
{
free(base);
}
-bool cM3uChannelList::HasNext()
+bool cM3uMenuList::HasNext()
{
return m3uState != msLast;
}
-std::string cM3uChannelList::Next()
+std::string cM3uMenuList::Next()
{
if (m3uState == msFirst)
{
@@ -411,32 +434,30 @@ std::string cM3uChannelList::Next()
return "#EXTM3U";
}
- const cChannel *channel = NextChannel();
- if (!channel)
+ if (!NextItem())
{
m3uState = msLast;
return "";
}
- std::string name = (std::string) m_IConv.Convert(channel->Name());
+ std::string name = (std::string) m_IConv.Convert(ItemTitle());
- if (channel->GroupSep())
+ if (IsGroup())
{
return (std::string) "#EXTINF:-1," + name + "\r\n" +
- base + "group.m3u?group=" +
- (const char*) itoa(cChannelList::GetGroupIndex(channel));
+ base + "group.m3u?group=" + (const char*) ItemId();
}
else
{
return (std::string) "#EXTINF:-1," +
- (const char*) itoa(channel->Number()) + " " + name + "\r\n" +
- base + (std::string) channel->GetChannelID().ToString();
+ (const char*) ItemId() + " " + name + "\r\n" +
+ base + (const char*) ItemRessource();
}
}
-// ******************** cRssChannelList ******************
-cRssChannelList::cRssChannelList(cChannelIterator *Iterator, const char *Base, const char *Html)
-: cChannelList(Iterator),
+// ******************** cRssMenuList ******************
+cRssMenuList::cRssMenuList(cItemIterator *Iterator, const char *Base, const char *Html)
+: cMenuList(Iterator),
m_IConv(cCharSetConv::SystemCharacterTable(), "UTF-8")
{
base = strdup(Base);
@@ -444,18 +465,18 @@ cRssChannelList::cRssChannelList(cChannelIterator *Iterator, const char *Base, c
rssState = msFirst;
}
-cRssChannelList::~cRssChannelList()
+cRssMenuList::~cRssMenuList()
{
free(base);
free(html);
}
-bool cRssChannelList::HasNext()
+bool cRssMenuList::HasNext()
{
return rssState != msLast;
}
-std::string cRssChannelList::Next()
+std::string cRssMenuList::Next()
{
std::string type_ext;
@@ -469,27 +490,26 @@ std::string cRssChannelList::Next()
;
}
- const cChannel *channel = NextChannel();
- if (!channel)
+ if (!NextItem())
{
rssState = msLast;
return "\t</channel>\n</rss>\n";
}
- std::string name = (std::string) m_IConv.Convert(channel->Name());
+ std::string name = (std::string) m_IConv.Convert(ItemTitle());
- if (channel->GroupSep())
+ if (IsGroup())
{
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";
+ base + "group.rss?group=" + (const char*) ItemId() + "</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";
+ (const char*) ItemId() + " " + name + "</title>\n\t\t\t<link>" +
+ base + (const char*) ItemRessource() + "</link>\n\t\t\t<enclosure url=\"" +
+ base + (const char*) ItemRessource() + "\" type=\"video/mpeg\" />\n\t\t</item>\n";
}
}
diff --git a/server/menuHTTP.h b/server/menuHTTP.h
index b025598..ec759e9 100644
--- a/server/menuHTTP.h
+++ b/server/menuHTTP.h
@@ -6,16 +6,38 @@
class cChannel;
-// ******************** cChannelIterator ******************
-class cChannelIterator
+// ******************** cItemIterator ******************
+class cItemIterator
+{
+ public:
+ virtual bool Next() = 0;
+ virtual bool IsGroup() const = 0;
+ virtual const cString ItemId() const = 0;
+ virtual const char* ItemTitle() const = 0;
+ virtual const cString ItemRessource() const = 0;
+ virtual const char* Alang(int i) const = 0;
+ virtual const char* Dlang(int i) const = 0;
+};
+
+class cChannelIterator: public cItemIterator
{
private:
- const cChannel *channel;
+ const cChannel *first;
+ const cChannel *current;
protected:
virtual const cChannel* NextChannel(const cChannel *Channel) = 0;
static inline const cChannel* SkipFakeGroups(const cChannel *Channel);
+ // Helper which returns the group by its index
+ static const cChannel* GetGroup(const char* GroupId);
public:
- const cChannel* Next();
+
+ virtual bool Next();
+ virtual bool IsGroup() const { return current && current->GroupSep(); }
+ virtual const cString ItemId() const;
+ virtual const char* ItemTitle() const { return current ? current->Name() : ""; }
+ virtual const cString ItemRessource() const { return (current ? current->GetChannelID() : tChannelID::InvalidID).ToString(); }
+ virtual const char* Alang(int i) const { return current && current->Apid(i) ? current->Alang(i) : NULL; }
+ virtual const char* Dlang(int i) const { return current && current->Dpid(i) ? current->Dlang(i) : NULL; }
cChannelIterator(const cChannel *First);
virtual ~cChannelIterator() {};
};
@@ -54,7 +76,7 @@ class cListGroup: public cChannelIterator
protected:
virtual const cChannel* NextChannel(const cChannel *Channel);
public:
- cListGroup(const cChannel *Group);
+ cListGroup(const char *GroupId);
virtual ~cListGroup() {};
};
@@ -66,31 +88,32 @@ class cListTree: public cChannelIterator
protected:
virtual const cChannel* NextChannel(const cChannel *Channel);
public:
- cListTree(const cChannel *SelectedGroup);
+ cListTree(const char *SelectedGroupId);
virtual ~cListTree() {};
};
-// ******************** cChannelList ******************
-class cChannelList
+// ******************** cMenuList ******************
+class cMenuList
{
private:
- cChannelIterator *iterator;
+ cItemIterator *iterator;
protected:
- const cChannel* NextChannel() { return iterator->Next(); }
+ bool NextItem() { return iterator->Next(); }
+ bool IsGroup() { return iterator->IsGroup(); }
+ const cString ItemId() { return iterator->ItemId(); }
+ const char* ItemTitle() { return iterator->ItemTitle(); }
+ const cString ItemRessource() { return iterator->ItemRessource(); }
+ const char* Alang(int i) { return iterator->Alang(i); }
+ const char* Dlang(int i) { return iterator->Dlang(i); }
public:
- // Helper which returns the group index
- static int GetGroupIndex(const cChannel* Group);
- // Helper which returns the group by its index
- static const cChannel* GetGroup(int Index);
-
virtual std::string HttpHeader() { return "HTTP/1.0 200 OK\r\n"; };
virtual bool HasNext() = 0;
virtual std::string Next() = 0;
- cChannelList(cChannelIterator *Iterator);
- virtual ~cChannelList();
+ cMenuList(cItemIterator *Iterator);
+ virtual ~cMenuList();
};
-class cHtmlChannelList: public cChannelList
+class cHtmlMenuList: public cMenuList
{
private:
static const char* menu;
@@ -104,7 +127,7 @@ class cHtmlChannelList: public cChannelList
hsItemsTop, hsItem, hsItemsBottom
};
eHtmlState htmlState;
- const cChannel *current;
+ bool onItem;
eStreamType streamType;
const char* self;
const char* rss;
@@ -118,18 +141,18 @@ class cHtmlChannelList: public cChannelList
std::string PageBottom();
public:
virtual std::string HttpHeader() {
- return cChannelList::HttpHeader()
+ return cMenuList::HttpHeader()
+ "Content-type: text/html; charset="
+ (cCharSetConv::SystemCharacterTable() ? cCharSetConv::SystemCharacterTable() : "UTF-8")
+ "\r\n";
}
virtual bool HasNext();
virtual std::string Next();
- cHtmlChannelList(cChannelIterator *Iterator, eStreamType StreamType, const char *Self, const char *Rss, const char *GroupTarget);
- virtual ~cHtmlChannelList();
+ cHtmlMenuList(cItemIterator *Iterator, eStreamType StreamType, const char *Self, const char *Rss, const char *GroupTarget);
+ virtual ~cHtmlMenuList();
};
-class cM3uChannelList: public cChannelList
+class cM3uMenuList: public cMenuList
{
private:
char *base;
@@ -137,14 +160,14 @@ class cM3uChannelList: public cChannelList
eM3uState m3uState;
cCharSetConv m_IConv;
public:
- virtual std::string HttpHeader() { return cChannelList::HttpHeader() + "Content-type: audio/x-mpegurl; charset=UTF-8\r\n"; };
+ virtual std::string HttpHeader() { return cMenuList::HttpHeader() + "Content-type: audio/x-mpegurl; charset=UTF-8\r\n"; };
virtual bool HasNext();
virtual std::string Next();
- cM3uChannelList(cChannelIterator *Iterator, const char* Base);
- virtual ~cM3uChannelList();
+ cM3uMenuList(cItemIterator *Iterator, const char* Base);
+ virtual ~cM3uMenuList();
};
-class cRssChannelList: public cChannelList
+class cRssMenuList: public cMenuList
{
private:
char *base;
@@ -153,12 +176,12 @@ class cRssChannelList: public cChannelList
eRssState rssState;
cCharSetConv m_IConv;
public:
- virtual std::string HttpHeader() { return cChannelList::HttpHeader() + "Content-type: application/rss+xml\r\n"; };
+ virtual std::string HttpHeader() { return cMenuList::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();
+ cRssMenuList(cItemIterator *Iterator, const char *Base, const char *Html);
+ virtual ~cRssMenuList();
};
inline const cChannel* cChannelIterator::SkipFakeGroups(const cChannel* Group)