diff options
author | thlo <t.lohmar@gmx.de> | 2013-09-14 18:11:01 +0200 |
---|---|---|
committer | thlo <t.lohmar@gmx.de> | 2013-09-14 18:11:01 +0200 |
commit | 971c1891c0f02e98859956ed8ef821cc5e53eed0 (patch) | |
tree | 60ea6d142d10c65f79fd1f788fab00e00197664d | |
parent | ab15172eb00855899da98c9b2b9b028a4d306789 (diff) | |
parent | b0bc0c365594276f6f14fec785e4fb8a37ad79c5 (diff) | |
download | vdr-plugin-smarttvweb-971c1891c0f02e98859956ed8ef821cc5e53eed0.tar.gz vdr-plugin-smarttvweb-971c1891c0f02e98859956ed8ef821cc5e53eed0.tar.bz2 |
Merge branch 'master' of git-vdr@projects.vdr-developer.org:vdr-plugin-smarttvweb.git
-rw-r--r-- | httpclient.c | 3 | ||||
-rwxr-xr-x | httpresource.c | 34 | ||||
-rw-r--r-- | responsebase.c | 27 | ||||
-rw-r--r-- | responsebase.h | 2 | ||||
-rw-r--r-- | responsefile.c | 27 | ||||
-rw-r--r-- | responsefile.h | 2 | ||||
-rwxr-xr-x | responsememblk.c | 86 | ||||
-rwxr-xr-x | responsememblk.h | 7 | ||||
-rwxr-xr-x | smarttvfactory.c | 9 | ||||
-rw-r--r-- | smarttvweb.conf | 5 | ||||
-rwxr-xr-x | stvw_cfg.c | 15 | ||||
-rwxr-xr-x | stvw_cfg.h | 4 |
12 files changed, 171 insertions, 50 deletions
diff --git a/httpclient.c b/httpclient.c index a3fb192..722a659 100644 --- a/httpclient.c +++ b/httpclient.c @@ -364,7 +364,6 @@ string cHttpYtPushClient::getMsgBody(int) { //------------------------------ cHttpCfgPushClient::cHttpCfgPushClient(int f, int id, int port, SmartTvServer* fac, string peer) : cHttpClientBase(f, id, port, fac, peer) { - createRequestMessage(""); } @@ -403,5 +402,5 @@ cHttpMesgPushClient::~cHttpMesgPushClient() { } string cHttpMesgPushClient::getMsgBody(int) { - return "{\"type\":\"MESG\",payload:" + mMesg +"}";; + return "{\"type\":\"MESG\",payload:\"" + mMesg +"\"}";; } diff --git a/httpresource.c b/httpresource.c index fcb7f82..76f7956 100755 --- a/httpresource.c +++ b/httpresource.c @@ -352,6 +352,14 @@ int cHttpResource::processRequest() { } //thlo for testing purpose +/* + if (mPath.compare("/modifyTimer") == 0) { + mResponse = new cResponseMemBlk(this); + ((cResponseMemBlk*)mResponse)->receiveModTimerReq(); + return OKAY; + } +*/ + //thlo for testing purpose if (mPath.compare("/addTimer") == 0) { mResponse = new cResponseMemBlk(this); ((cResponseMemBlk*)mResponse)->receiveAddTimerReq(); @@ -359,6 +367,14 @@ int cHttpResource::processRequest() { } #endif + + if (mPath.compare("/deleteFile") == 0) { + mResponse = new cResponseMemBlk(this); + ((cResponseMemBlk*)mResponse)->receiveDelFileReq(); + return OKAY; + } + + if (mPath.compare("/serverName.xml") == 0) { mResponse = new cResponseMemBlk(this); ((cResponseMemBlk*)mResponse)->sendServerNameXml( ); @@ -453,13 +469,22 @@ int cHttpResource::processRequest() { } } - if (mPath.find("/web/") == 0) { + if (mPath.find("/web/", 0, 5) == 0) { mPath = mFactory->getConfigDir() + mPath; *(mLog->log())<< DEBUGPREFIX << " Found web request. serving " << mPath << endl; ok_to_serve = true; } + if (mPath.find("/live/", 0, 6) == 0) { + *(mLog->log())<< DEBUGPREFIX + << " Found live request. serving " << mPath << endl; + //mResponse = new cResponseLive(this, mPath.substr(6)); + //((cResponseVdrDir*)mResponse)->sendMediaSegment( &statbuf); + return OKAY; + + } + if (mPath.compare(0, strlen(VideoDirectory), VideoDirectory) == 0) { *(mLog->log())<< DEBUGPREFIX << " Found video dir request. serving " << mPath << endl; @@ -624,12 +649,17 @@ int cHttpResource::handlePost() { } if (mPath.compare("/deleteYtUrl") == 0) { - mResponse = new cResponseMemBlk(this); ((cResponseMemBlk*)mResponse)->receiveDelYtUrl(); return OKAY; } + if (mPath.compare("/deleteFile") == 0) { + mResponse = new cResponseMemBlk(this); + ((cResponseMemBlk*)mResponse)->receiveDelFileReq(); + return OKAY; + } + if (mPath.compare("/deleteRecording.xml") == 0) { mResponse = new cResponseMemBlk(this); ((cResponseMemBlk*)mResponse)->receiveDelRecReq(); diff --git a/responsebase.c b/responsebase.c index 633b922..5297700 100644 --- a/responsebase.c +++ b/responsebase.c @@ -125,6 +125,33 @@ void cResponseBase::sendHeaders(int status, const char *title, const char *extra strcpy(mBlkData, hdr.c_str()); } +const char *cResponseBase::getMimeType(const char *name) { + char *ext = strrchr((char*)name, '.'); + if (!ext) + return "application/octet-stream"; + + if (strcmp(ext, ".html") == 0 || strcmp(ext, ".htm") == 0) return "text/html"; + if (strcmp(ext, ".jpg") == 0 || strcmp(ext, ".jpeg") == 0) return "image/jpeg"; + if (strcmp(ext, ".gif") == 0) return "image/gif"; + if (strcmp(ext, ".png") == 0) return "image/png"; + if (strcmp(ext, ".xml") == 0) return "application/xml"; + if (strcmp(ext, ".css") == 0) return "text/css"; + if (strcmp(ext, ".js") == 0) return "text/javascript"; + if (strcmp(ext, ".au") == 0) return "audio/basic"; + if (strcmp(ext, ".wav") == 0) return "audio/wav"; + if (strcmp(ext, ".avi") == 0) return "video/x-msvideo"; + if (strcmp(ext, ".mp4") == 0) return "video/mp4"; + if (strcmp(ext, ".3gp") == 0) return "video/3gp"; + if (strcmp(ext, ".vdr") == 0) return "video/mpeg"; + if (strcmp(ext, ".ts") == 0) return "video/mpeg"; + if (strcmp(ext, ".mpeg") == 0 || strcmp(ext, ".mpg") == 0) return "video/mpeg"; + if (strcmp(ext, ".mp3") == 0) return "audio/mpeg"; + if (strcmp(ext, ".mpd") == 0) return "application/dash+xml"; + if (strcmp(ext, ".m3u8") == 0) return "application/x-mpegURL"; + + return "application/octet-stream"; +} + int cResponseBase::fillDataBlk() { diff --git a/responsebase.h b/responsebase.h index 18ea439..5600866 100644 --- a/responsebase.h +++ b/responsebase.h @@ -50,6 +50,8 @@ class cResponseBase { void sendHeaders(int status, const char *title, const char *extra, const char *mime, long long int length, time_t date); + const char *getMimeType(const char *name) ; + Log* mLog; cHttpResource* mRequest; uint64_t mRemLength; diff --git a/responsefile.c b/responsefile.c index 4fed5e4..90fa97b 100644 --- a/responsefile.c +++ b/responsefile.c @@ -47,33 +47,6 @@ cResponseFile::~cResponseFile() { } -const char *cResponseFile::getMimeType(const char *name) { - char *ext = strrchr((char*)name, '.'); - if (!ext) - return NULL; - // if (ext.compare(".html") || ext.compare(".htm")) return "text/html"; - if (strcmp(ext, ".html") == 0 || strcmp(ext, ".htm") == 0) return "text/html"; - if (strcmp(ext, ".jpg") == 0 || strcmp(ext, ".jpeg") == 0) return "image/jpeg"; - if (strcmp(ext, ".gif") == 0) return "image/gif"; - if (strcmp(ext, ".png") == 0) return "image/png"; - if (strcmp(ext, ".xml") == 0) return "application/xml"; - if (strcmp(ext, ".css") == 0) return "text/css"; - if (strcmp(ext, ".js") == 0) return "text/javascript"; - if (strcmp(ext, ".au") == 0) return "audio/basic"; - if (strcmp(ext, ".wav") == 0) return "audio/wav"; - if (strcmp(ext, ".avi") == 0) return "video/x-msvideo"; - if (strcmp(ext, ".mp4") == 0) return "video/mp4"; - if (strcmp(ext, ".vdr") == 0) return "video/mpeg"; - if (strcmp(ext, ".ts") == 0) return "video/mpeg"; - if (strcmp(ext, ".mpeg") == 0 || strcmp(ext, ".mpg") == 0) return "video/mpeg"; - if (strcmp(ext, ".mp3") == 0) return "audio/mpeg"; - if (strcmp(ext, ".mpd") == 0) return "application/dash+xml"; - if (strcmp(ext, ".m3u8") == 0) return "application/x-mpegURL"; - - return NULL; -} - - int cResponseFile::sendFile() { // Send the First Datachunk, incl all headers diff --git a/responsefile.h b/responsefile.h index b4a1b36..2133b83 100644 --- a/responsefile.h +++ b/responsefile.h @@ -40,8 +40,6 @@ class cResponseFile : public cResponseBase { int sendFile(); private: - const char *getMimeType(const char *name) ; - int openFile(const char *name); FILE *mFile; diff --git a/responsememblk.c b/responsememblk.c index f77f950..d53fdc1 100755 --- a/responsememblk.c +++ b/responsememblk.c @@ -26,6 +26,7 @@ #include "smarttvfactory.h" #include <sstream> +#include <cstdio> #ifndef STANDALONE #include <vdr/recording.h> @@ -44,7 +45,6 @@ //#include <stdio.h> //#include <sys/stat.h> #include <dirent.h> - #endif @@ -1060,6 +1060,58 @@ void cResponseMemBlk::receiveDelTimerReq() { } } +void cResponseMemBlk::receiveDelFileReq() { + if (isHeadRequest()) + return ; + + *(mLog->log()) << DEBUGPREFIX << " cResponseMemBlk::receiveDelFileReq" << endl; + + vector<sQueryAVP> avps; + mRequest->parseQueryLine(&avps); + + //guid=<guid> + string guid = ""; + + if (mRequest->getQueryAttributeValue(&avps, "guid", guid) == OKAY) { + guid = cUrlEncode::doUrlSaveDecode(guid); + *(mLog->log()) << DEBUGPREFIX + << " guid= " << guid << endl; + } + + if (guid.size() == 0) { + sendError(404, "Not Found", NULL, "003 File not found."); + return; + } + if (guid.compare(0, (mRequest->mFactory->getConfig()->getMediaFolder()).size(), mRequest->mFactory->getConfig()->getMediaFolder()) != 0) { + sendError(404, "Not Found", NULL, "003 File not found."); + return; + } + + *(mLog->log()) << DEBUGPREFIX + << " Trying to delete file " << guid << endl; + + if( remove( guid.c_str() ) != 0 ) { + *(mLog->log()) << DEBUGPREFIX + << " Deletion Failed. Errno= " << errno << endl; + switch (errno) { + case 2: // No such file or directory + sendError(400, "Bad Request", NULL, "018 No such file or directory. "); + break; + case 13: // Permission denied + sendError(400, "Bad Request", NULL, "019 Permission Denied. "); + break; + case 21: // Is a directory + sendError(400, "Bad Request", NULL, "020 Is a directory. "); + break; + default: // default + sendError(400, "Bad Request", NULL, "021 Deletion failed. "); + break; + } + } + else + sendHeaders(200, "OK", NULL, NULL, 0, -1); +} + void cResponseMemBlk::sendTimersXml() { char f[200]; @@ -1079,7 +1131,9 @@ void cResponseMemBlk::sendTimersXml() { // s_timers.push_back(t); s_timers.Append(t); } +#if VDRVERSNUM > 10721 s_timers.Sort(timerCompare); +#endif #else cSortedTimers s_timers; #endif @@ -1172,7 +1226,6 @@ void cResponseMemBlk::sendRecCmds() { void cResponseMemBlk::receiveExecRecCmdReq() { vector<sQueryAVP> avps; - mRequest->parseQueryLine(&avps); string guid; string cmd_str; uint cmdid; @@ -1180,6 +1233,14 @@ void cResponseMemBlk::receiveExecRecCmdReq() { if (isHeadRequest()) return; + if (! mRequest->mFactory->getConfig()->getRecCmds()) { + sendError(400, "Bad Request", NULL, "017 execreccmd disabled."); + return; + + } + mRequest->parseQueryLine(&avps); + + if (mRequest->getQueryAttributeValue(&avps, "guid", guid) != OKAY){ sendError(400, "Bad Request", NULL, "002 No guid in query line"); return; @@ -1268,7 +1329,7 @@ uint64_t cResponseMemBlk::getVdrFileSize() { // common for all create xml file modules -int cResponseMemBlk::writeXmlItem(string name, string link, string programme, string desc, string guid, int no, time_t start, int dur, double fps, int is_pes, int is_new) { +int cResponseMemBlk::writeXmlItem(string name, string link, string programme, string desc, string guid, int no, time_t start, int dur, double fps, int is_pes, int is_new, string mime) { string hdr = ""; char f[400]; @@ -1276,7 +1337,8 @@ int cResponseMemBlk::writeXmlItem(string name, string link, string programme, st // snprintf(f, sizeof(f), "%s - %s", ); hdr += "<title>" + name +"</title>\n"; hdr += "<link>" +link + "</link>\n"; - hdr += "<enclosure url=\"" +link + "\" type=\"video/mpeg\" />\n"; + // hdr += "<enclosure url=\"" +link + "\" type=\"video/mpeg\" />\n"; + hdr += "<enclosure url=\"" +link + "\" type=\""+mime+"\" />\n"; hdr += "<guid>" + guid + "</guid>\n"; @@ -1471,7 +1533,7 @@ int cResponseMemBlk::parseFiles(vector<sFileEntry> *entries, string prefix, stri << " Vdr Folder Found: " << pathbuf << " start= " << start << endl; #endif - entries->push_back(sFileEntry(dir_name, pathbuf, start)); + entries->push_back(sFileEntry(dir_name, pathbuf, start, "video/mpeg")); } else { // regular file @@ -1479,8 +1541,9 @@ int cResponseMemBlk::parseFiles(vector<sFileEntry> *entries, string prefix, stri } } else { - if ((de->d_name)[0] != '.' ) - entries->push_back(sFileEntry(prefix+de->d_name, pathbuf, 1)); + if ((de->d_name)[0] != '.' ) { + entries->push_back(sFileEntry(prefix+de->d_name, pathbuf, 1, getMimeType(de->d_name))); + } } } closedir(dir); @@ -1530,8 +1593,9 @@ int cResponseMemBlk::sendMediaXml (struct stat *statbuf) { snprintf(pathbuf, sizeof(pathbuf), "http://%s:%d%s", own_ip.c_str(), mRequest->mServerPort, cUrlEncode::doUrlSaveEncode(entries[i].sPath).c_str()); - if (writeXmlItem(cUrlEncode::doXmlSaveEncode(entries[i].sName), pathbuf, "NA", "NA", "-", - -1, entries[i].sStart, -1, -1, -1, -1) == ERROR) + if (writeXmlItem(cUrlEncode::doXmlSaveEncode(entries[i].sName), pathbuf, "NA", "NA", + cUrlEncode::doUrlSaveEncode(entries[i].sPath).c_str(), + -1, entries[i].sStart, -1, -1, -1, -1, entries[i].sMime) == ERROR) return ERROR; } @@ -1865,7 +1929,7 @@ int cResponseMemBlk::sendChannelsXml (struct stat *statbuf) { string c_name = (group_sep != "") ? (group_sep + "~" + cUrlEncode::doXmlSaveEncode(channel->Name())) : cUrlEncode::doXmlSaveEncode(channel->Name()); // if (writeXmlItem(channel->Name(), link, title, desc, *(channel->GetChannelID()).ToString(), start_time, duration) == ERROR) - if (writeXmlItem(c_name, link, title, desc, *(channel->GetChannelID()).ToString(), channel->Number(), start_time, duration, -1, -1, -1) == ERROR) + if (writeXmlItem(c_name, link, title, desc, *(channel->GetChannelID()).ToString(), channel->Number(), start_time, duration, -1, -1, -1, "video/mpeg") == ERROR) return ERROR; } @@ -2237,7 +2301,7 @@ int cResponseMemBlk::sendRecordingsXml(struct stat *statbuf) { cUrlEncode::doUrlSaveEncode(recording->FileName()).c_str(), -1, recording->Start(), rec_dur, recording->FramesPerSecond(), - (recording->IsPesRecording() ? 0: 1), (recording->IsNew() ? 0: 1)) == ERROR) { + (recording->IsPesRecording() ? 0: 1), (recording->IsNew() ? 0: 1), "video/mpeg") == ERROR) { *mResponseMessage = ""; sendError(500, "Internal Server Error", NULL, "005 writeXMLItem returned an error"); return OKAY; diff --git a/responsememblk.h b/responsememblk.h index f0b1174..5f564c2 100755 --- a/responsememblk.h +++ b/responsememblk.h @@ -38,8 +38,9 @@ struct sFileEntry { string sName; string sPath; int sStart; + string sMime; -sFileEntry(string n, string l, int s) : sName(n), sPath(l), sStart(s) { +sFileEntry(string n, string l, int s, string m) : sName(n), sPath(l), sStart(s), sMime(m) { }; }; @@ -75,6 +76,8 @@ class cResponseMemBlk : public cResponseBase { void receiveAddTimerReq(); void receiveDelTimerReq(); + void receiveDelFileReq(); + void receiveClientInfo(); int receiveResume(); @@ -91,7 +94,7 @@ class cResponseMemBlk : public cResponseBase { int parseResume(cResumeEntry &entry, string &id); int parseFiles(vector<sFileEntry> *entries, string prefix, string dir_base, string dir_name, struct stat *statbuf); int sendDir(struct stat *statbuf); - int writeXmlItem(string title, string link, string programme, string desc, string guid, int no, time_t start, int dur, double fps, int is_pes, int is_new); + int writeXmlItem(string title, string link, string programme, string desc, string guid, int no, time_t start, int dur, double fps, int is_pes, int is_new, string mime); uint64_t getVdrFileSize(); private: diff --git a/smarttvfactory.c b/smarttvfactory.c index b281a61..94242e6 100755 --- a/smarttvfactory.c +++ b/smarttvfactory.c @@ -713,9 +713,14 @@ void SmartTvServer::initServer(string dir) { #ifndef STANDALONE mConfig = new cSmartTvConfig(dir); + serverPort = mConfig->getServerPort(); mLog.init(mConfig->getLogFile()); - esyslog("SmartTvWeb: Logfile created"); - + + if (mConfig->getLogFile() != "") { + string msg = "SmartTvWeb: Logfile created File= " + mConfig->getLogFile(); + // esyslog("SmartTvWeb: Logfile created"); + esyslog(msg.c_str()); + } *(mLog.log()) << "LogFile= " << mConfig->getLogFile() << endl; initRecCmds(); diff --git a/smarttvweb.conf b/smarttvweb.conf index 07920dc..10adaa7 100644 --- a/smarttvweb.conf +++ b/smarttvweb.conf @@ -26,3 +26,8 @@ GroupSeparators Ignore # Bind the web server to a specific IP address. Otherwise, the Web Server is listening on ALL interfaces. #ServerAddress 127.0.0.1 +# Bind the web server to a specific port. Default is Port 8000. +#ServerPort 8000 + +# Allow execution of reccmd.conf defined programs through the widget. Ensure that only authorized hosts get access to the plugin (e.g. firewall protected). +#RecCmds enable @@ -33,7 +33,7 @@ cSmartTvConfig::cSmartTvConfig(string d): mConfigDir(d), mLog(NULL), mCfgFile(NULL), mLogFile(), mMediaFolder(), mSegmentDuration(), mHasMinBufferTime(), mHasBitrateCorrection(), - mLiveChannels(), mGroupSep(IGNORE), mServerAddress("") { + mLiveChannels(), mGroupSep(IGNORE), mServerAddress(""), mServerPort(8000), mRecCmds(false) { #ifndef STANDALONE mLogFile= ""; @@ -106,6 +106,7 @@ void cSmartTvConfig::readConfig() { // cout << " Found mMediaFolder= " << mMediaFolder << endl; continue; } + if (strcmp(attr, "SegmentDuration") == 0) { mSegmentDuration = atoi(value); // cout << " Found mSegmentDuration= " << mSegmentDuration << endl; @@ -140,7 +141,17 @@ void cSmartTvConfig::readConfig() { if (strcmp(attr, "ServerAddress") == 0) { mServerAddress = value; - // cout << " Found mLiveChannels= " <<mLiveChannels << endl; + continue; + } + + if (strcmp(attr, "ServerPort") == 0) { + mServerPort = atoi(value); + continue; + } + + if (strcmp(attr, "RecCmds") == 0) { + if (strcmp(value, "enable") == 0) + mRecCmds = true; continue; } @@ -54,6 +54,8 @@ class cSmartTvConfig { eGroupSep mGroupSep; string mServerAddress; + int mServerPort; + bool mRecCmds; public: cSmartTvConfig(string dir); @@ -70,6 +72,8 @@ class cSmartTvConfig { int getLiveChannels() {return mLiveChannels; }; eGroupSep getGroupSep() { return mGroupSep; }; string getServerAddress() { return mServerAddress; }; + int getServerPort() { return mServerPort; }; + bool getRecCmds() { return mRecCmds; }; }; #endif |