#include #include "server/menuHTTP.h" //**************************** cChannelIterator ************** cChannelIterator::cChannelIterator(cChannel *First): channel(First) {} const cChannel* cChannelIterator::Next() { const cChannel *current = channel; channel = NextChannel(channel); return current; } //**************************** cListAll ************** cListAll::cListAll(): cChannelIterator(Channels.First()) {} const cChannel* cListAll::NextChannel(const cChannel *Channel) { if (Channel) Channel = Channels.Next(Channel); return Channel; } //**************************** cListChannels ************** cListChannels::cListChannels(): cChannelIterator(Channels.Get(Channels.GetNextNormal(-1))) {} const cChannel* cListChannels::NextChannel(const cChannel *Channel) { if (Channel) Channel = Channels.Get(Channels.GetNextNormal(Channel->Index())); return Channel; } // ********************* cListGroups **************** cListGroups::cListGroups(): cChannelIterator(Channels.Get(Channels.GetNextGroup(-1))) {} const cChannel* cListGroups::NextChannel(const cChannel *Channel) { if (Channel) Channel = Channels.Get(Channels.GetNextGroup(Channel->Index())); return Channel; } // // ********************* cListGroup **************** cListGroup::cListGroup(const cChannel *Group): cChannelIterator((Group && Group->GroupSep() && Channels.Next(Group) && !Channels.Next(Group)->GroupSep()) ? Channels.Next(Group) : NULL) {} const cChannel* cListGroup::NextChannel(const cChannel *Channel) { if (Channel) Channel = Channels.Next(Channel); return (Channel && !Channel->GroupSep()) ? Channel : NULL; } // // ********************* cListTree **************** cListTree::cListTree(const cChannel *SelectedGroup): cChannelIterator(Channels.Get(Channels.GetNextGroup(-1))) { selectedGroup = SelectedGroup; currentGroup = Channels.Get(Channels.GetNextGroup(-1)); } const cChannel* cListTree::NextChannel(const cChannel *Channel) { if (currentGroup == selectedGroup) { if (Channel) Channel = Channels.Next(Channel); if (Channel && Channel->GroupSep()) currentGroup = Channel; } else { if (Channel) Channel = Channels.Get(Channels.GetNextGroup(Channel->Index())); currentGroup = Channel; } return Channel; } // ******************** cChannelList ****************** cChannelList::cChannelList(cChannelIterator *Iterator) : iterator(Iterator) {} cChannelList::~cChannelList() { 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 = "[Home (no script)] " "[Tree View] " "[Groups (Playlist)] " "[Channels (Playlist)] "; const char* cHtmlChannelList::css = ""; const char* cHtmlChannelList::js = ""; std::string cHtmlChannelList::StreamTypeMenu() { std::string typeMenu; typeMenu += (streamType == stTS ? (std::string) "[TS] " : (std::string) "[TS] "); typeMenu += (streamType == stPS ? (std::string) "[PS] " : (std::string) "[PS] "); typeMenu += (streamType == stPES ? (std::string) "[PES] " : (std::string) "[PES] "); typeMenu += (streamType == stES ? (std::string) "[ES] " : (std::string) "[ES] "); typeMenu += (streamType == stExtern ? (std::string) "[Extern] " : (std::string) "[Extern] "); return typeMenu; } cHtmlChannelList::cHtmlChannelList(cChannelIterator *Iterator, eStreamType StreamType, const char *Self, const char *GroupTarget): cChannelList(Iterator) { streamType = StreamType; self = strdup(Self); groupTarget = (GroupTarget && *GroupTarget) ? strdup(GroupTarget) : NULL; htmlState = hsRoot; current = NULL; } cHtmlChannelList::~cHtmlChannelList() { free((void *) self); free((void *) groupTarget); } bool cHtmlChannelList::HasNext() { return htmlState != hsPageBottom; } std::string cHtmlChannelList::Next() { switch (htmlState) { case hsRoot: htmlState = hsHtmlHead; break; case hsHtmlHead: htmlState = hsCss; break; case hsCss: htmlState = *self ? hsPageTop : hsJs; break; case hsJs: htmlState = hsPageTop; break; case hsPageTop: current = NextChannel(); htmlState = current ? (current->GroupSep() ? hsGroupTop : hsPlainTop) : hsPageBottom; break; case hsPlainTop: htmlState = hsPlainItem; break; case hsPlainItem: current = NextChannel(); htmlState = current && !current->GroupSep() ? hsPlainItem : hsPlainBottom; break; case hsPlainBottom: htmlState = current ? hsGroupTop : hsPageBottom; break; case hsGroupTop: current = NextChannel(); htmlState = current && !current->GroupSep() ? hsItemsTop : hsGroupBottom; break; case hsItemsTop: htmlState = hsItem; break; case hsItem: current = NextChannel(); htmlState = current && !current->GroupSep() ? hsItem : hsItemsBottom; break; case hsItemsBottom: htmlState = hsGroupBottom; break; case hsGroupBottom: htmlState = current ? hsGroupTop : hsPageBottom; break; case hsPageBottom: default: esyslog("streamdev-server cHtmlChannelList: invalid call to Next()"); break; } switch (htmlState) { // NOTE: JavaScript requirements: // Group title is identified by

