diff options
Diffstat (limited to 'cmps/serverlib/src')
-rw-r--r-- | cmps/serverlib/src/AbstractMediaRequestHandler.cc | 46 | ||||
-rw-r--r-- | cmps/serverlib/src/CommandHandler.cc | 94 | ||||
-rw-r--r-- | cmps/serverlib/src/HTMLListAssembler.cc | 171 | ||||
-rw-r--r-- | cmps/serverlib/src/HTTPMediaResponse.cc | 50 | ||||
-rw-r--r-- | cmps/serverlib/src/JSonListAssembler.cc | 73 | ||||
-rw-r--r-- | cmps/serverlib/src/MediaFileHandler.cc | 62 | ||||
-rw-r--r-- | cmps/serverlib/src/MediaListHandler.cc | 101 |
7 files changed, 597 insertions, 0 deletions
diff --git a/cmps/serverlib/src/AbstractMediaRequestHandler.cc b/cmps/serverlib/src/AbstractMediaRequestHandler.cc new file mode 100644 index 0000000..b65ad13 --- /dev/null +++ b/cmps/serverlib/src/AbstractMediaRequestHandler.cc @@ -0,0 +1,46 @@ +/** + * ======================== legal notice ====================== + * + * File: AbstractMediaRequestHandler.cc + * Created: 5. Juli 2012, 07:58 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmps - the backend (server) part of compound media player + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +#include <AbstractMediaRequestHandler.h> +#include <FilesystemScanner.h> + +static cFilesystemScanner *scanner = NULL; + +cAbstractMediaRequestHandler::cAbstractMediaRequestHandler() +{ +} + +cAbstractMediaRequestHandler::~cAbstractMediaRequestHandler() +{ +} + +cFilesystemScanner *cAbstractMediaRequestHandler::FileSystemScanner(void) +{ + return scanner; +} + +void cAbstractMediaRequestHandler::SetFilesystemScanner(cFilesystemScanner* Scanner) +{ + scanner = Scanner; +}
\ No newline at end of file diff --git a/cmps/serverlib/src/CommandHandler.cc b/cmps/serverlib/src/CommandHandler.cc new file mode 100644 index 0000000..b1a17b8 --- /dev/null +++ b/cmps/serverlib/src/CommandHandler.cc @@ -0,0 +1,94 @@ +/** + * ======================== legal notice ====================== + * + * File: CommandHandler.cc + * Created: 5. Juli 2012, 16:06 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmps - the backend (server) part of compound media player + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +#include <CommandHandler.h> +#include <tr1/unordered_map> +#include <HTTPRequest.h> +#include <HTTPResponse.h> +#include <StringBuilder.h> +#include <Logging.h> + +typedef struct { + CommandCallback callback; + void *opaque; +} CallbackInfo; +std::tr1::unordered_map<std::string, CallbackInfo *> supportedCommands; + + +cCommandHandler::cCommandHandler() +{ +} + +cCommandHandler::~cCommandHandler() +{ +} + +void cCommandHandler::Cleanup() +{ + std::tr1::unordered_map<std::string, CallbackInfo *>::iterator it = supportedCommands.begin(); + + while (it != supportedCommands.end()) { + free(it->second); + ++it; + } +} + +cHTTPResponse *cCommandHandler::ProcessRequest(cHTTPRequest& Request) +{ + const char *command = Request.GetHeader("what"); + CallbackInfo *info; + + isyslog("cCommandHandler::ProcessRequest ..."); + if (!command) { + esyslog("ERROR: no command in request"); + return new cHTTPResponse(HTTP_BadRequest); + } + info = supportedCommands[command]; + if (!info) { + esyslog("ERROR: command not registered/supported!"); + return new cHTTPResponse(HTTP_BadRequest); + } + if ((*info->callback)(info->opaque, Request)) { + esyslog("ERROR: failed to execute command!"); + return new cHTTPResponse(HTTP_InternalServerError); + } + isyslog("OK - all went well?!?"); + + return new cHTTPResponse(HTTP_NoContent); +} + +void cCommandHandler::Usage(cStringBuilder &sb) +{ + +} + +void cCommandHandler::RegisterCallback(const char* CommandID, CommandCallback cb, void* opaque) +{ + CallbackInfo *info = (CallbackInfo *)malloc(sizeof(CallbackInfo)); + + info->callback = cb; + info->opaque = opaque; + supportedCommands[CommandID] = info; +} + diff --git a/cmps/serverlib/src/HTMLListAssembler.cc b/cmps/serverlib/src/HTMLListAssembler.cc new file mode 100644 index 0000000..8ef3261 --- /dev/null +++ b/cmps/serverlib/src/HTMLListAssembler.cc @@ -0,0 +1,171 @@ +/** + * ======================== legal notice ====================== + * + * File: HTMLListAssembler.cc + * Created: 6. Juli 2012, 09:55 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmps - the backend (server) part of compound media player + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +#include <HTMLListAssembler.h> +#include <AbstractMedia.h> +#include <StringBuilder.h> +#include <tools.h> + +cHTMLListAssembler::cHTMLListAssembler() +{ +} + +cHTMLListAssembler::~cHTMLListAssembler() +{ +} + +bool cHTMLListAssembler::OpenList(cStringBuilder &sb, std::map<int, size_t> &Categories, size_t total, size_t start, uint delta) +{ + genHTMLPrefix(sb, "Medien-Liste"); + + genPreviousLink(sb, !start ? -1 : max<size_t>(0, start - delta)); + genNextLink(sb, start + delta >= total ? -1 : min(start + delta, total)); + genDelim(sb); + genTypeMenu(sb, Categories); + genDelim(sb); + + return true; +} + +bool cHTMLListAssembler::AddElement(cStringBuilder &sb, void *ListElement, bool odd) +{ + genMediaLink(sb, ListElement, odd); + + return true; +} + +bool cHTMLListAssembler::CloseList(cStringBuilder &sb, size_t total, size_t start, uint delta) +{ + genDelim(sb); + genPreviousLink(sb, !start ? -1 : max<size_t>(0, start - delta)); + genNextLink(sb, start + delta >= total ? -1 : min(start + delta, total)); + + return true; +} + +cStringBuilder &cHTMLListAssembler::genHTMLPrefix(cStringBuilder& sb, const char *Title) +{ + sb.Append("<html><head><title>").Append(Title).Append("</title>"); + + sb.Append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">"); + sb.Append("<style type=\"text/css\"><!--\n"); + sb.Append("body { background: #eef; } "); + sb.Append("h1 { margin: 0; margin-top: 20px; padding: 0; text-align: center; } "); + sb.Append(".left { text-align: left; } "); + sb.Append(".right { margin-top: -1em; text-align: right; } "); + sb.Append(".center { text-align: center; } "); + sb.Append(".hmenu { padding: 1em; margin-left: 1em; } "); + sb.Append(".odd { display: block; background: #DDF; margin-left: 1em; margin-right: 1em; padding: 5px; padding-left: 1em; } "); + sb.Append(".even { display: block; background: #EEF; margin-left: 1em; margin-right: 1em; padding: 5px; padding-left: 1em; } "); + sb.Append("\n--></style>"); + sb.Append("</head><body><h1>").Append(Title).Append("</h1>"); + + return sb; +} + +const char *cHTMLListAssembler::MediaType() const +{ + return "text/html"; +} + +cStringBuilder &cHTMLListAssembler::genDelim(cStringBuilder &sb) +{ + return sb.Append("<div class=\"break\"><hr/></div>"); +} + +cStringBuilder &cHTMLListAssembler::genMediaLink(cStringBuilder &sb, void *Element, bool odd) +{ + cAbstractMedia *m = (cAbstractMedia *)Element; + + sb.Append("<a class=\""); + sb.Append(odd ? "odd" : "even"); + sb.Append("\" href=\""); + sb.Append(m->LogicalPath()); + sb.Append("\">"); + switch (m->MediaType()) { + case cAbstractMedia::Audio: sb.Append("[A] "); break; + case cAbstractMedia::Movie: sb.Append("[M] "); break; + case cAbstractMedia::DVDImage: sb.Append("[D] "); break; + case cAbstractMedia::LegacyVdrRecording: sb.Append("[L] "); break; + case cAbstractMedia::VdrRecording: sb.Append("[V] "); break; + case cAbstractMedia::Picture: sb.Append("[P] "); break; + default: ; + } + sb.Append(m->Name()); + sb.Append("</a>"); + + return sb; +} + +cStringBuilder &cHTMLListAssembler::genNextLink(cStringBuilder &sb, int n) +{ + sb.Append("<div class=\"right\">"); + if (n < 0) + sb.Append("next"); + else { + sb.Append("<a href=\"/?start="); + sb.Append(n); + sb.Append("\">"); + sb.Append("next"); + sb.Append("</a>"); + } + sb.Append("</div>"); + + return sb; +} + +cStringBuilder &cHTMLListAssembler::genPreviousLink(cStringBuilder &sb, int n) +{ + sb.Append("<div class=\"left\">"); + if (n < 0) + sb.Append("previous"); + else { + sb.Append("<a href=\"/?start="); + sb.Append(n); + sb.Append("\">"); + sb.Append("previous"); + sb.Append("</a>"); + } + sb.Append("</div>"); + + return sb; +} + +cStringBuilder &cHTMLListAssembler::genTypeMenu(cStringBuilder &sb, std::map<int, size_t> &Categories) +{ + sb.Append("<div class=\"topmenu\">"); + std::map<int, size_t>::iterator it = Categories.begin(); + + while (it != Categories.end()) { + sb.Append("<a class=\"hmenu\" href=\"/?start="); + sb.Append(it->second); + sb.Append("\">"); + sb.Append(cAbstractMedia::MediaType2Text(it->first)); + sb.Append("</a>"); + ++it; + } + sb.Append("</div>"); + + return sb; +}
\ No newline at end of file diff --git a/cmps/serverlib/src/HTTPMediaResponse.cc b/cmps/serverlib/src/HTTPMediaResponse.cc new file mode 100644 index 0000000..667d114 --- /dev/null +++ b/cmps/serverlib/src/HTTPMediaResponse.cc @@ -0,0 +1,50 @@ +/** + * ======================== legal notice ====================== + * + * File: HTTPMediaResponse.cc + * Created: 6. Juli 2012, 07:44 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmps - the backend (server) part of compound media player + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +#include <HTTPMediaResponse.h> +#include <stdlib.h> + +cHTTPMediaResponse::cHTTPMediaResponse(cAbstractMedia *Media) + : cHTTPFileResponse() + , media(Media) +{ + if (media) { + char *lm = FormatTime(media->LastModified()); + + SetHeader("LastModified", lm); + free(lm); + SetContentSize(media->Size()); + SetContentType(media->MimeType()); + } +} + +cHTTPMediaResponse::~cHTTPMediaResponse() +{ +} + +size_t cHTTPMediaResponse::ReadContentChunk(char* Buf, size_t bufSize) +{ + if (!media) return 0; + return media->ReadChunk(Buf, bufSize); +}
\ No newline at end of file diff --git a/cmps/serverlib/src/JSonListAssembler.cc b/cmps/serverlib/src/JSonListAssembler.cc new file mode 100644 index 0000000..c5126a3 --- /dev/null +++ b/cmps/serverlib/src/JSonListAssembler.cc @@ -0,0 +1,73 @@ +/** + * ======================== legal notice ====================== + * + * File: JSonListAssembler.cc + * Created: 6. Juli 2012, 09:53 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmps - the backend (server) part of compound media player + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +#include <JSonListAssembler.h> +#include <AbstractMedia.h> +#include <JSonWriter.h> + +cJSonListAssembler::cJSonListAssembler() +{ +} + +cJSonListAssembler::~cJSonListAssembler() +{ +} + +bool cJSonListAssembler::OpenList(cStringBuilder &sb, std::map<int, size_t> &Categories, size_t total, size_t start, uint delta) +{ + cJSonWriter writer(sb); + + writer.Object().Key("total").Value(total); + writer.Key("results").Array(); + + return true; +} + +bool cJSonListAssembler::AddElement(cStringBuilder &sb, void *ListElement, bool odd) +{ + cJSonWriter writer(sb); + cAbstractMedia *m = (cAbstractMedia *)ListElement; + + writer.Object(); + writer.Key("name").Value(m->Name()); + writer.Key("type").Value(m->MediaType()); + writer.Key("path").Value(m->LogicalPath()); + writer.EndObject(); + + return true; +} + +bool cJSonListAssembler::CloseList(cStringBuilder &sb, size_t total, size_t start, uint delta) +{ + cJSonWriter writer(sb); + + writer.EndArray().EndObject(); + + return true; +} + +const char *cJSonListAssembler::MediaType(void) const +{ + return "application/json"; +}
\ No newline at end of file diff --git a/cmps/serverlib/src/MediaFileHandler.cc b/cmps/serverlib/src/MediaFileHandler.cc new file mode 100644 index 0000000..d16a033 --- /dev/null +++ b/cmps/serverlib/src/MediaFileHandler.cc @@ -0,0 +1,62 @@ +/** + * ======================== legal notice ====================== + * + * File: MediaFileHandler.cc + * Created: 5. Juli 2012, 08:06 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmps - the backend (server) part of compound media player + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +#include <MediaFileHandler.h> +#include <AbstractMedia.h> +#include <FilesystemScanner.h> +#include <HTTPRequest.h> +#include <HTTPMediaResponse.h> +#include <StringBuilder.h> +#include <Logging.h> + +cMediaFileHandler::cMediaFileHandler() +{ +} + +cMediaFileHandler::~cMediaFileHandler() +{ +} + +cHTTPResponse *cMediaFileHandler::ProcessRequest(cHTTPRequest& Request) +{ + cAbstractMedia *media = FileSystemScanner()->FindMedia(Request.Url().Path()); + + isyslog("cMediaFileHandler::ProcessRequest ... %0X", media); + + if (!media) return NULL; + media->Refresh(); + + return new cHTTPMediaResponse(media); +} + +void cMediaFileHandler::Usage(cStringBuilder& sb) +{ + isyslog("start of cMediaFileHandler::Usage() ..."); + sb.Append("<dl><dt><em>"); + sb.Append("/any/path/to/media/file"); + sb.Append("</em></dt><dd>"); + sb.Append("returns the media-file ready to be played by client media-players."); + sb.Append("</dd></dl>"); + isyslog("end of cMediaFileHandler::Usage() ..."); +}
\ No newline at end of file diff --git a/cmps/serverlib/src/MediaListHandler.cc b/cmps/serverlib/src/MediaListHandler.cc new file mode 100644 index 0000000..029c137 --- /dev/null +++ b/cmps/serverlib/src/MediaListHandler.cc @@ -0,0 +1,101 @@ +/** + * ======================== legal notice ====================== + * + * File: MediaListHandler.cc + * Created: 5. Juli 2012, 08:06 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmps - the backend (server) part of compound media player + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +#include <MediaListHandler.h> +#include <AbstractListAssembler.h> +#include <FilesystemScanner.h> +#include <HTTPRequest.h> +#include <HTTPResponse.h> +#include <StringBuilder.h> +#include <Logging.h> + +cMediaListHandler::cMediaListHandler() +{ +} + +cMediaListHandler::~cMediaListHandler() +{ + AssemblerList::iterator it = listAssemblers.begin(); + + while (it != listAssemblers.end()) { + delete it->second; + ++it; + } + if (defaultListAssembler) delete defaultListAssembler; +} + +cAbstractListAssembler *cMediaListHandler::ListAssembler(const char* ID) +{ + if (!ID) return defaultListAssembler; + cAbstractListAssembler *rv = listAssemblers[ID]; + + if (rv) return rv; + return defaultListAssembler; +} + +cHTTPResponse *cMediaListHandler::ProcessRequest(cHTTPRequest& Request) +{ + isyslog("cMediaListHandler::ProcessRequest ..."); + cHTTPResponse *res = NULL; + cAbstractListAssembler *la = ListAssembler(Request.Url().Parameter("format")); + const char *hdStart = Request.Url().Parameter("start"); + const char *hdDelta = Request.Url().Parameter("limit"); + int start = 0; + int delta = 40; + + if (hdStart) start = atol(hdStart); + if (hdDelta) delta = atol(hdDelta); + if (!la) return new cHTTPResponse(HTTP_NotFound); + res = new cHTTPResponse(HTTP_OK); + res->SetContentType(la->MediaType()); + la->AssembleList(res->StringBuilder(), FileSystemScanner()->MediaPool(), FileSystemScanner()->Categories(), start, delta); + + return res; +} + +void cMediaListHandler::Usage(cStringBuilder& sb) +{ + isyslog("start of cMediaListHandler::Usage() ..."); + sb.Append("returns a list of known/supported media on this machine. To access any media from the list, "); + sb.Append("use the path as uri (using the http protocol).<br/>"); + sb.Append("<strong>supported parameters:</strong><ul>"); + sb.Append("<dl><dt>start=#</dt>"); + sb.Append("<dd>used to step list by chunks, where <em>#</em> stands for the index of the first element to retrieve</dd>"); + sb.Append("<dt>limit=#</dt>"); + sb.Append("<dd>gives the chunksize (default is 40), where <em>#</em> stands for the number of elements to retrieve</dd>"); + sb.Append("<dt>format=json</dt>"); + sb.Append("<dd>default format is html, so if you like to get the list in json format, use this parameter</dd>"); + sb.Append("</dl></ul>"); + isyslog("end of cMediaListHandler::Usage() ..."); +} + +void cMediaListHandler::SetDefaultListAssembler(cAbstractListAssembler* assembler) +{ + defaultListAssembler = assembler; +} + +void cMediaListHandler::SetListAssembler(const char* ID, cAbstractListAssembler* assembler) +{ + listAssemblers[ID] = assembler; +} |