summaryrefslogtreecommitdiff
path: root/cmps/serverlib/src
diff options
context:
space:
mode:
Diffstat (limited to 'cmps/serverlib/src')
-rw-r--r--cmps/serverlib/src/AbstractMediaRequestHandler.cc46
-rw-r--r--cmps/serverlib/src/CommandHandler.cc94
-rw-r--r--cmps/serverlib/src/HTMLListAssembler.cc171
-rw-r--r--cmps/serverlib/src/HTTPMediaResponse.cc50
-rw-r--r--cmps/serverlib/src/JSonListAssembler.cc73
-rw-r--r--cmps/serverlib/src/MediaFileHandler.cc62
-rw-r--r--cmps/serverlib/src/MediaListHandler.cc101
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;
+}