diff options
author | geronimo <geronimo013@gmx.de> | 2012-07-13 04:26:40 +0200 |
---|---|---|
committer | geronimo <geronimo013@gmx.de> | 2012-07-13 04:26:40 +0200 |
commit | 2d48ae784ea6828e8626c32c848f64232d8f35c0 (patch) | |
tree | fab114b03e91125783a778b835dd1913b039cebe /libs/fsScan/src | |
download | cmp-2d48ae784ea6828e8626c32c848f64232d8f35c0.tar.gz cmp-2d48ae784ea6828e8626c32c848f64232d8f35c0.tar.bz2 |
initial import
Diffstat (limited to 'libs/fsScan/src')
-rw-r--r-- | libs/fsScan/src/AbstractMedia.cc | 92 | ||||
-rw-r--r-- | libs/fsScan/src/AbstractMultiFileMovie.cc | 111 | ||||
-rw-r--r-- | libs/fsScan/src/Audio.cc | 65 | ||||
-rw-r--r-- | libs/fsScan/src/DVDImage.cc | 100 | ||||
-rw-r--r-- | libs/fsScan/src/FilesystemScanner.cc | 166 | ||||
-rw-r--r-- | libs/fsScan/src/LegacyVdrRecording.cc | 91 | ||||
-rw-r--r-- | libs/fsScan/src/MediaFactory.cc | 137 | ||||
-rw-r--r-- | libs/fsScan/src/Movie.cc | 61 | ||||
-rw-r--r-- | libs/fsScan/src/Picture.cc | 69 | ||||
-rw-r--r-- | libs/fsScan/src/VdrRecording.cc | 91 |
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; +} |