tag // Channel list must be a sibling of

with class "items" case hsHtmlHead: return "" + HtmlHead(); case hsCss: return css; case hsJs: return js; case hsPageTop: return "" + PageTop() + "
"; case hsGroupTop: return "

" + GroupTitle() + "

"; case hsItemsTop: case hsPlainTop: return "
    "; case hsItem: case hsPlainItem: return ItemText(); case hsItemsBottom: case hsPlainBottom: return "
"; case hsGroupBottom: return "
"; case hsPageBottom: return "
" + PageBottom() + ""; default: return ""; } } std::string cHtmlChannelList::HtmlHead() { return (std::string) ""; } std::string cHtmlChannelList::PageTop() { return (std::string) "
" + menu + "
" + StreamTypeMenu() + "
"; } std::string cHtmlChannelList::PageBottom() { return (std::string) ""; } std::string cHtmlChannelList::GroupTitle() { if (groupTarget) { return (std::string) "" + current->Name() + ""; } else { return (std::string) current->Name(); } } std::string cHtmlChannelList::ItemText() { std::string line; line += (std::string) "
  • Number()) + "\">"; line += (std::string) "GetChannelID().ToString() + "\">" + current->Name() + ""; int count = 0; for (int i = 0; current->Apid(i) != 0; ++i, ++count) ; for (int i = 0; current->Dpid(i) != 0; ++i, ++count) ; if (count > 1) { int index = 1; for (int i = 0; current->Apid(i) != 0; ++i, ++index) { line += (std::string) " GetChannelID().ToString() + "+" + (const char*)itoa(index) + "\" class=\"apid\">" + current->Alang(i) + ""; } for (int i = 0; current->Dpid(i) != 0; ++i, ++index) { line += (std::string) " GetChannelID().ToString() + "+" + (const char*)itoa(index) + "\" class=\"dpid\">" + current->Dlang(i) + ""; } } line += "
  • "; return line; } // ******************** cM3uChannelList ****************** cM3uChannelList::cM3uChannelList(cChannelIterator *Iterator, const char* Base) : cChannelList(Iterator), m_IConv(cCharSetConv::SystemCharacterTable(), "UTF-8") { base = strdup(Base); m3uState = msFirst; } cM3uChannelList::~cM3uChannelList() { free(base); } bool cM3uChannelList::HasNext() { return m3uState != msLast; } std::string cM3uChannelList::Next() { if (m3uState == msFirst) { m3uState = msContinue; return "#EXTM3U"; } const cChannel *channel = NextChannel(); if (!channel) { m3uState = msLast; return ""; } std::string name = (std::string) m_IConv.Convert(channel->Name()); if (channel->GroupSep()) { return (std::string) "#EXTINF:0," + name + "\r\n" + base + "group.m3u?group=" + (const char*) itoa(cChannelList::GetGroupIndex(channel)); } else { return (std::string) "#EXTINF:0," + (const char*) itoa(channel->Number()) + " " + name + "\r\n" + base + (std::string) channel->GetChannelID().ToString(); } }