diff --git a/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h b/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h index bdc365c04..5f2a0cc52 100644 --- a/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h +++ b/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.9 $ + Version : $Revision: 1.10 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h,v $ ------------------------------------------------------------------------------*/ @@ -95,7 +95,7 @@ using namespace boost::posix_time; * * * @author $Author: fgerlits $ - * @version $Revision: 1.9 $ + * @version $Revision: 1.10 $ */ class AudioClip : public Configurable, public Playable @@ -256,6 +256,16 @@ class AudioClip : public Configurable, { this->token = token; } + + /** + * Return an XML representation of this audio clip. This contains + * the metadata fields of the audio clip, and it's roughly the + * inverse of the configure() method. + * + * @return an xmlpp::Document containing the metadata. + */ + Ptr::Ref + getMetadata() throw (); }; diff --git a/livesupport/modules/core/include/LiveSupport/Core/Playlist.h b/livesupport/modules/core/include/LiveSupport/Core/Playlist.h index f4d8e3195..e160acdf9 100644 --- a/livesupport/modules/core/include/LiveSupport/Core/Playlist.h +++ b/livesupport/modules/core/include/LiveSupport/Core/Playlist.h @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.18 $ + Version : $Revision: 1.19 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/Playlist.h,v $ ------------------------------------------------------------------------------*/ @@ -93,7 +93,7 @@ using namespace boost::posix_time; * * * @author $Author: fgerlits $ - * @version $Revision: 1.18 $ + * @version $Revision: 1.19 $ */ class Playlist : public Configurable, public Playable @@ -138,7 +138,7 @@ class Playlist : public Configurable, * A map type for storing the playlist elements associated with * this playlist, indexed by their relative offsets. */ - typedef std::map::Ref> + typedef std::map::Ref> PlaylistElementListType; /** @@ -343,8 +343,14 @@ class Playlist : public Configurable, throw (); /** - * The iterator type for this class. + * The iterator type for this class. A Playlist::const_iterator + * is a (constant) pointer to a pair < time_duration, + * Ptr<PlaylistElement>::Ref >. + * If it is such an iterator, then it->second + * is the playlist element referenced by the iterator, and + * it->first is its relative offset in the playlist. * + * @see begin(), end(), find() */ typedef PlaylistElementListType::const_iterator const_iterator; @@ -372,7 +378,7 @@ class Playlist : public Configurable, * @param relativeOffset (a pointer to) the relative offset where * the playlist element is. * @return a constant iterator to the playlist element if it exists, - * or playlist->end() if it does not. + * or this->end() if it does not. */ const_iterator find(Ptr::Ref relativeOffset) const diff --git a/livesupport/modules/core/include/LiveSupport/Core/StorageClientInterface.h b/livesupport/modules/core/include/LiveSupport/Core/StorageClientInterface.h index 7a86e35b5..4c1ecd02a 100644 --- a/livesupport/modules/core/include/LiveSupport/Core/StorageClientInterface.h +++ b/livesupport/modules/core/include/LiveSupport/Core/StorageClientInterface.h @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.15 $ + Version : $Revision: 1.16 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/Attic/StorageClientInterface.h,v $ ------------------------------------------------------------------------------*/ @@ -62,7 +62,7 @@ namespace Core { * An interface for storage clients. * * @author $Author: fgerlits $ - * @version $Revision: 1.15 $ + * @version $Revision: 1.16 $ */ class StorageClientInterface { @@ -221,6 +221,21 @@ class StorageClientInterface throw (std::logic_error) = 0; + /** + * Store an audio clip. + * + * @param sessionId the session ID from the authentication client + * @param audioClip the audio clip to store. + * @return true if the operation was successful. + * + * @exception std::logic_error if we have not logged in yet. + */ + virtual bool + storeAudioClip(Ptr::Ref sessionId, + Ptr::Ref audioClip) + throw (std::logic_error) + = 0; + /** * Acquire the resources for the audio clip with the specified id. * diff --git a/livesupport/modules/core/src/AudioClip.cxx b/livesupport/modules/core/src/AudioClip.cxx index 98e571cab..27b1ea627 100644 --- a/livesupport/modules/core/src/AudioClip.cxx +++ b/livesupport/modules/core/src/AudioClip.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.6 $ + Version : $Revision: 1.7 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/AudioClip.cxx,v $ ------------------------------------------------------------------------------*/ @@ -110,3 +110,16 @@ AudioClip :: configure(const xmlpp::Element & element) uri.reset(new std::string(uriValue)); } } + + +/*------------------------------------------------------------------------------ + * Create an XML element from this audio clip. + *----------------------------------------------------------------------------*/ +Ptr::Ref +AudioClip :: getMetadata() + throw () +{ + Ptr::Ref metadata(new xmlpp::Document); + return metadata; +} + diff --git a/livesupport/modules/storage/etc/webStorage.xml b/livesupport/modules/storage/etc/webStorage.xml index df6e91d5c..5471c5f25 100644 --- a/livesupport/modules/storage/etc/webStorage.xml +++ b/livesupport/modules/storage/etc/webStorage.xml @@ -10,7 +10,7 @@ ]> - + diff --git a/livesupport/modules/storage/src/StorageClientFactory.cxx b/livesupport/modules/storage/src/StorageClientFactory.cxx index 747ab2034..2919d861e 100644 --- a/livesupport/modules/storage/src/StorageClientFactory.cxx +++ b/livesupport/modules/storage/src/StorageClientFactory.cxx @@ -21,8 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Author : $Author: maroy $ - Version : $Revision: 1.4 $ + Author : $Author: fgerlits $ + Version : $Revision: 1.5 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/StorageClientFactory.cxx,v $ ------------------------------------------------------------------------------*/ @@ -36,7 +36,7 @@ #include "LiveSupport/Storage/StorageClientFactory.h" #include "TestStorageClient.h" -#include "LiveSupport/Storage/WebStorageClient.h" +#include "WebStorageClient.h" using namespace LiveSupport::Core; diff --git a/livesupport/modules/storage/src/TestStorageClient.cxx b/livesupport/modules/storage/src/TestStorageClient.cxx index e349556e7..f24df5bbe 100644 --- a/livesupport/modules/storage/src/TestStorageClient.cxx +++ b/livesupport/modules/storage/src/TestStorageClient.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.20 $ + Version : $Revision: 1.21 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/TestStorageClient.cxx,v $ ------------------------------------------------------------------------------*/ @@ -486,6 +486,19 @@ TestStorageClient :: getAudioClip(Ptr::Ref sessionId, } +/*------------------------------------------------------------------------------ + * Store an audio clip. + *----------------------------------------------------------------------------*/ +bool +TestStorageClient :: storeAudioClip(Ptr::Ref sessionId, + Ptr::Ref audioClip) + throw (std::invalid_argument) +{ + audioClipMap[audioClip->getId()->getId()] = audioClip; + return true; +} + + /*------------------------------------------------------------------------------ * Acquire resources for an audio clip. *----------------------------------------------------------------------------*/ diff --git a/livesupport/modules/storage/src/TestStorageClient.h b/livesupport/modules/storage/src/TestStorageClient.h index 1a97f63f5..f5518de15 100644 --- a/livesupport/modules/storage/src/TestStorageClient.h +++ b/livesupport/modules/storage/src/TestStorageClient.h @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.17 $ + Version : $Revision: 1.18 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/TestStorageClient.h,v $ ------------------------------------------------------------------------------*/ @@ -90,7 +90,7 @@ using namespace LiveSupport::Core; * * * @author $Author: fgerlits $ - * @version $Revision: 1.17 $ + * @version $Revision: 1.18 $ */ class TestStorageClient : virtual public Configurable, @@ -314,6 +314,19 @@ class TestStorageClient : Ptr::Ref id) const throw (std::invalid_argument); + /** + * Store an audio clip. + * + * @param sessionId the session ID from the authentication client + * @param audioClip the audio clip to store. + * @return true if the operation was successful. + * @exception std::invalid_argument never in this implementation + */ + virtual bool + storeAudioClip(Ptr::Ref sessionId, + Ptr::Ref audioClip) + throw (std::invalid_argument); + /** * Acquire the resources for the audio clip with the specified id. * diff --git a/livesupport/modules/storage/src/TestStorageClientTest.cxx b/livesupport/modules/storage/src/TestStorageClientTest.cxx index 99d28b6b3..05ca8af79 100644 --- a/livesupport/modules/storage/src/TestStorageClientTest.cxx +++ b/livesupport/modules/storage/src/TestStorageClientTest.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.15 $ + Version : $Revision: 1.16 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/TestStorageClientTest.cxx,v $ ------------------------------------------------------------------------------*/ @@ -186,14 +186,14 @@ void TestStorageClientTest :: audioClipTest(void) throw (CPPUNIT_NS::Exception) { - Ptr::Ref id2(new UniqueId(10002)); + Ptr::Ref id02(new UniqueId(10002)); Ptr::Ref id77(new UniqueId(10077)); - CPPUNIT_ASSERT(tsc->existsAudioClip(dummySessionId, id2)); + CPPUNIT_ASSERT(tsc->existsAudioClip(dummySessionId, id02)); CPPUNIT_ASSERT(!tsc->existsAudioClip(dummySessionId, id77)); - Ptr::Ref audioClip = tsc->getAudioClip(dummySessionId, id2); - CPPUNIT_ASSERT(audioClip->getId()->getId() == id2->getId()); + Ptr::Ref audioClip = tsc->getAudioClip(dummySessionId, id02); + CPPUNIT_ASSERT(audioClip->getId()->getId() == id02->getId()); CPPUNIT_ASSERT(audioClip->getPlaylength()->total_seconds() == 30*60); @@ -205,8 +205,11 @@ TestStorageClientTest :: audioClipTest(void) audioClip = (*audioClipVector)[0]; CPPUNIT_ASSERT((int) (audioClip->getId()->getId()) == 10001); - tsc->deleteAudioClip(dummySessionId, id2); - CPPUNIT_ASSERT(!tsc->existsAudioClip(dummySessionId, id2)); + tsc->deleteAudioClip(dummySessionId, id02); + CPPUNIT_ASSERT(!tsc->existsAudioClip(dummySessionId, id02)); + + tsc->storeAudioClip(dummySessionId, (*audioClipVector)[1]); + CPPUNIT_ASSERT(tsc->existsAudioClip(dummySessionId, id02)); } diff --git a/livesupport/modules/storage/src/WebStorageClient.cxx b/livesupport/modules/storage/src/WebStorageClient.cxx index d4135abee..c97eed585 100644 --- a/livesupport/modules/storage/src/WebStorageClient.cxx +++ b/livesupport/modules/storage/src/WebStorageClient.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.5 $ + Version : $Revision: 1.6 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/WebStorageClient.cxx,v $ ------------------------------------------------------------------------------*/ @@ -45,7 +45,7 @@ #include #include -#include "LiveSupport/Storage/WebStorageClient.h" +#include "WebStorageClient.h" using namespace boost::posix_time; using namespace XmlRpc; @@ -197,6 +197,37 @@ static const std::string getAudioClipMethodSessionIdParamName = "sessid"; static const std::string getAudioClipMethodAudioClipIdParamName = "gunid"; +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ storage server constants: storeAudioClip */ + +/*------------------------------------------------------------------------------ + * The name of the store audio clip method on the storage server + *----------------------------------------------------------------------------*/ +static const std::string storeAudioClipMethodName + = "locstor.storeAudioClip"; + +/*------------------------------------------------------------------------------ + * The name of the session ID parameter in the input structure + *----------------------------------------------------------------------------*/ +static const std::string storeAudioClipMethodSessionIdParamName = "sessid"; + +/*------------------------------------------------------------------------------ + * The name of the audio clip unique ID parameter in the input structure + *----------------------------------------------------------------------------*/ +static const std::string storeAudioClipMethodAudioClipIdParamName = "gunid"; + +/*------------------------------------------------------------------------------ + * The name of the binary file name parameter in the input structure + *----------------------------------------------------------------------------*/ +static const std::string storeAudioClipMethodBinaryFileParamName + = "mediaFileLP"; + +/*------------------------------------------------------------------------------ + * The name of the metadata file name parameter in the input structure + *----------------------------------------------------------------------------*/ +static const std::string storeAudioClipMethodMetadataFileParamName + = "mdataFileLP"; + + /* =============================================== local function prototypes */ @@ -464,12 +495,12 @@ WebStorageClient :: getAudioClip(Ptr::Ref sessionId, throw std::logic_error(eMsg.str()); } - Ptr::Ref xmlAudioClip = decodeString(result); + std::string xmlAudioClip(result); Ptr::Ref audioClip; try { Ptr::Ref parser(new xmlpp::DomParser()); - parser->parse_memory(*xmlAudioClip); + parser->parse_memory(xmlAudioClip); const xmlpp::Document * document = parser->get_document(); const xmlpp::Element * root = document->get_root_node(); @@ -485,6 +516,81 @@ WebStorageClient :: getAudioClip(Ptr::Ref sessionId, } +/*------------------------------------------------------------------------------ + * Store an audio clip. + *----------------------------------------------------------------------------*/ +bool +WebStorageClient :: storeAudioClip(Ptr::Ref sessionId, + Ptr::Ref audioClip) + throw (std::logic_error) +{ + if (!audioClip || !audioClip->getUri()) { + throw std::logic_error("binary audio clip file not found"); + } + + Ptr::Ref metadata = audioClip->getMetadata(); + + std::stringstream metadataFileName; + metadataFileName << localTempStorage << "-audioClipMetadata-" + << audioClip->getId()->getId() + << "-" << rand() << ".xml"; + + metadata->write_to_file(metadataFileName.str(), "UTF-8"); + + // temporary hack; we will expect an absolute file name from getUri() + // in the final version + std::string binaryFileName = audioClip->getUri()->substr(5); + std::ifstream ifs(binaryFileName.c_str()); + if (!ifs) { + ifs.close(); + throw std::logic_error("could not read audio clip"); + } + ifs.close(); + std::string binaryFilePrefix("file://"); + binaryFilePrefix += get_current_dir_name(); // doesn't work if current + binaryFilePrefix += "/"; // dir = /, but OK for now + binaryFileName = binaryFilePrefix + binaryFileName; + + XmlRpcValue parameters; + XmlRpcValue result; + + XmlRpcClient xmlRpcClient(storageServerName.c_str(), storageServerPort, + storageServerPath.c_str(), false); + + parameters[storeAudioClipMethodSessionIdParamName] + = sessionId->getId(); + parameters[storeAudioClipMethodAudioClipIdParamName] + = int(audioClip->getId()->getId()); + parameters[storeAudioClipMethodBinaryFileParamName] + = binaryFileName; + parameters[storeAudioClipMethodMetadataFileParamName] + = metadataFileName.str(); + + bool clientStatus = xmlRpcClient.execute(storeAudioClipMethodName.c_str(), + parameters, result); + std::remove(metadataFileName.str().substr(7).c_str()); + + if (!clientStatus) { + std::string eMsg = "cannot execute XML-RPC method '"; + eMsg += storeAudioClipMethodName; + eMsg += "'"; + throw std::logic_error(eMsg); + } + + if (xmlRpcClient.isFault() + || result.getType() != XmlRpcValue::TypeString) { + std::stringstream eMsg; + eMsg << "XML-RPC method '" + << getAudioClipMethodName + << "' returned error message:\n" + << result; + throw std::logic_error(eMsg.str()); + } + + return true; +} + + /*------------------------------------------------------------------------------ * Acquire resources for an audio clip. *----------------------------------------------------------------------------*/ diff --git a/livesupport/modules/storage/include/LiveSupport/Storage/WebStorageClient.h b/livesupport/modules/storage/src/WebStorageClient.h similarity index 94% rename from livesupport/modules/storage/include/LiveSupport/Storage/WebStorageClient.h rename to livesupport/modules/storage/src/WebStorageClient.h index 53359c0b2..fbd483e46 100644 --- a/livesupport/modules/storage/include/LiveSupport/Storage/WebStorageClient.h +++ b/livesupport/modules/storage/src/WebStorageClient.h @@ -22,8 +22,8 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.1 $ - Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/include/LiveSupport/Storage/Attic/WebStorageClient.h,v $ + Version : $Revision: 1.7 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/WebStorageClient.h,v $ ------------------------------------------------------------------------------*/ #ifndef WebStorageClient_h @@ -99,7 +99,7 @@ using namespace LiveSupport::Core; * * * @author $Author: fgerlits $ - * @version $Revision: 1.1 $ + * @version $Revision: 1.7 $ */ class WebStorageClient : virtual public Configurable, @@ -346,6 +346,25 @@ class WebStorageClient : Ptr::Ref id) const throw (std::logic_error); + /** + * Store an audio clip. The uri field of the audio clip + * is expected to contain the valid URI of a binary audio file. + * + * In this testing version, the audio clip URI is expected in the + * form file:relative_path/file_name.mp3. Later this + * should be changed to an absolute URI. + * + * @param sessionId the session ID from the authentication client + * @param audioClip the audio clip to store. + * @return true if the operation was successful. + * + * @exception std::logic_error if we have not logged in yet. + */ + virtual bool + storeAudioClip(Ptr::Ref sessionId, + Ptr::Ref audioClip) + throw (std::logic_error); + /** * Acquire the resources for the audio clip with the specified id. * diff --git a/livesupport/modules/storage/src/WebStorageClientTest.cxx b/livesupport/modules/storage/src/WebStorageClientTest.cxx index 76b2e3343..6118c1adf 100644 --- a/livesupport/modules/storage/src/WebStorageClientTest.cxx +++ b/livesupport/modules/storage/src/WebStorageClientTest.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.5 $ + Version : $Revision: 1.6 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/WebStorageClientTest.cxx,v $ ------------------------------------------------------------------------------*/ @@ -44,7 +44,7 @@ #include #include -#include "LiveSupport/Storage/WebStorageClient.h" +#include "WebStorageClient.h" #include "LiveSupport/Core/SessionId.h" #include "WebStorageClientTest.h" @@ -70,7 +70,7 @@ static const std::string storageConfigFileName = "etc/webStorage.xml"; * The name of the configuration file for the authentication factory. */ static const std::string authenticationFactoryConfigFileName - = "etc/authenticationClient.xml"; + = "etc/webAuthenticationClient.xml"; /* =============================================== local function prototypes */ @@ -129,26 +129,26 @@ WebStorageClientTest :: tearDown(void) throw () /*------------------------------------------------------------------------------ - * Test to see if the singleton Hello object is accessible + * Test to see if we can log in to the storage server *----------------------------------------------------------------------------*/ void WebStorageClientTest :: firstTest(void) throw (CPPUNIT_NS::Exception) { - Ptr::Ref id77(new UniqueId(10077)); Ptr::Ref sessionId(new SessionId("bad ID")); // this does not currently work due to a bug in the storage server // try { -// wsc->existsAudioClip(sessionId, id77); -// CPPUNIT_FAIL("existsAudioClip allowed operation without login"); +// wsc->logout(sessionId); +// CPPUNIT_FAIL("allowed logout operation without login"); // } // catch (std::logic_error &e) { // } - CPPUNIT_ASSERT( sessionId = authentication->login("root", "q")); - CPPUNIT_ASSERT(!wsc->existsAudioClip(sessionId, id77)); - CPPUNIT_ASSERT( authentication->logout(sessionId)); + CPPUNIT_ASSERT(!(sessionId = authentication->login("noSuchUser", + "incorrectPassword"))); + CPPUNIT_ASSERT( (sessionId = authentication->login("root", "q"))); + CPPUNIT_ASSERT( authentication->logout(sessionId)); } @@ -159,28 +159,35 @@ void WebStorageClientTest :: audioClipTest(void) throw (CPPUNIT_NS::Exception) { -/* Ptr::Ref id01(new UniqueId(10001)); Ptr::Ref id77(new UniqueId(10077)); Ptr::Ref sessionId; CPPUNIT_ASSERT( sessionId = authentication->login("root", "q")); -//cerr << "###\n" << sessionId << "\n" << sessionId->getId() << endl; - CPPUNIT_ASSERT( wsc->existsAudioClip(sessionId, id01)); - -//std::cerr << "\naudio clip: <<<\n" << audioClip->getId()->getId() << ">>>\n"; + CPPUNIT_ASSERT(!wsc->existsAudioClip(sessionId, id77)); +/* + Ptr::Ref playlength(new time_duration(0,0,11,0)); + Ptr::Ref uri(new std::string("file:var/test10001.mp3")); + Ptr::Ref audioClip(new AudioClip(id01, playlength, uri)); + try { + wsc->storeAudioClip(sessionId, audioClip); + } + catch (std::logic_error &e) { + CPPUNIT_FAIL(e.what()); + } + + CPPUNIT_ASSERT( wsc->existsAudioClip(sessionId, id01)); + + Ptr::Ref newAudioClip + = wsc->getAudioClip(sessionId, id01); + CPPUNIT_ASSERT(newAudioClip->getId()->getId() == id01->getId()); + CPPUNIT_ASSERT(newAudioClip->getPlaylength()->total_seconds() + == audioClip->getPlaylength()->total_seconds()); +*/ CPPUNIT_ASSERT( authentication->logout(sessionId)); - - CPPUNIT_ASSERT(wsc->existsAudioClip(id2)); - CPPUNIT_ASSERT(!wsc->existsAudioClip(id77)); - - Ptr::Ref audioClip = wsc->getAudioClip(id2); - CPPUNIT_ASSERT(audioClip->getId()->getId() == id2->getId()); - CPPUNIT_ASSERT(audioClip->getPlaylength()->total_seconds() - == 30*60); - +/* Ptr::Ref> >::Ref audioClipVector = wsc->getAllAudioClips(); CPPUNIT_ASSERT(audioClipVector->size() == 2);