summaryrefslogtreecommitdiff
path: root/libs/fsScan/src
diff options
context:
space:
mode:
Diffstat (limited to 'libs/fsScan/src')
-rw-r--r--libs/fsScan/src/AbstractMedia.cc92
-rw-r--r--libs/fsScan/src/AbstractMultiFileMovie.cc111
-rw-r--r--libs/fsScan/src/Audio.cc65
-rw-r--r--libs/fsScan/src/DVDImage.cc100
-rw-r--r--libs/fsScan/src/FilesystemScanner.cc166
-rw-r--r--libs/fsScan/src/LegacyVdrRecording.cc91
-rw-r--r--libs/fsScan/src/MediaFactory.cc137
-rw-r--r--libs/fsScan/src/Movie.cc61
-rw-r--r--libs/fsScan/src/Picture.cc69
-rw-r--r--libs/fsScan/src/VdrRecording.cc91
10 files changed, 983 insertions, 0 deletions
diff --git a/libs/fsScan/src/AbstractMedia.cc b/libs/fsScan/src/AbstractMedia.cc
new file mode 100644
index 0000000..3a3556b
--- /dev/null
+++ b/libs/fsScan/src/AbstractMedia.cc
@@ -0,0 +1,92 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: AbstractMedia.cc
+ * Created: 2. Juli 2012, 14:33
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * 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 <AbstractMedia.h>
+#include <Logging.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <util.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+
+cAbstractMedia::cAbstractMedia(cAbstractMedia::SupportedMediaType Type, const char *Name, const char *Logical, const char *Path, const char *Mime)
+ : fd(-1)
+ , mediaType(Type)
+ , logicalPath(Logical ? strdup(Logical) : NULL)
+ , realPath(Path ? strdup(Path) : NULL)
+ , name(Name ? strdup(Name) : NULL)
+ , mimeType(Mime ? strdup(Mime) : NULL)
+ , lastModified(0)
+ , size(0)
+{
+}
+
+cAbstractMedia::~cAbstractMedia()
+{
+ free(logicalPath);
+ free(realPath);
+ free(name);
+ free(mimeType);
+}
+
+void cAbstractMedia::Refresh(void)
+{
+}
+
+size_t cAbstractMedia::ReadChunk(char* Buf, size_t bufSize)
+{
+ long rv = 0;
+
+ if (fd < 1) { // fp stays open between various calls
+ fd = open(RealPath(), O_RDONLY | O_LARGEFILE);
+ if (fd < 1) {
+ esyslog("could not open requested path %s - Error #%d", RealPath(), errno);
+ return 0;
+ }
+ }
+ isyslog("have filehandle #%d (%s)", fd, RealPath());
+ if ((rv = read(fd, Buf, bufSize)) < 0)
+ esyslog("ERROR: failed to read from file %s #%d", RealPath(), errno);
+ else
+ isyslog("read %u bytes from file", rv);
+ if (rv < (long) bufSize) { // most probabely end of file
+ close(fd);
+ }
+ return rv;
+}
+
+const char *cAbstractMedia::MediaType2Text(int Type)
+{
+ switch(Type) {
+ case Audio: return TO_STRING(Audio);
+ case Movie: return TO_STRING(Movie);
+ case DVDImage: return TO_STRING(DVDImage);
+ case LegacyVdrRecording: return TO_STRING(LegacyVdrRecording);
+ case VdrRecording: return TO_STRING(VdrRecording);
+ case Picture: return TO_STRING(Picture);
+ default: return TO_STRING(Invalid);
+ }
+} \ No newline at end of file
diff --git a/libs/fsScan/src/AbstractMultiFileMovie.cc b/libs/fsScan/src/AbstractMultiFileMovie.cc
new file mode 100644
index 0000000..bcbd115
--- /dev/null
+++ b/libs/fsScan/src/AbstractMultiFileMovie.cc
@@ -0,0 +1,111 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: AbstractMultiFileMovie.cc
+ * Created: 3. Juli 2012, 07:39
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * 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 <AbstractMultiFileMovie.h>
+#include <Logging.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+
+cAbstractMultiFileMovie::cAbstractMultiFileMovie(const char *Name, const char *Logical, const char *Path, const char *Mime, SupportedMediaType Type)
+ : cMovie(Name, Logical, Path, Mime, Type)
+ , movieFiles(0)
+ , curFileNo(0)
+ , fileNameBuf(NULL)
+ , bufSize(0)
+{
+}
+
+cAbstractMultiFileMovie::~cAbstractMultiFileMovie()
+{
+ free(fileNameBuf);
+}
+
+size_t cAbstractMultiFileMovie::ReadChunk(char* Buf, size_t bufSize)
+{
+ long rv = 0;
+
+ if (fd < 1) {
+ fd = open(FirstFile(), O_RDONLY | O_LARGEFILE);
+ if (fd < 1) {
+ esyslog("could not open requested path %s - Error #%d", FirstFile(), errno);
+ return 0;
+ }
+ }
+ isyslog("have filehandle #%d (%s)", fd, FirstFile());
+ rv = read(fd, Buf, bufSize);
+
+ if (rv < (long) bufSize) {
+ const char *nextFilename = NextFile();
+
+ if (nextFilename) {
+ close(fd);
+ fd = open(nextFilename, O_RDONLY | O_LARGEFILE);
+ if (fd < 1) {
+ esyslog("could not open requested path %s - Error #%d", nextFilename, errno);
+ return 0;
+ }
+ isyslog("have filehandle #%d (%s)", fd, nextFilename);
+ rv = read(fd, Buf, bufSize);
+ }
+ if (rv < (long) bufSize) {
+ close(fd);
+ fd = -1;
+ }
+ }
+ return rv;
+}
+
+//int cAbstractMultiFileMovie::ReadBlah(char* buf, size_t bufSize)
+//{
+// size_t bytesRead = 0;
+//
+// if (!fp) {
+// if (!(fp = f open(FirstFile(), "r"))) {
+// //TODO: add some verbose error message?
+// return 0;
+// }
+// }
+//
+// bytesRead = f read(buf, sizeof(char), bufSize, fp);
+//
+// if (bytesRead < bufSize) {
+// const char *nextFilename = NextFile();
+//
+// if (nextFilename) {
+// f close(fp);
+// if (!(fp = f open(nextFilename, "r"))) {
+// //TODO: be verbose
+// return 0;
+// }
+// bytesRead += f read(buf + bytesRead, sizeof(char), bufSize - bytesRead, fp);
+// }
+// if (bytesRead < bufSize) {
+// f close(fp);
+// fp = NULL;
+// }
+// }
+// return bytesRead;
+//}
diff --git a/libs/fsScan/src/Audio.cc b/libs/fsScan/src/Audio.cc
new file mode 100644
index 0000000..25521dc
--- /dev/null
+++ b/libs/fsScan/src/Audio.cc
@@ -0,0 +1,65 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Audio.cc
+ * Created: 2. Juli 2012, 15:00
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * 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 <Audio.h>
+#include <stddef.h>
+#include <string.h>
+
+SupportedExtension cAudio::knownExtensions[] = {
+ { "aac", "audio/aac" },
+ { "aif", "audio/x-aiff" },
+ { "aiff", "audio/x-aiff" },
+ { "aifc", "audio/x-aiff" },
+ { "au", "audio/x-au" },
+ { "fla", "audio/flac" },
+ { "flac", "audio/flac" },
+ { "oga", "audio/ogg" },
+ { "ogg", "audio/ogg" },
+ { "mka", "audio/x-matroska" },
+ { "mp3", "audio/mpeg" },
+ { "mp4", "audio/x-mpeg4" },
+ { "m4a", "audio/x-m4" },
+ { "mpg", "audio/mpeg" },
+ { "mpp", "audio/x-musepack" },
+ { "ram", "audio/x-realaudio" },
+ { NULL, NULL }
+};
+
+cAudio::cAudio(const char *Name, const char *Logical, const char *Path, const char *Mime)
+ : cAbstractMedia(Audio, Name, Logical, Path, Mime)
+{
+}
+
+cAudio::~cAudio()
+{
+}
+
+const char *cAudio::ContentType(const char* Extension)
+{
+ for (SupportedExtension *p = knownExtensions; p && p->extension; ++p) {
+ if (!strcasecmp(p->extension, Extension)) return p->mimeType;
+ }
+ return NULL;
+}
+
diff --git a/libs/fsScan/src/DVDImage.cc b/libs/fsScan/src/DVDImage.cc
new file mode 100644
index 0000000..5ffb170
--- /dev/null
+++ b/libs/fsScan/src/DVDImage.cc
@@ -0,0 +1,100 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: DVDImage.cc
+ * Created: 3. Juli 2012, 08:34
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * 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 <DVDImage.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#define FILE_MASK "VIDEO_TS/VTS_%02d_%d.VOB"
+
+cDVDImage::cDVDImage(const char *Name, const char *Logical, const char *Path)
+ : cAbstractMultiFileMovie(Name, Logical, Path, "video/mpeg", DVDImage)
+{
+}
+
+cDVDImage::~cDVDImage()
+{
+}
+
+void cDVDImage::Refresh(void)
+{
+ struct stat stBuf;
+ size_t maxSize = 0;
+ size_t total = 0;
+ time_t lastMod = 0;
+
+ if (!fileNameBuf) {
+ if (!(fileNameBuf = (char *)malloc(strlen(RealPath()) + 10))) {
+ //TODO: some error message?
+ return;
+ }
+ strcpy(fileNameBuf, RealPath());
+ }
+ movieFiles = 0;
+ mainMovie = 0;
+
+ for (int movie = 1; movie < 100; ++movie) {
+ total = 0;
+ for (int fileNo = 1;; ++fileNo) {
+ sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, movie, fileNo);
+ if (stat(fileNameBuf, &stBuf) < 0) {
+ movieFiles = fileNo - 1;
+ break;
+ }
+ total += stBuf.st_size;
+ if (stBuf.st_mtime > lastMod) lastMod = stBuf.st_mtime;
+ }
+ if (total > maxSize) {
+ maxSize = total;
+ mainMovie = movie;
+ }
+ }
+ SetSize(total);
+ SetLastModified(lastMod);
+}
+
+const char *cDVDImage::FirstFile(void)
+{
+ if (!fileNameBuf) {
+ if (!(fileNameBuf = (char *)malloc(strlen(RealPath()) + 10))) {
+ //TODO: some error message?
+ return NULL;
+ }
+ strcpy(fileNameBuf, RealPath());
+ }
+ curFileNo = 1;
+ sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, mainMovie, curFileNo);
+
+ return fileNameBuf;
+}
+
+const char *cDVDImage::NextFile(void)
+{
+ if (++curFileNo < movieFiles) {
+ sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, mainMovie, curFileNo);
+
+ return fileNameBuf;
+ }
+ return NULL;
+}
diff --git a/libs/fsScan/src/FilesystemScanner.cc b/libs/fsScan/src/FilesystemScanner.cc
new file mode 100644
index 0000000..8377691
--- /dev/null
+++ b/libs/fsScan/src/FilesystemScanner.cc
@@ -0,0 +1,166 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: FilesystemScanner.cc
+ * Created: 2. Juli 2012, 13:58
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * 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 <FilesystemScanner.h>
+#include <AbstractMedia.h>
+#include <Logging.h>
+#include <stddef.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/dir.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <errno.h>
+#include <util.h>
+
+void freeMediaCallback(void *elem)
+{
+ delete (cAbstractMedia *)elem;
+}
+
+cFilesystemScanner::cFilesystemScanner()
+ : baseDirectory(NULL)
+ , fileBufSize(512)
+ , dirEntryBuf(NULL)
+ , pool(freeMediaCallback)
+ , mediaFactory(NULL)
+{
+}
+
+cFilesystemScanner::~cFilesystemScanner()
+{
+ FREE(dirEntryBuf);
+ FREE(baseDirectory);
+ pool.clear();
+ if (mediaFactory) delete mediaFactory;
+}
+
+void cFilesystemScanner::SetBaseDirectory(const char* dir)
+{
+ FREE(baseDirectory);
+ baseDirectory = strdup(dir);
+ if (mediaFactory) mediaFactory->SetBaseDirectory(dir);
+}
+
+void cFilesystemScanner::SetMediaFactory(cMediaFactory* factory)
+{
+ if ((mediaFactory = factory)) {
+ FREE(baseDirectory);
+ baseDirectory = strdup(mediaFactory->BaseDirectory());
+ }
+}
+
+// return true if a should be ordered before b
+bool defaultMediaSortOrder(void *a, void *b)
+{
+ if (!a && !b) return true;
+ if (!a && b) return false;
+ if (a && !b) return true;
+ cAbstractMedia *m0 = (cAbstractMedia *)a;
+ cAbstractMedia *m1 = (cAbstractMedia *)b;
+ bool rv = (m0->MediaType() - m1->MediaType()) < 0;
+
+ if (!rv) rv = strcmp(m0->Name(), m1->Name());
+
+ return rv;
+}
+
+void cFilesystemScanner::Refresh()
+{
+ if (!mediaFactory) return;
+ pool.clear();
+ categories.clear();
+ dirEntryBuf = (struct dirent *)malloc(sizeof(struct dirent));
+ if (!dirEntryBuf) {
+ esyslog("ERROR: out of memory!");
+ return;
+ }
+ parseDir(baseDirectory, pool);
+ FREE(dirEntryBuf);
+#ifdef REDNOSE
+ pool.sort(defaultMediaSortOrder);
+#else
+ pool.sort(NULL);
+#endif
+ cAbstractMedia::SupportedMediaType ot = cAbstractMedia::Invalid;
+ cAbstractMedia *m;
+
+ for (size_t i=0; i < pool.size(); ++i) {
+ m = (cAbstractMedia *) pool[i];
+ if (m->MediaType() != ot) {
+ ot = m->MediaType();
+ categories[ot] = i;
+ }
+ }
+}
+
+void cFilesystemScanner::parseDir(const char* dirName, cManagedVector &result)
+{
+ if (!mediaFactory) return;
+ DIR *dir = opendir(dirName);
+ cAbstractMedia *media;
+ char *pathBuf = (char *)malloc(fileBufSize);
+ struct dirent *dirEntry;
+ struct stat statBuf;
+
+ if (!dir) return;
+ if (!pathBuf) {
+ closedir(dir);
+ return;
+ }
+ if (fileBufSize < strlen(dirName) + 128) {
+ fileBufSize += 256;
+ pathBuf = (char *)realloc(pathBuf, fileBufSize);
+ }
+ while (!readdir_r(dir, dirEntryBuf, &dirEntry) && dirEntry) {
+ if (*dirEntry->d_name == '.') continue; // don't bother with hidden stuff
+ strcpy(pathBuf, dirName);
+ strcat(pathBuf, "/");
+ strcat(pathBuf, dirEntry->d_name);
+ if (stat(pathBuf, &statBuf) < 0) return;
+ if ((media = mediaFactory->CreateMedia(pathBuf, &statBuf))) {
+ result.push_back(media);
+ isyslog("found media %s - %s", media->MimeType(), media->LogicalPath());
+ continue;
+ }
+ if ((statBuf.st_mode & S_IFMT) == S_IFDIR) parseDir(pathBuf, result);
+ }
+ closedir(dir);
+ FREE(pathBuf);
+}
+
+cAbstractMedia *cFilesystemScanner::FindMedia(const char* LogicalPath)
+{
+ cAbstractMedia *rv = NULL, *tmp;
+
+ for (size_t i=0; i < pool.size(); ++i) {
+ tmp = (cAbstractMedia *) pool[i];
+ if (!strcmp(tmp->LogicalPath(), LogicalPath)) {
+ rv = tmp;
+ break;
+ }
+ }
+ return rv;
+} \ No newline at end of file
diff --git a/libs/fsScan/src/LegacyVdrRecording.cc b/libs/fsScan/src/LegacyVdrRecording.cc
new file mode 100644
index 0000000..ea2ed35
--- /dev/null
+++ b/libs/fsScan/src/LegacyVdrRecording.cc
@@ -0,0 +1,91 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: LegacyVdrRecording.cc
+ * Created: 3. Juli 2012, 08:16
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * 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 <LegacyVdrRecording.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#define FILE_MASK "/%03d.vdr"
+
+cLegacyVdrRecording::cLegacyVdrRecording(const char *Name, const char *Logical, const char *Path)
+ : cAbstractMultiFileMovie(Name, Logical, Path, "video/mpeg", LegacyVdrRecording)
+{
+}
+
+cLegacyVdrRecording::~cLegacyVdrRecording()
+{
+}
+
+void cLegacyVdrRecording::Refresh(void)
+{
+ struct stat stBuf;
+ size_t total = 0;
+ time_t lastMod = 0;
+
+ if (!fileNameBuf) {
+ if (!(fileNameBuf = (char *)malloc(strlen(RealPath()) + 10))) {
+ //TODO: some error message?
+ return;
+ }
+ strcpy(fileNameBuf, RealPath());
+ }
+ movieFiles = 0;
+
+ for (int fileNo = 1;; ++fileNo) {
+ sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, fileNo);
+ if (stat(fileNameBuf, &stBuf) < 0) {
+ movieFiles = fileNo - 1;
+ break;
+ }
+ total += stBuf.st_size;
+ if (stBuf.st_mtime > lastMod) lastMod = stBuf.st_mtime;
+ }
+ SetSize(total);
+ SetLastModified(lastMod);
+}
+
+const char *cLegacyVdrRecording::FirstFile(void)
+{
+ if (!fileNameBuf) {
+ if (!(fileNameBuf = (char *)malloc(strlen(RealPath()) + 10))) {
+ //TODO: some error message?
+ return NULL;
+ }
+ strcpy(fileNameBuf, RealPath());
+ }
+ curFileNo = 1;
+ sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, curFileNo);
+
+ return fileNameBuf;
+}
+
+const char *cLegacyVdrRecording::NextFile(void)
+{
+ if (++curFileNo < movieFiles) {
+ sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, curFileNo);
+
+ return fileNameBuf;
+ }
+ return NULL;
+}
diff --git a/libs/fsScan/src/MediaFactory.cc b/libs/fsScan/src/MediaFactory.cc
new file mode 100644
index 0000000..a94fbb1
--- /dev/null
+++ b/libs/fsScan/src/MediaFactory.cc
@@ -0,0 +1,137 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: MediaFactory.cc
+ * Created: 2. Juli 2012, 15:43
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * 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 <MediaFactory.h>
+#include <Audio.h>
+#include <Movie.h>
+#include <Picture.h>
+#include <LegacyVdrRecording.h>
+#include <VdrRecording.h>
+#include <DVDImage.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+cMediaFactory::cMediaFactory(const char *BaseDirectory)
+ : baseDirectory(BaseDirectory ? strdup(BaseDirectory) : NULL)
+ , scratch(NULL)
+ , scratchSize(1024)
+{
+ if (baseDirectory && *(baseDirectory + strlen(baseDirectory) - 1) == '/')
+ *(baseDirectory + strlen(baseDirectory) - 1) = 0;
+ scratch = (char *)malloc(scratchSize);
+}
+
+cMediaFactory::~cMediaFactory()
+{
+ free(scratch);
+ free(baseDirectory);
+}
+
+void cMediaFactory::SetBaseDirectory(const char* dir)
+{
+ if (baseDirectory == dir) return;
+ char *tmp = baseDirectory;
+ baseDirectory = NULL;
+ free(tmp);
+ if (dir) {
+ baseDirectory = strdup(dir);
+ if (*(baseDirectory + strlen(baseDirectory) - 1) == '/')
+ *(baseDirectory + strlen(baseDirectory) - 1) = 0;
+ }
+}
+
+cAbstractMedia *cMediaFactory::CreateMedia(const char* FileOrDirname, struct stat *st)
+{
+ const char *name = rindex(FileOrDirname, '/') + 1;
+ const char *logical = FileOrDirname + strlen(baseDirectory);
+ const char *mimeType = NULL;
+ cAbstractMedia *rv = NULL;
+
+// printf("CreateMedia(%s) ... name=[%s], logical=[%s]\n", FileOrDirname, name, logical);
+ if ((st->st_mode & S_IFMT) == S_IFDIR) {
+ static const char *addons[] = { "/001.vdr", "/00001.ts", "/VIDEO_TS/VIDEO_TS.IFO", "/video_ts/VIDEO_TS.IFO", "/video_ts/video_ts.ifo", NULL };
+ struct stat stBuf;
+ int n=0;
+
+ if (scratchSize < (strlen(FileOrDirname) + 32)) {
+ scratchSize += 128;
+ scratch = (char *)realloc(scratch, scratchSize);
+ }
+ if (!scratch) return NULL;
+
+ for (const char **pa = addons; pa && *pa; ++pa, ++n) {
+ strcpy(scratch, FileOrDirname);
+ strcat(scratch, *pa);
+
+ if (stat(scratch, &stBuf) < 0) continue;
+
+ if ((stBuf.st_mode & S_IFMT) == S_IFREG) {
+ if (n < 2) {
+ char *tmp = rindex(scratch, '/'); // filename
+ char *p = tmp;
+
+ *p = ')';
+ *(p + 2) = 0;
+ tmp = rindex(scratch, '/'); // ts-directory
+
+ for (; p > tmp; --p) *(p + 1) = *p; // shift it up one position
+ *(p + 1) = '('; // start of ts-directory
+ *tmp = ' '; // add separator
+ tmp = rindex(scratch, '/'); // name of vdr recording
+ if (tmp) name = tmp + 1;
+ }
+ switch (n) {
+ case 0: rv = new cLegacyVdrRecording(name, logical, FileOrDirname); break;
+ case 1: rv = new cVdrRecording(name, logical, FileOrDirname); break;
+ default: rv = new cDVDImage(name, logical, FileOrDirname); break;
+ }
+ rv->SetLastModified(st->st_mtime);
+ }
+ }
+ }
+ else if ((st->st_mode & S_IFMT) == S_IFREG) {
+ const char *extension = rindex(FileOrDirname, '.');
+
+ if (!extension) return NULL;
+ ++extension;
+
+ mimeType = cMovie::ContentType(extension);
+ if (mimeType) rv = new cMovie(name, logical, FileOrDirname, mimeType);
+ else {
+ mimeType = cAudio::ContentType(extension);
+ if (mimeType) rv = new cAudio(name, logical, FileOrDirname, mimeType);
+ else {
+ mimeType = cPicture::ContentType(extension);
+ if (mimeType) rv = new cPicture(name, logical, FileOrDirname, mimeType);
+ }
+ }
+ if (rv) {
+ rv->SetLastModified(st->st_mtime);
+ rv->SetSize(st->st_size);
+ }
+ }
+ return rv;
+} \ No newline at end of file
diff --git a/libs/fsScan/src/Movie.cc b/libs/fsScan/src/Movie.cc
new file mode 100644
index 0000000..a558f81
--- /dev/null
+++ b/libs/fsScan/src/Movie.cc
@@ -0,0 +1,61 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Movie.cc
+ * Created: 2. Juli 2012, 15:12
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * 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 <Movie.h>
+#include <stddef.h>
+#include <string.h>
+
+SupportedExtension cMovie::knownExtensions[] = {
+ { "asd", "video/x-ms-asf" },
+ { "asf", "video/x-ms-asf" },
+ { "avi", "video/x-msvideo" },
+ { "dv", "video/x-dv" },
+ { "flv", "video/x-flv" },
+ { "gl", "video/x-gl" },
+ { "iso", "application/x-iso9660-image" },
+ { "ogv", "video/ogg" },
+ { "mkv", "video/x-matroska" },
+ { "mov", "video/quicktime" },
+ { "mpeg", "video/mpeg" },
+ { "swf", "application/x-shockwave-flash" },
+ { NULL, NULL }
+};
+
+cMovie::cMovie(const char *Name, const char *Logical, const char *Path, const char *Mime, SupportedMediaType Type)
+ : cAbstractMedia(Type, Name, Logical, Path, Mime)
+{
+}
+
+cMovie::~cMovie()
+{
+}
+
+const char *cMovie::ContentType(const char* Extension)
+{
+ for (SupportedExtension *p = knownExtensions; p && p->extension; ++p) {
+ if (!strcasecmp(p->extension, Extension)) return p->mimeType;
+ }
+ return NULL;
+}
+
diff --git a/libs/fsScan/src/Picture.cc b/libs/fsScan/src/Picture.cc
new file mode 100644
index 0000000..3c44ce6
--- /dev/null
+++ b/libs/fsScan/src/Picture.cc
@@ -0,0 +1,69 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Picture.cc
+ * Created: 2. Juli 2012, 15:18
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * 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 <Picture.h>
+#include <stddef.h>
+#include <string.h>
+
+SupportedExtension cPicture::knownExtensions[] = {
+ { "bmp", "image/x-windows-bmp" },
+ { "gif", "image/gif" },
+ { "jff", "image/jpeg" },
+ { "jfif", "image/jpeg" },
+ { "jif", "image/jpeg" },
+ { "jp2", "image/jp2" },
+ { "jpe", "image/jpeg" },
+ { "jpeg", "image/jpeg" },
+ { "jpg", "image/jpeg" },
+ { "jpm", "image/jpm" },
+ { "jpx", "image/jpx" },
+ { "pbm", "image/x-portable-bitmap" },
+ { "pct", "image/x-pict" },
+ { "pcx", "image/x-pcx" },
+ { "png", "image/png" },
+ { "pnm", "image/x-portable-anymap" },
+ { "ppm", "image/x-portable-pixmap" },
+ { "qti", "image/quicktime" },
+ { "ras", "image/x-cmu-raster" },
+ { "rgb", "image/x-rgb" },
+ { NULL, NULL }
+};
+
+cPicture::cPicture(const char *Name, const char *Logical, const char *Path, const char *Mime)
+: cAbstractMedia(Picture, Name, Logical, Path, Mime)
+{
+}
+
+cPicture::~cPicture()
+{
+}
+
+const char *cPicture::ContentType(const char* Extension)
+{
+ for (SupportedExtension *p = knownExtensions; p && p->extension; ++p) {
+ if (!strcasecmp(p->extension, Extension)) return p->mimeType;
+ }
+ return NULL;
+}
+
diff --git a/libs/fsScan/src/VdrRecording.cc b/libs/fsScan/src/VdrRecording.cc
new file mode 100644
index 0000000..f706477
--- /dev/null
+++ b/libs/fsScan/src/VdrRecording.cc
@@ -0,0 +1,91 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: VdrRecording.cc
+ * Created: 3. Juli 2012, 08:30
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * 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 <VdrRecording.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#define FILE_MASK "/%05d.ts"
+
+cVdrRecording::cVdrRecording(const char *Name, const char *Logical, const char *Path)
+ : cAbstractMultiFileMovie(Name, Logical, Path, "video/mpeg", VdrRecording)
+{
+}
+
+cVdrRecording::~cVdrRecording()
+{
+}
+
+void cVdrRecording::Refresh(void)
+{
+ struct stat stBuf;
+ size_t total = 0;
+ time_t lastMod = 0;
+
+ if (!fileNameBuf) {
+ if (!(fileNameBuf = (char *)malloc(strlen(RealPath()) + 10))) {
+ //TODO: some error message?
+ return;
+ }
+ strcpy(fileNameBuf, RealPath());
+ }
+ movieFiles = 0;
+
+ for (int fileNo = 1;; ++fileNo) {
+ sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, fileNo);
+ if (stat(fileNameBuf, &stBuf) < 0) {
+ movieFiles = fileNo - 1;
+ break;
+ }
+ total += stBuf.st_size;
+ if (stBuf.st_mtime > lastMod) lastMod = stBuf.st_mtime;
+ }
+ SetSize(total);
+ SetLastModified(lastMod);
+}
+
+const char *cVdrRecording::FirstFile(void)
+{
+ if (!fileNameBuf) {
+ if (!(fileNameBuf = (char *)malloc(strlen(RealPath()) + 16))) {
+ //TODO: some error message?
+ return NULL;
+ }
+ strcpy(fileNameBuf, RealPath());
+ }
+ curFileNo = 1;
+ sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, curFileNo);
+
+ return fileNameBuf;
+}
+
+const char *cVdrRecording::NextFile(void)
+{
+ if (++curFileNo < movieFiles) {
+ sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, curFileNo);
+
+ return fileNameBuf;
+ }
+ return NULL;
+}