diff options
-rw-r--r-- | include/media/mediaManager.h | 2 | ||||
-rw-r--r-- | include/plugin.h | 12 | ||||
-rw-r--r-- | include/server.h | 6 | ||||
-rw-r--r-- | media/mediaManager.cpp | 241 | ||||
-rw-r--r-- | media/pluginManager.cpp | 18 | ||||
-rw-r--r-- | plugins/profiler/vdrDVBProfiler/Makefile | 4 | ||||
-rw-r--r-- | plugins/provider/vdrProvider/vdrProvider.cpp | 15 | ||||
-rw-r--r-- | server/server.cpp | 1 |
8 files changed, 195 insertions, 104 deletions
diff --git a/include/media/mediaManager.h b/include/media/mediaManager.h index b0cac0a..265e024 100644 --- a/include/media/mediaManager.h +++ b/include/media/mediaManager.h @@ -8,7 +8,6 @@ #ifndef MEDIAMANAGER_H_ #define MEDIAMANAGER_H_ -#include "../../include/pluginManager.h" #include "../../include/plugin.h" #include "../../include/tools.h" #include <vdr/thread.h> @@ -21,6 +20,7 @@ namespace upnp { class cResourceStreamer; +class cPluginManager; class cMediaManager : public cThread { friend void cUPnPResourceProvider::OnContainerUpdate(const string& uri, long updateID, const string& target = string()); diff --git a/include/plugin.h b/include/plugin.h index 4016db0..5607a7e 100644 --- a/include/plugin.h +++ b/include/plugin.h @@ -164,6 +164,18 @@ public: uint32_t GetNrAudioChannels() const { return nrAudioChannels; } uint32_t GetColorDepth() const { return colorDepth; } + /** + * Compares a resource with another resource + * + * This returns true if and only if the resource uri of the + * compared two resources are equal. + * + * It is illegal to have two distinct resources with the + * same resource uri even if one of them is a converted or + * transcoded version of the other one. + */ + bool operator==(const Resource& rhs); + private: string resourceUri; string protocolInfo; diff --git a/include/server.h b/include/server.h index 48e85a9..7d9e479 100644 --- a/include/server.h +++ b/include/server.h @@ -9,16 +9,18 @@ #define SERVER_H_ #include <string> +#include <map> +#include <list> #include <upnp/upnp.h> #include "../include/config.h" -#include "../include/service.h" -#include "../include/webserver.h" using namespace std; namespace upnp { class cMediaManager; +class cWebserver; +class cUPnPService; class cMediaServer { public: diff --git a/media/mediaManager.cpp b/media/mediaManager.cpp index 16e7497..3df218a 100644 --- a/media/mediaManager.cpp +++ b/media/mediaManager.cpp @@ -6,6 +6,7 @@ */ #include "../include/media/mediaManager.h" +#include "../include/pluginManager.h" #include "../include/server.h" #include "../include/parser.h" #include <upnp/upnp.h> @@ -14,6 +15,7 @@ #include <upnp/ixml.h> #include <memory> #include <tntdb/statement.h> +#include <tntdb/transaction.h> namespace upnp { @@ -108,6 +110,13 @@ cMediaManager::cMediaManager() } cMediaManager::~cMediaManager(){ + try { + tntdb::Statement stmt = connection.prepare("VACUUM"); + stmt.execute(); + } catch (const std::exception& e) { + esyslog("UPnP\tFailed to vacuum database '%s': '%s'", databaseFile.c_str(), e.what()); + } + delete pluginManager; } @@ -218,16 +227,21 @@ StringList cMediaManager::GetSupportedProtocolInfos() const { ss << "SELECT DISTINCT `" << property::resource::KEY_PROTOCOL_INFO << "` FROM " << db::Resources; - tntdb::Statement stmt = conn.prepare(ss.str()); - StringList list; - for(tntdb::Statement::const_iterator it = stmt.begin(); it != stmt.end(); ++it){ - tntdb::Row row = (*it); + try { + tntdb::Statement stmt = conn.prepare(ss.str()); + + for(tntdb::Statement::const_iterator it = stmt.begin(); it != stmt.end(); ++it){ + tntdb::Row row = (*it); - cout << row.getString(property::resource::KEY_PROTOCOL_INFO) << endl; + cout << row.getString(property::resource::KEY_PROTOCOL_INFO) << endl; - list.push_back(row.getString(property::resource::KEY_PROTOCOL_INFO)); + list.push_back(row.getString(property::resource::KEY_PROTOCOL_INFO)); + } + + } catch (const std::exception& e) { + esyslog("UPnP\tException occurred while getting protocol infos: %s", e.what()); } return list; @@ -244,114 +258,120 @@ int cMediaManager::CreateResponse(MediaRequest& request, const string& select, c << "`" << property::object::KEY_OBJECTID << "` = " << ":objectID"; - tntdb::Statement select1 = connection.prepare(select); - tntdb::Result result = connection.select(count); - tntdb::Statement select2 = connection.prepare(resources.str()); - tntdb::Statement select3 = connection.prepare(details.str()); + IXML_Document* DIDLDoc = NULL; - StringList filterList = cFilterCriteria::parse(request.filter); + try { + tntdb::Statement select1 = connection.prepare(select); + tntdb::Result result = connection.select(count); + tntdb::Statement select2 = connection.prepare(resources.str()); + tntdb::Statement select3 = connection.prepare(details.str()); - request.numberReturned = 0; - request.updateID = 0; - request.totalMatches = result.getRow(0).getInt32("totalMatches"); + StringList filterList = cFilterCriteria::parse(request.filter); - IXML_Document* DIDLDoc = NULL; - if(ixmlParseBufferEx(DIDLFragment, &DIDLDoc)==IXML_SUCCESS){ + request.numberReturned = 0; + request.updateID = 0; + request.totalMatches = result.getRow(0).getInt32("totalMatches"); - IXML_Node* root = ixmlNode_getFirstChild((IXML_Node*) DIDLDoc); + if(ixmlParseBufferEx(DIDLFragment, &DIDLDoc)==IXML_SUCCESS){ - tntdb::Row row, row2, row3; + IXML_Node* root = ixmlNode_getFirstChild((IXML_Node*) DIDLDoc); - for(tntdb::Statement::const_iterator it = select1.begin(); it != select1.end(); ++it){ + tntdb::Row row, row2, row3; - row = (*it); + for(tntdb::Statement::const_iterator it = select1.begin(); it != select1.end(); ++it){ - IXML_Element* object; - string upnpClass = row.getString(property::object::KEY_CLASS); + row = (*it); - bool isContainer; + IXML_Element* object; + string upnpClass = row.getString(property::object::KEY_CLASS); + bool isContainer; - if(upnpClass.find("object.item",0) == 0){ - object = ixmlDocument_createElement(DIDLDoc, "item"); - isContainer = false; - } else if(upnpClass.find("object.container",0) == 0) { - object = ixmlDocument_createElement(DIDLDoc, "container"); - isContainer = true; - } else { - goto error; - } - ixmlNode_appendChild(root, (IXML_Node*)object); - string objectID = row.getString(property::object::KEY_OBJECTID); + if(upnpClass.find("object.item",0) == 0){ + object = ixmlDocument_createElement(DIDLDoc, "item"); + isContainer = false; + } else if(upnpClass.find("object.container",0) == 0) { + object = ixmlDocument_createElement(DIDLDoc, "container"); + isContainer = true; + } else { + goto error; + } + ixmlNode_appendChild(root, (IXML_Node*)object); - ixml::IxmlAddProperty(DIDLDoc, object, property::object::KEY_OBJECTID, objectID); - ixml::IxmlAddProperty(DIDLDoc, object, property::object::KEY_PARENTID, row.getString(property::object::KEY_PARENTID)); - ixml::IxmlAddProperty(DIDLDoc, object, property::object::KEY_RESTRICTED, row.getString(property::object::KEY_RESTRICTED)); - ixml::IxmlAddProperty(DIDLDoc, object, property::object::KEY_TITLE, row.getString(property::object::KEY_TITLE).substr(0, MAX_METADATA_LENGTH_S)); - ixml::IxmlAddProperty(DIDLDoc, object, property::object::KEY_CLASS, row.getString(property::object::KEY_CLASS).substr(0, MAX_METADATA_LENGTH_S)); + string objectID = row.getString(property::object::KEY_OBJECTID); - if(isContainer){ - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_CHILD_COUNT, row.getString(property::object::KEY_CHILD_COUNT)); - } - else { - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_CHANNEL_NR, row.getString(property::object::KEY_CHANNEL_NR)); - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_CHANNEL_NAME, row.getString(property::object::KEY_CHANNEL_NAME)); - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_SCHEDULED_START, row.getString(property::object::KEY_SCHEDULED_START)); - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_SCHEDULED_END, row.getString(property::object::KEY_SCHEDULED_END)); - } + ixml::IxmlAddProperty(DIDLDoc, object, property::object::KEY_OBJECTID, objectID); + ixml::IxmlAddProperty(DIDLDoc, object, property::object::KEY_PARENTID, row.getString(property::object::KEY_PARENTID)); + ixml::IxmlAddProperty(DIDLDoc, object, property::object::KEY_RESTRICTED, row.getString(property::object::KEY_RESTRICTED)); + ixml::IxmlAddProperty(DIDLDoc, object, property::object::KEY_TITLE, row.getString(property::object::KEY_TITLE).substr(0, MAX_METADATA_LENGTH_S)); + ixml::IxmlAddProperty(DIDLDoc, object, property::object::KEY_CLASS, row.getString(property::object::KEY_CLASS).substr(0, MAX_METADATA_LENGTH_S)); - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_CREATOR, row.getString(property::object::KEY_CREATOR)); - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_DESCRIPTION, row.getString(property::object::KEY_DESCRIPTION)); - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_LONG_DESCRIPTION, row.getString(property::object::KEY_LONG_DESCRIPTION)); - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_DATE, row.getString(property::object::KEY_DATE)); - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_LANGUAGE, row.getString(property::object::KEY_LANGUAGE)); + if(isContainer){ + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_CHILD_COUNT, row.getString(property::object::KEY_CHILD_COUNT)); + } + else { + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_CHANNEL_NR, row.getString(property::object::KEY_CHANNEL_NR)); + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_CHANNEL_NAME, row.getString(property::object::KEY_CHANNEL_NAME)); + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_SCHEDULED_START, row.getString(property::object::KEY_SCHEDULED_START)); + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_SCHEDULED_END, row.getString(property::object::KEY_SCHEDULED_END)); + } + + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_CREATOR, row.getString(property::object::KEY_CREATOR)); + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_DESCRIPTION, row.getString(property::object::KEY_DESCRIPTION)); + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_LONG_DESCRIPTION, row.getString(property::object::KEY_LONG_DESCRIPTION)); + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_DATE, row.getString(property::object::KEY_DATE)); + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::object::KEY_LANGUAGE, row.getString(property::object::KEY_LANGUAGE)); - select2.setString("objectID", objectID); + select2.setString("objectID", objectID); - for(tntdb::Statement::const_iterator it2 = select2.begin(); it2 != select2.end(); ++it2){ - row2 = (*it2); + for(tntdb::Statement::const_iterator it2 = select2.begin(); it2 != select2.end(); ++it2){ + row2 = (*it2); - boost::shared_ptr<cUPnPResourceProvider> provider(CreateResourceProvider(row2.getString(property::resource::KEY_RESOURCE))); + boost::shared_ptr<cUPnPResourceProvider> provider(CreateResourceProvider(row2.getString(property::resource::KEY_RESOURCE))); - if(provider.get()){ - string resourceURI = provider->GetHTTPUri(row2.getString(property::resource::KEY_RESOURCE), cMediaServer::GetInstance()->GetServerIPAddress()); + if(provider.get()){ + string resourceURI = provider->GetHTTPUri(row2.getString(property::resource::KEY_RESOURCE), cMediaServer::GetInstance()->GetServerIPAddress()); - IXML_Element* resource = ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_RESOURCE, resourceURI); + IXML_Element* resource = ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_RESOURCE, resourceURI); - if(resource){ - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_PROTOCOL_INFO, row2.getString(property::resource::KEY_PROTOCOL_INFO)); - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_BITRATE, row2.getString(property::resource::KEY_BITRATE)); - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_BITS_PER_SAMPLE, row2.getString(property::resource::KEY_BITS_PER_SAMPLE)); - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_COLOR_DEPTH, row2.getString(property::resource::KEY_COLOR_DEPTH)); - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_DURATION, row2.getString(property::resource::KEY_DURATION)); - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_NR_AUDIO_CHANNELS, row2.getString(property::resource::KEY_NR_AUDIO_CHANNELS)); - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_RESOLUTION, row2.getString(property::resource::KEY_RESOLUTION)); - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_SAMPLE_FREQUENCY, row2.getString(property::resource::KEY_SAMPLE_FREQUENCY)); - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_SIZE, tools::ToString(row2.getInt64(property::resource::KEY_SIZE))); + if(resource){ + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_PROTOCOL_INFO, row2.getString(property::resource::KEY_PROTOCOL_INFO)); + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_BITRATE, row2.getString(property::resource::KEY_BITRATE)); + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_BITS_PER_SAMPLE, row2.getString(property::resource::KEY_BITS_PER_SAMPLE)); + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_COLOR_DEPTH, row2.getString(property::resource::KEY_COLOR_DEPTH)); + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_DURATION, row2.getString(property::resource::KEY_DURATION)); + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_NR_AUDIO_CHANNELS, row2.getString(property::resource::KEY_NR_AUDIO_CHANNELS)); + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_RESOLUTION, row2.getString(property::resource::KEY_RESOLUTION)); + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_SAMPLE_FREQUENCY, row2.getString(property::resource::KEY_SAMPLE_FREQUENCY)); + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, property::resource::KEY_SIZE, tools::ToString(row2.getInt64(property::resource::KEY_SIZE))); + } } - } - } + } - select3.setString("objectID", objectID); + select3.setString("objectID", objectID); - for(tntdb::Statement::const_iterator it3 = select3.begin(); it3 != select2.end(); ++it3){ - row3 = (*it3); + for(tntdb::Statement::const_iterator it3 = select3.begin(); it3 != select2.end(); ++it3){ + row3 = (*it3); - ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, row3.getString("property"), row3.getString("value")); - } + ixml::IxmlAddFilteredProperty(filterList, DIDLDoc, object, row3.getString("property"), row3.getString("value")); + } - ++request.numberReturned; - } + ++request.numberReturned; + } - request.result = ixmlDocumenttoString(DIDLDoc); + request.result = ixmlDocumenttoString(DIDLDoc); - cout << request.result << endl; + cout << request.result << endl; - ixmlDocument_free(DIDLDoc); - return UPNP_E_SUCCESS; + ixmlDocument_free(DIDLDoc); + return UPNP_E_SUCCESS; + } + } catch (const std::exception& e) { + esyslog("UPnP\tException occurred while creating response for object '%s': %s", + request.objectID.c_str(), e.what()); } error: @@ -572,6 +592,10 @@ bool cMediaManager::Initialise(){ bool cMediaManager::CheckIntegrity(){ + tntdb::Statement enableForeignKeys = connection.prepare("PRAGMA foreign_keys = ON"); + + enableForeignKeys.execute(); + tntdb::Statement checkTable = connection.prepare( "SELECT name FROM sqlite_master WHERE type='table' AND name=:table;" ); @@ -680,7 +704,7 @@ void cMediaManager::Action(){ uri = scanTargets.front(); boost::shared_ptr<cUPnPResourceProvider> provider(CreateResourceProvider(uri)); if(!ScanURI(uri, provider.get())){ - isyslog("UPnP\tAn error occured while scanning '%s'!", uri.c_str()); + //isyslog("UPnP\tAn error occured while scanning '%s'!", uri.c_str()); } scanTargets.pop_front(); } @@ -706,7 +730,6 @@ bool cMediaManager::ScanURI(const string& uri, cUPnPResourceProvider* provider){ } } - isyslog("UPnP\tCannot find a profiler for schema '%s'", schema.c_str()); return false; } else { @@ -735,7 +758,16 @@ bool cMediaManager::ScanURI(const string& uri, cUPnPResourceProvider* provider){ << " != '" << tools::GenerateUUIDFromURL(uristrm.str()) << "'"; } - cout << ss.str() << endl; + try { + tntdb::Statement objects = connection.prepare(ss.str()); + + objects.execute(); + } catch (const std::exception& e) { + esyslog("UPnP\tException occurred while removing old object in '%s' from database '%s': %s", + tools::GenerateUUIDFromURL(uri).c_str(), databaseFile.c_str(), e.what()); + + return false; + } for(StringList::iterator it = entries.begin(); it != entries.end(); ++it){ uristrm.str(string()); @@ -750,6 +782,8 @@ bool cMediaManager::ScanURI(const string& uri, cUPnPResourceProvider* provider){ bool cMediaManager::RefreshObject(cMetadata& metadata){ stringstream ss; + string objectID = metadata.GetPropertyByKey(property::object::KEY_OBJECTID).GetString(); + try { connection.beginTransaction(); @@ -779,8 +813,6 @@ bool cMediaManager::RefreshObject(cMetadata& metadata){ const cMediaServer::Description desc = cMediaServer::GetInstance()->GetServerDescription(); - string objectID = metadata.GetPropertyByKey(property::object::KEY_OBJECTID).GetString(); - object.setString("objectID", objectID) .setString("parentID", metadata.GetPropertyByKey(property::object::KEY_PARENTID).GetString()) .setString("title", metadata.GetPropertyByKey(property::object::KEY_TITLE).GetString()) @@ -808,7 +840,7 @@ bool cMediaManager::RefreshObject(cMetadata& metadata){ object.setNull("language"); (!metadata.GetPropertyByKey(property::object::KEY_CHANNEL_NR).IsEmpty()) ? - object.setInteger("channelNr", metadata.GetPropertyByKey(property::object::KEY_CHANNEL_NR).GetString()) : + object.setInt("channelNr", metadata.GetPropertyByKey(property::object::KEY_CHANNEL_NR).GetInteger()) : object.setNull("channelNr"); (!metadata.GetPropertyByKey(property::object::KEY_CHANNEL_NAME).IsEmpty()) ? @@ -852,7 +884,7 @@ bool cMediaManager::RefreshObject(cMetadata& metadata){ << "`" << property::resource::KEY_COLOR_DEPTH << "`" << ") VALUES ( " << ":objectID, :resource, :protocolInfo, :size," - << ":duration, :resolution, :bitrate, :sampleFreq, :bpSample" + << ":duration, :resolution, :bitrate, :sampleFreq, :bpSample," << ":nrChannels, :colorDepth" << ")"; @@ -862,7 +894,7 @@ bool cMediaManager::RefreshObject(cMetadata& metadata){ for(cMetadata::ResourceList::iterator it = resources.begin(); it != resources.end(); ++it){ resourcestmt2.setString("objectID", objectID) .setString("resource", (*it).GetResourceUri()) - .setString("protocolInfo", (*it).GetProtocolInfo()) + .setString("protocolInfo", (*it).GetProtocolInfo()); ((*it).GetSize()) ? resourcestmt2.setInt("size",(*it).GetSize()) : @@ -905,7 +937,7 @@ bool cMediaManager::RefreshObject(cMetadata& metadata){ << "`" << property::object::KEY_OBJECTID << "`" << " = :objectID"; - tntdb::Statement detailstmt = connection.prepare(resourcestr.str()); + tntdb::Statement detailstmt = connection.prepare(detailstr.str()); detailstmt.setString("objectID", objectID) .execute(); @@ -920,17 +952,36 @@ bool cMediaManager::RefreshObject(cMetadata& metadata){ << ":objectID, :property, :value" << ")"; - tntdb::Statement detailstmt2 = connection.prepare(resourcestr.str()); + tntdb::Statement detailstmt2 = connection.prepare(detailstr.str()); cMetadata::PropertyRange properties = metadata.GetAllProperties(); for(cMetadata::PropertyMap::iterator it = properties.first; it != properties.second; ++it){ - // TODO + if((*it).first.compare(property::object::KEY_OBJECTID) == 0 || + (*it).first.compare(property::object::KEY_PARENTID) == 0 || + (*it).first.compare(property::object::KEY_TITLE) == 0 || + (*it).first.compare(property::object::KEY_CLASS) == 0 || + (*it).first.compare(property::object::KEY_RESTRICTED) == 0 || + (*it).first.compare(property::object::KEY_CREATOR) == 0 || + (*it).first.compare(property::object::KEY_DESCRIPTION) == 0 || + (*it).first.compare(property::object::KEY_LONG_DESCRIPTION) == 0 || + (*it).first.compare(property::object::KEY_DATE) == 0 || + (*it).first.compare(property::object::KEY_LANGUAGE) == 0 || + (*it).first.compare(property::object::KEY_CHANNEL_NR) == 0 || + (*it).first.compare(property::object::KEY_CHANNEL_NAME) == 0 || + (*it).first.compare(property::object::KEY_SCHEDULED_START) == 0 || + (*it).first.compare(property::object::KEY_SCHEDULED_END) == 0) continue; + + detailstmt2.setString("objectID", objectID) + .setString("property", (*it).second.GetKey()) + .setString("value", (*it).second.GetString()) + .execute(); } connection.commitTransaction(); } catch (const std::exception& e) { - esyslog("UPnP\tException occurred while initializing database '%s': %s", databaseFile.c_str(), e.what()); + esyslog("UPnP\tException occurred while storing object '%s' to database '%s': %s", + objectID.c_str(), databaseFile.c_str(), e.what()); connection.rollbackTransaction(); diff --git a/media/pluginManager.cpp b/media/pluginManager.cpp index 59dccfa..baacbc2 100644 --- a/media/pluginManager.cpp +++ b/media/pluginManager.cpp @@ -6,8 +6,8 @@ */ #include "../include/server.h" -#include "../include/media/mediaManager.h" #include "../include/pluginManager.h" +#include "../include/media/mediaManager.h" #include "../include/tools/string.h" #include "../include/tools/uuid.h" #include <string> @@ -120,6 +120,18 @@ cMetadata::Property& cMetadata::GetPropertyByKey(const string& property) { return (it != properties.end()) ? (*it).second : cMetadata::Property::Empty; } +cMetadata::ResourceList& cMetadata::GetResources(){ + return resources; +} + +void cMetadata::AddResource(const Resource& resource){ + resources.push_back(resource); +} + +void cMetadata::RemoveResource(const Resource& resource){ + resources.remove(resource); +} + string cMetadata::ToString() { stringstream ss; @@ -218,6 +230,10 @@ bool cMetadata::Resource::SetColorDepth(uint32_t colorDepth){ return true; } +bool cMetadata::Resource::operator ==(const Resource& rhs){ + return (GetResourceUri().compare(rhs.GetResourceUri()) == 0); +} + class ClassValidator : public PropertyValidator { public: ClassValidator() : PropertyValidator(property::object::KEY_CLASS) {} diff --git a/plugins/profiler/vdrDVBProfiler/Makefile b/plugins/profiler/vdrDVBProfiler/Makefile index e779d3d..7ff813f 100644 --- a/plugins/profiler/vdrDVBProfiler/Makefile +++ b/plugins/profiler/vdrDVBProfiler/Makefile @@ -20,7 +20,7 @@ CXX ?= g++ CXXFLAGS ?= -g -O3 -Wall -Werror=overloaded-virtual -Wno-parentheses -fPIC UPNPDIR ?= ../../.. -VDRLIBDIR = $(UPNPDIR)/../../lib +VDRLIBDIR ?= $(UPNPDIR)/../../lib APIVERSION = $(shell sed -ne '/define UPNPPLUGIN_VERSION/s/^.*"\(.*\)".*$$/\1/p' $(UPNPDIR)/include/plugin.h) @@ -48,7 +48,7 @@ $(DEPFILE): Makefile -include $(DEPFILE) -libupnp-$(PROFILE)-provider.so: $(OBJS) +libupnp-$(PROFILE)-profiler.so: $(OBJS) $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@ @cp --remove-destination $@ $@.$(APIVERSION) diff --git a/plugins/provider/vdrProvider/vdrProvider.cpp b/plugins/provider/vdrProvider/vdrProvider.cpp index fa7a32b..b98568f 100644 --- a/plugins/provider/vdrProvider/vdrProvider.cpp +++ b/plugins/provider/vdrProvider/vdrProvider.cpp @@ -15,6 +15,8 @@ #include <tools.h> #include <vdr/thread.h> #include <iostream> +#include <pwd.h> +#include <unistd.h> using namespace std; @@ -93,6 +95,16 @@ public: metadata.SetProperty(cMetadata::Property(property::object::KEY_TITLE, string("VDR Live-TV"))); metadata.SetProperty(cMetadata::Property("dlna:containerType", string("Tuner_1_0"))); + 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)); + } + + metadata.SetProperty(cMetadata::Property(property::object::KEY_DESCRIPTION, string("Watch Live-TV"))); + return true; } @@ -116,8 +128,6 @@ public: virtual void Action(){ - dsyslog("VdrProvider\tStarting vdrProvider thread"); - const cSchedules* Schedules; long now = 0; bool modified = false; @@ -151,7 +161,6 @@ public: sleep(2); } - dsyslog("VdrProvider\tStopping vdrProvider thread"); } }; diff --git a/server/server.cpp b/server/server.cpp index 95e7f16..b44056f 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -10,6 +10,7 @@ #include <sstream> #include "../include/server.h" #include "../include/service.h" +#include "../include/webserver.h" #include "../include/tools.h" #include "../include/media/mediaManager.h" #include "../upnp.h" |