summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/tools.cpp12
-rw-r--r--include/media/mediaManager.h1
-rw-r--r--include/server.h2
-rw-r--r--include/tools/string.h1
-rw-r--r--media/mediaManager.cpp21
-rw-r--r--plugins/provider/fileProvider/fileProvider.cpp87
-rw-r--r--server/server.cpp6
-rw-r--r--upnp.cpp3
8 files changed, 111 insertions, 22 deletions
diff --git a/common/tools.cpp b/common/tools.cpp
index 6f02d2a..1e40ccc 100644
--- a/common/tools.cpp
+++ b/common/tools.cpp
@@ -74,6 +74,18 @@ StringVector GetNetworkInterfaces(bool skipLoop){
return interfaces;
}
+string Trim(const std::string& str, const std::string& whitespace)
+{
+ const unsigned long int strBegin = str.find_first_not_of(whitespace);
+ if (strBegin == std::string::npos)
+ return ""; // no content
+
+ const unsigned long int strEnd = str.find_last_not_of(whitespace);
+ const unsigned long int strRange = strEnd - strBegin + 1;
+
+ return str.substr(strBegin, strRange);
+}
+
string ToString(long number){
stringstream ss;
ss << number;
diff --git a/include/media/mediaManager.h b/include/media/mediaManager.h
index 40aa49f..9857d50 100644
--- a/include/media/mediaManager.h
+++ b/include/media/mediaManager.h
@@ -60,6 +60,7 @@ public:
void SetDatabaseDir(const string& file);
bool Initialise();
+ void Housekeeping();
uint32_t GetSystemUpdateID() const;
IdList GetContainerUpdateIDs(bool unevented = false);
diff --git a/include/server.h b/include/server.h
index ebdee03..be76e41 100644
--- a/include/server.h
+++ b/include/server.h
@@ -75,6 +75,8 @@ public:
static void RegisterService(cUPnPService* service);
+ void Housekeeping();
+
private:
cMediaServer();
diff --git a/include/tools/string.h b/include/tools/string.h
index 0ff5434..8d54706 100644
--- a/include/tools/string.h
+++ b/include/tools/string.h
@@ -21,6 +21,7 @@ string ToString(long number);
string StringListToCSV(StringList list);
string IdListToCSV(IdList list);
void StringExplode(string str, string separator, StringVector& results);
+string Trim(const std::string& str, const std::string& whitespace = " \t");
}
diff --git a/media/mediaManager.cpp b/media/mediaManager.cpp
index 670a158..5618817 100644
--- a/media/mediaManager.cpp
+++ b/media/mediaManager.cpp
@@ -112,8 +112,7 @@ cMediaManager::cMediaManager()
cMediaManager::~cMediaManager(){
try {
- tntdb::Statement stmt = connection.prepare("VACUUM");
- stmt.execute();
+ connection.execute("VACUUM");
} catch (const std::exception& e) {
esyslog("UPnP\tFailed to vacuum database '%s': '%s'", databaseFile.c_str(), e.what());
}
@@ -466,6 +465,14 @@ cMediaManager::BrowseFlag cMediaManager::ToBrowseFlag(const std::string& browseF
return NumBrowseFlags;
}
+void cMediaManager::Housekeeping(){
+ try {
+ connection.execute("VACUUM");
+ } catch (const std::exception& e) {
+ esyslog("UPnP\tFailed to vacuum database '%s': '%s'", databaseFile.c_str(), e.what());
+ }
+}
+
bool cMediaManager::Initialise(){
try {
@@ -614,9 +621,12 @@ bool cMediaManager::Initialise(){
bool cMediaManager::CheckIntegrity(){
- tntdb::Statement enableForeignKeys = connection.prepare("PRAGMA foreign_keys = ON");
-
- enableForeignKeys.execute();
+ connection.execute("PRAGMA foreign_keys = ON");
+ connection.execute("PRAGMA page_size = 4096");
+ connection.execute("PRAGMA cache_size = 16384");
+ connection.execute("PRAGMA temp_store = MEMORY");
+ connection.execute("PRAGMA synchronous = OFF");
+ connection.execute("PRAGMA locking_mode = EXCLUSIVE");
tntdb::Statement checkTable = connection.prepare(
"SELECT name FROM sqlite_master WHERE type='table' AND name=:table;"
@@ -747,7 +757,6 @@ bool cMediaManager::ScanURI(const string& uri, cUPnPResourceProvider* provider){
}
}
- isyslog("UPnP\tUnsupported resource: '%s' skipped.", uri.c_str());
return false;
} else {
diff --git a/plugins/provider/fileProvider/fileProvider.cpp b/plugins/provider/fileProvider/fileProvider.cpp
index 15abc10..cbc84c2 100644
--- a/plugins/provider/fileProvider/fileProvider.cpp
+++ b/plugins/provider/fileProvider/fileProvider.cpp
@@ -7,6 +7,11 @@
#include <plugin.h>
#include <fstream>
+#include <sstream>
+#include <tools/string.h>
+#include <vdr/plugin.h>
+#include <pwd.h>
+#include <unistd.h>
using namespace std;
@@ -18,31 +23,44 @@ private:
StringMap directoryMap;
FILE* fileFD;
+ bool IsRootContainer(const string& uri){
+ if(uri.find(GetRootContainer(), 0) != 0){
+ isyslog("RecProvider\tUri does not contain the root.");
+ return false;
+ } else {
+ return true;
+ }
+ }
+
bool Load(const string& filename)
{
- bool result = false;
if (access(filename.c_str(), F_OK) == 0) {
isyslog("loading %s", filename.c_str());
ifstream file;
file.open(filename.c_str(), ifstream::in);
+ if(!file.is_open())
+ return false;
string line; int pos;
while(getline(file, line)){
if(line.length() > 0 && line[0] != '#'){
if((pos = line.find_first_of(':')) != string::npos){
- directoryMap[line.substr(0,pos)] = line.substr(pos+1);
+ directoryMap[tools::Trim(line.substr(0,pos))] = tools::Trim(line.substr(pos+1));
}
}
}
+ return true;
}
- return result;
+ return false;
}
string GetFile(const string& uri){
- string mountPoint = uri.substr(6, uri.find_first_of('/',6) - 7);
+ string mountPoint = uri.substr(7, uri.find_first_of('/',7) - 7);
string file;
if(!mountPoint.empty() && !directoryMap[mountPoint].empty()){
- file = directoryMap[mountPoint] + uri.substr(uri.find_first_of('/',6));
+ file = directoryMap[mountPoint];
+ if(uri.find_first_of('/', 7) != string::npos)
+ file += uri.substr(uri.find_first_of('/',7));
}
return file;
@@ -60,6 +78,14 @@ private:
public:
+ FileProvider()
+ : fileFD(NULL)
+ {
+ stringstream file;
+ file << cPlugin::ConfigDirectory(PLUGIN_NAME_I18N) << "/directories.conf";
+ Load(file.str());
+ }
+
virtual string ProvidesSchema() { return "file"; }
virtual string GetRootContainer() {
@@ -68,7 +94,8 @@ public:
virtual bool IsContainer(const string& uri) {
struct stat fileStat;
- if(GetFileStat(uri, fileStat) && S_ISDIR(fileStat.st_mode)) return true;
+ if(GetRootContainer().compare(uri) == 0 || (GetFileStat(uri, fileStat) && S_ISDIR(fileStat.st_mode)))
+ return true;
return false;
}
@@ -95,22 +122,52 @@ public:
DIR* dirHandle;
struct dirent* dirEntry;
- if((dirHandle = opendir(GetFile(uri).c_str())) == NULL){
- return list;
- }
+ if(GetRootContainer().compare(uri) == 0){
+ for( StringMap::iterator it = directoryMap.begin(); it != directoryMap.end(); ++it ) {
+ list.push_back( it->first + "/" );
+ }
+ } else {
+ if((dirHandle = opendir(GetFile(uri).c_str())) == NULL){
+ return list;
+ }
- string filename;
- while ((dirEntry = readdir(dirHandle)) != NULL) {
- filename = dirEntry->d_name;
- if(filename.compare(".") || filename.compare("..")){
- list.push_back(filename);
+ string filename;
+ while ((dirEntry = readdir(dirHandle)) != NULL) {
+ filename = dirEntry->d_name;
+ if( filename.compare(".") != 0 && filename.compare("..") != 0 ) {
+ if(dirEntry->d_type == DT_DIR) {
+ filename += "/";
+ }
+ list.push_back(filename);
+ }
}
+ closedir(dirHandle);
}
- closedir(dirHandle);
return list;
}
+ virtual bool GetMetadata(const string& uri, cMetadata& metadata){
+ if(!IsRootContainer(uri)) return false;
+
+ if(!cUPnPResourceProvider::GetMetadata(uri, metadata)) return false;
+
+ if(GetRootContainer().compare(uri) == 0){
+ metadata.SetProperty(cMetadata::Property(property::object::KEY_TITLE, string("File system")));
+ metadata.SetProperty(cMetadata::Property(property::object::KEY_DESCRIPTION, string("Access files on the file system")));
+ }
+
+ struct passwd *pw;
+ if((pw = getpwuid(getuid())) == NULL){
+ metadata.SetProperty(cMetadata::Property(property::object::KEY_CREATOR, string("Klaus Schmidinger")));
+ } else {
+ string name(pw->pw_gecos); name = name.substr(0,name.find(",,,",0));
+ metadata.SetProperty(cMetadata::Property(property::object::KEY_CREATOR, name));
+ }
+
+ return true;
+ }
+
virtual bool Seekable() const {
return true;
}
diff --git a/server/server.cpp b/server/server.cpp
index 1dfe605..b397a94 100644
--- a/server/server.cpp
+++ b/server/server.cpp
@@ -159,6 +159,12 @@ bool cMediaServer::Stop(){
return true;
}
+void cMediaServer::Housekeeping(){
+ if(mMediaManager){
+ mMediaManager->Housekeeping();
+ }
+}
+
bool cMediaServer::Initialize(){
string address;
uint16_t port = 0;
diff --git a/upnp.cpp b/upnp.cpp
index b344f8c..9784969 100644
--- a/upnp.cpp
+++ b/upnp.cpp
@@ -91,7 +91,8 @@ cString cPluginUpnp::Active(void)
void cPluginUpnp::Housekeeping(void)
{
- // Perform any cleanup or other regular tasks.
+ if(mMediaServer)
+ mMediaServer->Housekeeping();
}
void cPluginUpnp::MainThreadHook(void)