From 57923c656e264a032391693132fbe3add86df941 Mon Sep 17 00:00:00 2001 From: schmirl Date: Fri, 28 Mar 2008 15:13:11 +0000 Subject: [PATCH] Missing files --- server/menuHTTP.c | 420 ++++++++++++++++++++++++++++++++++++++++++++++ server/menuHTTP.h | 140 ++++++++++++++++ 2 files changed, 560 insertions(+) create mode 100644 server/menuHTTP.c create mode 100644 server/menuHTTP.h diff --git a/server/menuHTTP.c b/server/menuHTTP.c new file mode 100644 index 0000000..b5bb299 --- /dev/null +++ b/server/menuHTTP.c @@ -0,0 +1,420 @@ +#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) +#if defined(APIVERSNUM) && APIVERSNUM >= 10503 + , m_IConv(cCharSetConv::SystemCharacterTable(), "UTF-8") +#endif +{ + 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 ""; + } + +#if defined(APIVERSNUM) && APIVERSNUM >= 10503 + std::string name = (std::string) m_IConv.Convert(channel->Name()); +#else + std::string name = channel->Name(); +#endif + + 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(); + } +} + diff --git a/server/menuHTTP.h b/server/menuHTTP.h new file mode 100644 index 0000000..8be613b --- /dev/null +++ b/server/menuHTTP.h @@ -0,0 +1,140 @@ +#ifndef VDR_STREAMDEV_SERVERS_MENUHTTP_H +#define VDR_STREAMDEV_SERVERS_MENUHTTP_H + +#include +#include "../common.h" + +class cChannel; + +// ******************** cChannelIterator ****************** +class cChannelIterator +{ + private: + const cChannel *channel; + protected: + virtual const cChannel* NextChannel(const cChannel *Channel) = 0; + public: + const cChannel* Next(); + cChannelIterator(cChannel *First); + virtual ~cChannelIterator() {}; +}; + +class cListAll: public cChannelIterator +{ + protected: + virtual const cChannel* NextChannel(const cChannel *Channel); + public: + cListAll(); + virtual ~cListAll() {}; +}; + +class cListChannels: public cChannelIterator +{ + protected: + virtual const cChannel* NextChannel(const cChannel *Channel); + public: + cListChannels(); + virtual ~cListChannels() {}; +}; + +class cListGroups: public cChannelIterator +{ + protected: + virtual const cChannel* NextChannel(const cChannel *Channel); + public: + cListGroups(); + virtual ~cListGroups() {}; +}; + +class cListGroup: public cChannelIterator +{ + protected: + virtual const cChannel* NextChannel(const cChannel *Channel); + public: + cListGroup(const cChannel *Group); + virtual ~cListGroup() {}; +}; + +class cListTree: public cChannelIterator +{ + private: + const cChannel* selectedGroup; + const cChannel* currentGroup; + protected: + virtual const cChannel* NextChannel(const cChannel *Channel); + public: + cListTree(const cChannel *SelectedGroup); + virtual ~cListTree() {}; +}; + +// ******************** cChannelList ****************** +class cChannelList +{ + private: + cChannelIterator *iterator; + protected: + const cChannel* NextChannel() { return iterator->Next(); } + 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(); +}; + +class cHtmlChannelList: public cChannelList +{ + private: + static const char* menu; + static const char* css; + static const char* js; + + enum eHtmlState { + hsRoot, hsHtmlHead, hsCss, hsJs, hsPageTop, hsPageBottom, + hsGroupTop, hsGroupBottom, + hsPlainTop, hsPlainItem, hsPlainBottom, + hsItemsTop, hsItem, hsItemsBottom + }; + eHtmlState htmlState; + const cChannel *current; + eStreamType streamType; + const char* self; + const char* groupTarget; + + std::string StreamTypeMenu(); + std::string HtmlHead(); + std::string PageTop(); + std::string GroupTitle(); + std::string ItemText(); + std::string PageBottom(); + public: + virtual std::string HttpHeader() { return cChannelList::HttpHeader() + "Content-type: text/html\r\n\r\n"; } + virtual bool HasNext(); + virtual std::string Next(); + cHtmlChannelList(cChannelIterator *Iterator, eStreamType StreamType, const char *Self, const char *GroupTarget); + virtual ~cHtmlChannelList(); +}; + +class cM3uChannelList: public cChannelList +{ + private: + char *base; + enum eM3uState { msFirst, msContinue, msLast }; + eM3uState m3uState; +#if defined(APIVERSNUM) && APIVERSNUM >= 10503 + cCharSetConv m_IConv; +#endif + public: + virtual std::string HttpHeader() { return cChannelList::HttpHeader() + "Content-type: audio/x-mpegurl\r\n"; }; + virtual bool HasNext(); + virtual std::string Next(); + cM3uChannelList(cChannelIterator *Iterator, const char* Base); + virtual ~cM3uChannelList(); +}; + +#endif