diff --git a/livesupport/modules/core/etc/playlist.xml b/livesupport/modules/core/etc/playlist.xml index 99774dbd7..7f27c6ded 100644 --- a/livesupport/modules/core/etc/playlist.xml +++ b/livesupport/modules/core/etc/playlist.xml @@ -12,6 +12,7 @@ + @@ -24,12 +25,14 @@ playlength="00:00:34.000" > diff --git a/livesupport/modules/core/etc/playlistElement.xml b/livesupport/modules/core/etc/playlistElement.xml index 2dd075900..b968f39d3 100644 --- a/livesupport/modules/core/etc/playlistElement.xml +++ b/livesupport/modules/core/etc/playlistElement.xml @@ -12,6 +12,7 @@ + @@ -28,6 +29,7 @@ relativeOffset="0" > diff --git a/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h b/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h index ccafbde19..6860bf1b2 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.14 $ + Version : $Revision: 1.15 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h,v $ ------------------------------------------------------------------------------*/ @@ -124,7 +124,7 @@ using namespace boost::posix_time; * * * @author $Author: fgerlits $ - * @version $Revision: 1.14 $ + * @version $Revision: 1.15 $ */ class AudioClip : public Configurable, public Playable @@ -188,7 +188,7 @@ class AudioClip : public Configurable, /** * Create an audio clip by specifying all details, except - * for the title. + * for the title. The title is set to the empty string. * This is used for testing purposes. * * @param id the id of the audio clip. @@ -367,24 +367,37 @@ class AudioClip : public Configurable, /** - * 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 XML representation of this audio clip + * (in UTF-8 encoding). + * This consists of minimal information (ID, playlength, title) + * only, without any metadata. * - * (NOTE: This returns a non-constant pointer to a member of the - * AudioClip object, so handle with care, and do not ever, ever - * modify the Document object returned. It cannot be made const - * because xmlpp::Document::write_to_file() and - * xmlpp::Document::write_to_string() are only defined on - * non-constant instances.) - * - * @return an xmlpp::Document containing the metadata. + * @return a string representation of the audio clip in XML */ - Ptr::Ref - toXml() throw () - { - return xmlAudioClip; - } + virtual Ptr::Ref + getXmlString(void) throw (); + + + /** + * Return an XML representation of the metadata of the audio clip + * (in UTF-8 encoding). This has the (pseudo-) DTD + *

+         *  <!ELEMENT audioClip (metadata) >
+         *  <!ATTLIST audioClip  id           NMTOKEN     #REQUIRED  >
+         *
+         *  <!ELEMENT metadata (dcterms:extent, dc:title, (ANY)*) >
+         *  <!ELEMENT dcterms:extent (NMTOKEN) >
+         *  <!ELEMENT dc:title       (CDATA) >
+         *  
+ * + * If the audio clip has no metadata at all (this is possible if + * it was created by the default constructor or the constructor + * which takes a unique ID only), a null pointer is returned. + * + * @return a string representation of the metadata in XML + */ + Ptr::Ref + getMetadataString() throw (); }; diff --git a/livesupport/modules/core/include/LiveSupport/Core/FadeInfo.h b/livesupport/modules/core/include/LiveSupport/Core/FadeInfo.h index 878eed9d4..91ee45786 100644 --- a/livesupport/modules/core/include/LiveSupport/Core/FadeInfo.h +++ b/livesupport/modules/core/include/LiveSupport/Core/FadeInfo.h @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.4 $ + Version : $Revision: 1.5 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/FadeInfo.h,v $ ------------------------------------------------------------------------------*/ @@ -89,7 +89,7 @@ using namespace boost::posix_time; * * * @author $Author: fgerlits $ - * @version $Revision: 1.4 $ + * @version $Revision: 1.5 $ */ class FadeInfo : public Configurable { @@ -219,6 +219,14 @@ class FadeInfo : public Configurable { return fadeOut; } + + /** + * Return an XML representation of this FadeInfo object. + * + * @return a string representation of the audio clip in XML + */ + virtual Ptr::Ref + getXmlString(void) throw (); }; diff --git a/livesupport/modules/core/include/LiveSupport/Core/Playable.h b/livesupport/modules/core/include/LiveSupport/Core/Playable.h index ac2be3fea..fd4ada3d2 100644 --- a/livesupport/modules/core/include/LiveSupport/Core/Playable.h +++ b/livesupport/modules/core/include/LiveSupport/Core/Playable.h @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.4 $ + Version : $Revision: 1.5 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/Playable.h,v $ ------------------------------------------------------------------------------*/ @@ -69,7 +69,7 @@ using namespace boost::posix_time; * It contains the methods which are common to these classes. * * @author $Author: fgerlits $ - * @version $Revision: 1.4 $ + * @version $Revision: 1.5 $ */ class Playable { @@ -176,6 +176,14 @@ class Playable const std::string &ns = "") throw () = 0; + /** + * Return an XML representation of this audio clip or playlist. + * This consists of minimal information only, without any metadata. + * + * @return a string representation of the audio clip in XML + */ + virtual Ptr::Ref + getXmlString(void) throw () = 0; }; diff --git a/livesupport/modules/core/include/LiveSupport/Core/Playlist.h b/livesupport/modules/core/include/LiveSupport/Core/Playlist.h index 20a9109e9..0a2c58ce9 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.22 $ + Version : $Revision: 1.23 $ 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.22 $ + * @version $Revision: 1.23 $ */ class Playlist : public Configurable, public Playable @@ -191,6 +191,18 @@ class Playlist : public Configurable, this->isLockedForEditing = false; } + /** + * Create a playlist by specifying its ID only. + */ + Playlist(Ptr::Ref id) throw () + { + this->id = id; + + elementList.reset(new PlaylistElementListType); + this->isLockedForPlaying = false; + this->isLockedForEditing = false; + } + /** * Create a playlist by specifying all details, except the title. * This is used for testing purposes. @@ -209,6 +221,7 @@ class Playlist : public Configurable, this->title.reset(new Glib::ustring("")); this->playlength = playlength; this->uri = uri; + elementList.reset(new PlaylistElementListType); this->isLockedForPlaying = false; this->isLockedForEditing = false; @@ -233,6 +246,7 @@ class Playlist : public Configurable, this->title = title; this->playlength = playlength; this->uri = uri; + elementList.reset(new PlaylistElementListType); this->isLockedForPlaying = false; this->isLockedForEditing = false; @@ -586,7 +600,17 @@ class Playlist : public Configurable, throw (); - + /** + * Return an XML representation of this audio clip. + * This consists of minimal information (ID and playlength for + * playlists; ID, playlength and title + * for the audio clips, plus fade in / fade out info) + * only, without any metadata. + * + * @return a string representation of the audio clip in XML + */ + virtual Ptr::Ref + getXmlString(void) throw (); }; diff --git a/livesupport/modules/core/include/LiveSupport/Core/PlaylistElement.h b/livesupport/modules/core/include/LiveSupport/Core/PlaylistElement.h index 8b44521df..e72999bf3 100644 --- a/livesupport/modules/core/include/LiveSupport/Core/PlaylistElement.h +++ b/livesupport/modules/core/include/LiveSupport/Core/PlaylistElement.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/PlaylistElement.h,v $ ------------------------------------------------------------------------------*/ @@ -104,7 +104,7 @@ class Playlist; * * * @author $Author: fgerlits $ - * @version $Revision: 1.9 $ + * @version $Revision: 1.10 $ */ class PlaylistElement : public Configurable { @@ -369,6 +369,14 @@ class PlaylistElement : public Configurable return fadeInfo; } + /** + * Return an XML representation of this playlist element. + * This consists of minimal information only, without any metadata. + * + * @return a string representation of the audio clip in XML + */ + virtual Ptr::Ref + getXmlString(void) throw (); }; diff --git a/livesupport/modules/core/src/AudioClip.cxx b/livesupport/modules/core/src/AudioClip.cxx index 7a2731aad..e1435099d 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.12 $ + Version : $Revision: 1.13 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/AudioClip.cxx,v $ ------------------------------------------------------------------------------*/ @@ -66,6 +66,11 @@ static const std::string uriAttrName = "uri"; */ static const std::string playlengthAttrName = "playlength"; +/** + * The name of the attribute to get the title of the audio clip. + */ +static const std::string titleAttrName = "title"; + /** * The name of the metadata child element. */ @@ -76,31 +81,31 @@ static const std::string metadataElementName = "metadata"; */ static const std::string extentElementPrefix = "dcterms"; -/** - * The URI identifier for the "dcterms" prefix - */ -static const std::string extentElementUri = "http://purl.org/dc/terms/"; - /** * The name of the extent (length) metadata element. */ static const std::string extentElementName = "extent"; +/** + * The URI identifier for the "dcterms" prefix + */ +static const std::string extentElementUri = "http://purl.org/dc/terms/"; + /** * The prefix of the title metadata element. */ static const std::string titleElementPrefix = "dc"; -/** - * The URI identifier for the "dc" prefix - */ -static const std::string titleElementUri ="http://purl.org/dc/elements/1.1/"; - /** * The name of the title metadata element. */ static const std::string titleElementName = "title"; +/** + * The URI identifier for the "dc" prefix + */ +static const std::string titleElementUri ="http://purl.org/dc/elements/1.1/"; + /** * The URI identifier for the default XML namespace */ @@ -128,6 +133,8 @@ AudioClip :: AudioClip(Ptr::Ref id, Ptr::Ref playlengthString(new const Glib::ustring( to_simple_string(*playlength) )); setMetadata(playlengthString, extentElementName, extentElementPrefix); + + setMetadata(title, titleElementName, titleElementPrefix); } /*------------------------------------------------------------------------------ @@ -197,9 +204,14 @@ AudioClip :: configure(const xmlpp::Element & element) duration_from_string(attribute->get_value()))); } + if (!title + && (attribute = element.get_attribute(titleAttrName))) { + title.reset(new const Glib::ustring(attribute->get_value())); + } + if (!uri && (attribute = element.get_attribute(uriAttrName))) { - uri.reset(new std::string(attribute->get_value())); + uri.reset(new const std::string(attribute->get_value())); } xmlpp::Node::NodeList childNodes @@ -232,17 +244,25 @@ AudioClip :: configure(const xmlpp::Element & element) } if (!playlength && prefix == extentElementPrefix - && name == extentElementName - && dataElement->has_child_text()) { - playlength.reset(new time_duration(duration_from_string( + && name == extentElementName) { + if (dataElement->has_child_text()) { + playlength.reset(new time_duration(duration_from_string( dataElement->get_child_text()->get_content() ))); + } + else { // or just leave blank? bad either way + playlength.reset(new time_duration(0,0,0,0)); + } } if (!title && prefix == titleElementPrefix - && name == titleElementName - && dataElement->has_child_text()) { - Glib::ustring value = dataElement->get_child_text() - ->get_content(); + && name == titleElementName) { + Glib::ustring value; + if (dataElement->has_child_text()) { + value = dataElement->get_child_text()->get_content(); + } + else { + value = ""; + } Ptr::Ref ptrToValue( new const Glib::ustring(value)); title = ptrToValue; @@ -271,6 +291,16 @@ AudioClip :: configure(const xmlpp::Element & element) Ptr::Ref playlengthString(new const Glib::ustring( to_simple_string(*playlength) )); setMetadata(playlengthString, extentElementName, extentElementPrefix); + + if (!title) { + std::string eMsg = "missing attribute "; + eMsg += titleAttrName; + eMsg += " or metadata element "; + eMsg += titleElementPrefix + ":" + titleElementName; + throw std::invalid_argument(eMsg); + } + + setMetadata(title, titleElementName, titleElementPrefix); } @@ -353,9 +383,9 @@ AudioClip :: setMetadata(Ptr::Ref value, extentElementPrefix); } - xmlpp::Node::NodeList nodeList = metadata->get_children(key); - xmlpp::Node::NodeList::iterator it = nodeList.begin(); - xmlpp::Element* element; + xmlpp::Node::NodeList nodeList = metadata->get_children(key); + xmlpp::Node::NodeList::iterator it = nodeList.begin(); + xmlpp::Element* element = 0; while (it != nodeList.end()) { xmlpp::Node* node = *it; @@ -379,3 +409,44 @@ AudioClip :: setMetadata(Ptr::Ref value, element->set_child_text(*value); } + +/*------------------------------------------------------------------------------ + * Return a string containing the essential fields of this object, in XML. + *----------------------------------------------------------------------------*/ +Ptr::Ref +AudioClip :: getXmlString(void) throw () +{ + Ptr::Ref xmlString(new Glib::ustring); + + xmlString->append("<"); + xmlString->append(configElementNameStr + " "); + xmlString->append(idAttrName + "=\"" + + std::string(*id) + + "\" "); + xmlString->append(playlengthAttrName + "=\"" + + to_simple_string(*playlength) + + "\" "); + xmlString->append(Glib::ustring(titleAttrName) + "=\"" + + *title + + "\"/>"); + return xmlString; +} + + +/*------------------------------------------------------------------------------ + * Return a string containing the metadata of the audio clip, in XML. + *----------------------------------------------------------------------------*/ +Ptr::Ref +AudioClip :: getMetadataString() throw () +{ + Ptr::Ref metadataString; + + if (!xmlAudioClip) { + return metadataString; + } + + metadataString.reset(new Glib::ustring(xmlAudioClip->write_to_string() )); + + return metadataString; +} + diff --git a/livesupport/modules/core/src/AudioClipTest.cxx b/livesupport/modules/core/src/AudioClipTest.cxx index b887a0482..e700b129b 100644 --- a/livesupport/modules/core/src/AudioClipTest.cxx +++ b/livesupport/modules/core/src/AudioClipTest.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/core/src/AudioClipTest.cxx,v $ ------------------------------------------------------------------------------*/ @@ -124,6 +124,14 @@ AudioClipTest :: firstTest(void) CPPUNIT_ASSERT(*alternativeTitle == "Alternative File Title ín sőmé %$#@* LÁNGŰAGÉ"); + CPPUNIT_ASSERT(*audioClip->getXmlString() == + ""); + +//std::cerr << "\nxml: '" << *audioClip->getXmlString() << "'" << std::endl; +//std::cerr << "\nmetadata: " << *audioClip->getMetadataString() << std::endl; + } catch (std::invalid_argument &e) { CPPUNIT_FAIL("semantic error in configuration file"); } catch (xmlpp::exception &e) { diff --git a/livesupport/modules/core/src/FadeInfo.cxx b/livesupport/modules/core/src/FadeInfo.cxx index 07e8cb71f..ad05940fa 100644 --- a/livesupport/modules/core/src/FadeInfo.cxx +++ b/livesupport/modules/core/src/FadeInfo.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.2 $ + Version : $Revision: 1.3 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/FadeInfo.cxx,v $ ------------------------------------------------------------------------------*/ @@ -113,3 +113,27 @@ FadeInfo :: configure(const xmlpp::Element & element) fadeOut.reset(new time_duration( duration_from_string(attribute->get_value()))); } + + +/*------------------------------------------------------------------------------ + * Return a string containing the essential fields of this object, in XML. + *----------------------------------------------------------------------------*/ +Ptr::Ref +FadeInfo :: getXmlString(void) throw () +{ + Ptr::Ref xmlString(new Glib::ustring); + + xmlString->append("<"); + xmlString->append(configElementNameStr + " "); + xmlString->append(idAttrName + "=\"" + + std::string(*id) + + "\" "); + xmlString->append(fadeInAttrName + "=\"" + + to_simple_string(*fadeIn) + + "\" "); + xmlString->append(fadeOutAttrName + "=\"" + + to_simple_string(*fadeOut) + + "\"/>"); + return xmlString; +} + diff --git a/livesupport/modules/core/src/FadeInfoTest.cxx b/livesupport/modules/core/src/FadeInfoTest.cxx index 165896cff..e454c32d2 100644 --- a/livesupport/modules/core/src/FadeInfoTest.cxx +++ b/livesupport/modules/core/src/FadeInfoTest.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.1 $ + Version : $Revision: 1.2 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/FadeInfoTest.cxx,v $ ------------------------------------------------------------------------------*/ @@ -117,6 +117,11 @@ FadeInfoTest :: firstTest(void) CPPUNIT_ASSERT(fadeOut->seconds() == 1); CPPUNIT_ASSERT(fadeOut->fractional_seconds() == 500); + CPPUNIT_ASSERT(*fadeInfo->getXmlString() == + ""); + } catch (std::invalid_argument &e) { std::string eMsg = "semantic error in configuration file:\n"; eMsg += e.what(); diff --git a/livesupport/modules/core/src/Playlist.cxx b/livesupport/modules/core/src/Playlist.cxx index c9e5e44a0..b25d205df 100644 --- a/livesupport/modules/core/src/Playlist.cxx +++ b/livesupport/modules/core/src/Playlist.cxx @@ -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/src/Playlist.cxx,v $ ------------------------------------------------------------------------------*/ @@ -398,3 +398,32 @@ Playlist :: setMetadata(Ptr::Ref value, metadata[completeKey] = value; } +/*------------------------------------------------------------------------------ + * Return a string containing the essential fields of this object, in XML. + *----------------------------------------------------------------------------*/ +Ptr::Ref +Playlist :: getXmlString(void) throw () +{ + Ptr::Ref xmlString(new Glib::ustring); + + xmlString->append("<"); + xmlString->append(configElementNameStr + " "); + xmlString->append(idAttrName + "=\"" + + std::string(*id) + + "\" "); + xmlString->append(playlengthAttrName + "=\"" + + to_simple_string(*playlength) + + "\">\n"); + + PlaylistElementListType::const_iterator it = elementList->begin(); + while (it != elementList->end()) { + xmlString->append(*it->second->getXmlString() + "\n"); + ++it; + } + + xmlString->append("append(configElementNameStr + ">"); + + return xmlString; +} + diff --git a/livesupport/modules/core/src/PlaylistElement.cxx b/livesupport/modules/core/src/PlaylistElement.cxx index 305645d14..4ddb9918a 100644 --- a/livesupport/modules/core/src/PlaylistElement.cxx +++ b/livesupport/modules/core/src/PlaylistElement.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.7 $ + Version : $Revision: 1.8 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/PlaylistElement.cxx,v $ ------------------------------------------------------------------------------*/ @@ -188,3 +188,31 @@ PlaylistElement :: configure(const xmlpp::Element & element) throw std::invalid_argument(eMsg); } } + + +/*------------------------------------------------------------------------------ + * Return a string containing the essential fields of this object, in XML. + *----------------------------------------------------------------------------*/ +Ptr::Ref +PlaylistElement :: getXmlString(void) throw () +{ + Ptr::Ref xmlString(new Glib::ustring); + + xmlString->append("<"); + xmlString->append(configElementNameStr + " "); + xmlString->append(idAttrName + "=\"" + + std::string(*id) + + "\" "); + xmlString->append(relativeOffsetAttrName + "=\"" + + to_simple_string(*relativeOffset) + + "\">\n"); + xmlString->append(*getPlayable()->getXmlString() + "\n"); + if (fadeInfo) { + xmlString->append(*fadeInfo->getXmlString() + "\n"); + } + xmlString->append("append(configElementNameStr + ">"); + + return xmlString; +} + diff --git a/livesupport/modules/core/src/PlaylistElementTest.cxx b/livesupport/modules/core/src/PlaylistElementTest.cxx index 8994b8c2b..5a4a03ee4 100644 --- a/livesupport/modules/core/src/PlaylistElementTest.cxx +++ b/livesupport/modules/core/src/PlaylistElementTest.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/core/src/PlaylistElementTest.cxx,v $ ------------------------------------------------------------------------------*/ @@ -124,7 +124,7 @@ PlaylistElementTest :: firstTest(void) CPPUNIT_ASSERT(playlistElement->getType() == PlaylistElement::PlaylistType); - + // check that we can access the playlist inside the playlist element // as a Playable instance CPPUNIT_ASSERT(playlistElement->getPlaylist() @@ -148,6 +148,14 @@ PlaylistElementTest :: firstTest(void) CPPUNIT_ASSERT(playlistElement->getType() == PlaylistElement::AudioClipType); + CPPUNIT_ASSERT(*playlistElement->getXmlString() == + "\n" + "\n" + ""); + // and the audio clip inside the playlist element CPPUNIT_ASSERT(playlistElement->getAudioClip()->getId()->getId() == 10003); diff --git a/livesupport/modules/core/src/PlaylistTest.cxx b/livesupport/modules/core/src/PlaylistTest.cxx index c9d520f74..cd9d8d692 100644 --- a/livesupport/modules/core/src/PlaylistTest.cxx +++ b/livesupport/modules/core/src/PlaylistTest.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.14 $ + Version : $Revision: 1.15 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/PlaylistTest.cxx,v $ ------------------------------------------------------------------------------*/ @@ -115,6 +115,25 @@ PlaylistTest :: firstTest(void) CPPUNIT_ASSERT(playlist->valid()); + CPPUNIT_ASSERT(*playlist->getXmlString() == +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +""); + Playlist::const_iterator it = playlist->begin(); CPPUNIT_ASSERT(it != playlist->end()); Ptr::Ref playlistElement = it->second; diff --git a/livesupport/modules/storage/etc/storageClient.xml b/livesupport/modules/storage/etc/storageClient.xml index a6d97f42d..6b3c6cdca 100644 --- a/livesupport/modules/storage/etc/storageClient.xml +++ b/livesupport/modules/storage/etc/storageClient.xml @@ -17,6 +17,7 @@ + @@ -38,10 +39,12 @@ @@ -50,6 +53,7 @@ @@ -58,12 +62,15 @@ + title="three" + uri="file:var/test3.mp3" /> diff --git a/livesupport/modules/storage/etc/testStorage.xml b/livesupport/modules/storage/etc/testStorage.xml index a671bc9d8..c6c415719 100644 --- a/livesupport/modules/storage/etc/testStorage.xml +++ b/livesupport/modules/storage/etc/testStorage.xml @@ -15,6 +15,7 @@ + @@ -26,10 +27,12 @@ @@ -38,6 +41,7 @@ @@ -46,13 +50,17 @@ + title="three" + uri="file:var/test10003.mp3" /> diff --git a/livesupport/modules/storage/src/WebStorageClient.cxx b/livesupport/modules/storage/src/WebStorageClient.cxx index 622b62a81..0dd283d9c 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.15 $ + Version : $Revision: 1.16 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/WebStorageClient.cxx,v $ ------------------------------------------------------------------------------*/ @@ -177,6 +177,101 @@ static const std::string resetStorageMethodName static const std::string resetStorageResultParamName = "gunids"; +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ storage server constants: existsPlaylist */ + +/*------------------------------------------------------------------------------ + * The name of the exists playlist method on the storage server + *----------------------------------------------------------------------------*/ +static const std::string existsPlaylistMethodName + = "locstor.existsPlaylist"; + +/*------------------------------------------------------------------------------ + * The name of the session ID parameter in the input structure + *----------------------------------------------------------------------------*/ +static const std::string existsPlaylistSessionIdParamName = "sessid"; + +/*------------------------------------------------------------------------------ + * The name of the audio clip unique ID parameter in the input structure + *----------------------------------------------------------------------------*/ +static const std::string existsPlaylistPlaylistIdParamName = "plid"; + +/*------------------------------------------------------------------------------ + * The name of the result parameter returned by the method + *----------------------------------------------------------------------------*/ +static const std::string existsPlaylistResultParamName = "exists"; + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ storage server constants: getPlaylist */ + +/*------------------------------------------------------------------------------ + * The name of the opening 'get playlist' method on the storage server + *----------------------------------------------------------------------------*/ +static const std::string getPlaylistOpenMethodName + = "locstor.accessPlaylist"; + +/*------------------------------------------------------------------------------ + * The name of the closing 'get playlist' method on the storage server + *----------------------------------------------------------------------------*/ +static const std::string getPlaylistCloseMethodName + = "locstor.releasePlaylist"; + +/*------------------------------------------------------------------------------ + * The name of the session ID parameter in the input structure + *----------------------------------------------------------------------------*/ +static const std::string getPlaylistSessionIdParamName = "sessid"; + +/*------------------------------------------------------------------------------ + * The name of the playlist unique ID parameter in the input structure + *----------------------------------------------------------------------------*/ +static const std::string getPlaylistPlaylistIdParamName = "plid"; + +/*------------------------------------------------------------------------------ + * The name of the result URL parameter returned by the method + *----------------------------------------------------------------------------*/ +static const std::string getPlaylistUrlParamName = "url"; + +/*------------------------------------------------------------------------------ + * The name of the token parameter returned (for open) or input (for close) + *----------------------------------------------------------------------------*/ +static const std::string getPlaylistTokenParamName = "token"; + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ storage server constants: editPlaylist */ + +/*------------------------------------------------------------------------------ + * The name of the 'edit playlist' method on the storage server + *----------------------------------------------------------------------------*/ +static const std::string editPlaylistMethodName + = "locstor.editPlaylist"; + +/*------------------------------------------------------------------------------ + * The name of the session ID parameter in the input structure + *----------------------------------------------------------------------------*/ +static const std::string editPlaylistSessionIdParamName = "sessid"; + +/*------------------------------------------------------------------------------ + * The name of the playlist unique ID parameter in the input structure + *----------------------------------------------------------------------------*/ +static const std::string editPlaylistPlaylistIdParamName = "plid"; + +/*------------------------------------------------------------------------------ + * The name of the result URL parameter returned by the method + *----------------------------------------------------------------------------*/ +static const std::string editPlaylistUrlParamName = "url"; + +/*------------------------------------------------------------------------------ + * The name of the token parameter returned by the method + *----------------------------------------------------------------------------*/ +static const std::string editPlaylistTokenParamName = "token"; + + + + + + + + + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ storage server constants: existsAudioClip */ /*------------------------------------------------------------------------------ @@ -204,13 +299,13 @@ static const std::string existsAudioClipResultParamName = "exists"; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ storage server constants: getAudioClip */ /*------------------------------------------------------------------------------ - * The name of the get audio clip method on the storage server + * The name of the opening 'get audio clip' method on the storage server *----------------------------------------------------------------------------*/ static const std::string getAudioClipOpenMethodName = "locstor.downloadMetadataOpen"; /*------------------------------------------------------------------------------ - * The name of the get audio clip method on the storage server + * The name of the closing 'get audio clip' method on the storage server *----------------------------------------------------------------------------*/ static const std::string getAudioClipCloseMethodName = "locstor.downloadMetadataClose"; @@ -445,7 +540,48 @@ WebStorageClient :: existsPlaylist(Ptr::Ref sessionId, Ptr::Ref id) const throw (StorageException) { - return false; + XmlRpcValue parameters; + XmlRpcValue result; + + XmlRpcClient xmlRpcClient(storageServerName.c_str(), storageServerPort, + storageServerPath.c_str(), false); + + parameters.clear(); + parameters[existsPlaylistSessionIdParamName] + = sessionId->getId(); + parameters[existsPlaylistPlaylistIdParamName] + = std::string(*id); + + result.clear(); + if (!xmlRpcClient.execute(existsPlaylistMethodName.c_str(), + parameters, result)) { + std::string eMsg = "cannot execute XML-RPC method '"; + eMsg += existsPlaylistMethodName; + eMsg += "'"; + throw XmlRpcCommunicationException(eMsg); + } + + if (xmlRpcClient.isFault()) { + std::stringstream eMsg; + eMsg << "XML-RPC method '" + << existsPlaylistMethodName + << "' returned error message:\n" + << result; + throw XmlRpcMethodFaultException(eMsg.str()); + } + + if (! result.hasMember(existsPlaylistResultParamName) + || result[existsPlaylistResultParamName].getType() + != XmlRpcValue::TypeBoolean) { + std::stringstream eMsg; + eMsg << "XML-RPC method '" + << existsPlaylistMethodName + << "' returned unexpected value:\n" + << result; + throw XmlRpcMethodResponseException(eMsg.str()); + } + + return bool(result[existsPlaylistResultParamName]); } @@ -457,7 +593,106 @@ WebStorageClient :: getPlaylist(Ptr::Ref sessionId, Ptr::Ref id) const throw (StorageException) { - Ptr::Ref playlist(new Playlist); + XmlRpcValue parameters; + XmlRpcValue result; + + XmlRpcClient xmlRpcClient(storageServerName.c_str(), storageServerPort, + storageServerPath.c_str(), false); + + parameters.clear(); + parameters[getPlaylistSessionIdParamName] + = sessionId->getId(); + parameters[getPlaylistPlaylistIdParamName] + = std::string(*id); + + result.clear(); + if (!xmlRpcClient.execute(getPlaylistOpenMethodName.c_str(), + parameters, result)) { + std::string eMsg = "cannot execute XML-RPC method '"; + eMsg += getPlaylistOpenMethodName; + eMsg += "'"; + throw XmlRpcCommunicationException(eMsg); + } + + if (xmlRpcClient.isFault()) { + std::stringstream eMsg; + eMsg << "XML-RPC method '" + << getPlaylistOpenMethodName + << "' returned error message:\n" + << result; + throw XmlRpcMethodFaultException(eMsg.str()); + } + + if (! result.hasMember(getPlaylistUrlParamName) + || result[getPlaylistUrlParamName].getType() + != XmlRpcValue::TypeString + || ! result.hasMember(getPlaylistTokenParamName) + || result[getPlaylistTokenParamName].getType() + != XmlRpcValue::TypeString) { + std::stringstream eMsg; + eMsg << "XML-RPC method '" + << getPlaylistOpenMethodName + << "' returned unexpected value:\n" + << result; + throw XmlRpcMethodResponseException(eMsg.str()); + } + + const std::string url = result[getPlaylistUrlParamName]; + const std::string token = result[getPlaylistTokenParamName]; + + Ptr::Ref playlist(new Playlist(id)); + + try { + Ptr::Ref parser(new xmlpp::DomParser()); + parser->parse_file(url); + const xmlpp::Document * document = parser->get_document(); + const xmlpp::Element * root = document->get_root_node(); + + playlist->configure(*root); + + } catch (std::invalid_argument &e) { + throw XmlRpcMethodResponseException( + "semantic error in playlist metafile"); + } catch (xmlpp::exception &e) { + throw XmlRpcMethodResponseException( + "error parsing playlist metafile"); + } + + parameters.clear(); + parameters[getPlaylistSessionIdParamName] = sessionId->getId(); + parameters[getPlaylistTokenParamName] = token; + + result.clear(); + if (!xmlRpcClient.execute(getPlaylistCloseMethodName.c_str(), + parameters, result)) { + std::string eMsg = "cannot execute XML-RPC method '"; + eMsg += getPlaylistCloseMethodName; + eMsg += "'"; + throw XmlRpcCommunicationException(eMsg); + } + + if (xmlRpcClient.isFault()) { + std::stringstream eMsg; + eMsg << "XML-RPC method '" + << getPlaylistCloseMethodName + << "' returned error message:\n" + << result; + throw XmlRpcMethodFaultException(eMsg.str()); + } + + if (! result.hasMember(getPlaylistPlaylistIdParamName) + || result[getPlaylistPlaylistIdParamName].getType() + != XmlRpcValue::TypeString + || std::string(result[getPlaylistPlaylistIdParamName]) + != std::string(*id)) { + std::stringstream eMsg; + eMsg << "XML-RPC method '" + << getPlaylistCloseMethodName + << "' returned unexpected value:\n" + << result; + throw XmlRpcMethodResponseException(eMsg.str()); + } + return playlist; } @@ -470,7 +705,74 @@ WebStorageClient :: editPlaylist(Ptr::Ref sessionId, Ptr::Ref id) const throw (StorageException) { - Ptr::Ref playlist(new Playlist); + XmlRpcValue parameters; + XmlRpcValue result; + + XmlRpcClient xmlRpcClient(storageServerName.c_str(), storageServerPort, + storageServerPath.c_str(), false); + + parameters.clear(); + parameters[editPlaylistSessionIdParamName] + = sessionId->getId(); + parameters[editPlaylistPlaylistIdParamName] + = std::string(*id); + + result.clear(); + if (!xmlRpcClient.execute(editPlaylistMethodName.c_str(), + parameters, result)) { + std::string eMsg = "cannot execute XML-RPC method '"; + eMsg += editPlaylistMethodName; + eMsg += "'"; + throw XmlRpcCommunicationException(eMsg); + } + + if (xmlRpcClient.isFault()) { + std::stringstream eMsg; + eMsg << "XML-RPC method '" + << editPlaylistMethodName + << "' returned error message:\n" + << result; + throw XmlRpcMethodFaultException(eMsg.str()); + } + + if (! result.hasMember(editPlaylistUrlParamName) + || result[editPlaylistUrlParamName].getType() + != XmlRpcValue::TypeString + || ! result.hasMember(editPlaylistTokenParamName) + || result[editPlaylistTokenParamName].getType() + != XmlRpcValue::TypeString) { + std::stringstream eMsg; + eMsg << "XML-RPC method '" + << editPlaylistMethodName + << "' returned unexpected value:\n" + << result; + throw XmlRpcMethodResponseException(eMsg.str()); + } + + const std::string url = result[getPlaylistUrlParamName]; + + Ptr::Ref playlist(new Playlist(id)); + + try { + Ptr::Ref parser(new xmlpp::DomParser()); + parser->parse_file(url); + const xmlpp::Document * document = parser->get_document(); + const xmlpp::Element * root = document->get_root_node(); + + playlist->configure(*root); + + } catch (std::invalid_argument &e) { + throw XmlRpcMethodResponseException( + "semantic error in playlist metafile"); + } catch (xmlpp::exception &e) { + throw XmlRpcMethodResponseException( + "error parsing playlist metafile"); + } + + Ptr::Ref token(new const std::string( + result[getPlaylistTokenParamName] )); + playlist->setToken(token); + return playlist; } @@ -653,8 +955,8 @@ WebStorageClient :: getAudioClip(Ptr::Ref sessionId, throw XmlRpcMethodResponseException(eMsg.str()); } - std::string url = result[getAudioClipUrlParamName]; - std::string token = result[getAudioClipTokenParamName]; + const std::string url = result[getAudioClipUrlParamName]; + const std::string token = result[getAudioClipTokenParamName]; Ptr::Ref audioClip(new AudioClip(id)); @@ -667,18 +969,18 @@ WebStorageClient :: getAudioClip(Ptr::Ref sessionId, audioClip->configure(*root); } catch (std::invalid_argument &e) { - throw XmlRpcMethodResponseException( - "semantic error in audio clip metafile"); + std::string eMsg = "semantic error in audio clip metafile:\n"; + eMsg += e.what(); + throw XmlRpcMethodResponseException(eMsg); } catch (xmlpp::exception &e) { - throw XmlRpcMethodResponseException( - "error parsing audio clip metafile"); + std::string eMsg = "error parsing audio clip metafile"; + eMsg += e.what(); + throw XmlRpcMethodResponseException(eMsg); } parameters.clear(); - parameters[getAudioClipSessionIdParamName] - = sessionId->getId(); - parameters[getAudioClipTokenParamName] - = token; + parameters[getAudioClipSessionIdParamName] = sessionId->getId(); + parameters[getAudioClipTokenParamName] = token; result.clear(); if (!xmlRpcClient.execute(getAudioClipCloseMethodName.c_str(), @@ -727,9 +1029,6 @@ WebStorageClient :: storeAudioClip(Ptr::Ref sessionId, throw InvalidArgumentException("binary audio clip file not found"); } - std::string metadata = audioClip->toXml() - ->write_to_string("utf-8"); - // temporary hack; we will expect an absolute file name from getUri() // in the final version std::string binaryFileName = audioClip->getUri()->substr(5); @@ -753,7 +1052,7 @@ WebStorageClient :: storeAudioClip(Ptr::Ref sessionId, parameters[storeAudioClipAudioClipIdParamName] = std::string(*audioClip->getId()); parameters[storeAudioClipMetadataParamName] - = metadata; + = std::string(*audioClip->getMetadataString()); parameters[storeAudioClipChecksumParamName] = md5string; diff --git a/livesupport/modules/storage/src/WebStorageClientTest.cxx b/livesupport/modules/storage/src/WebStorageClientTest.cxx index a8d8a9332..5861dccd9 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.17 $ + Version : $Revision: 1.18 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/WebStorageClientTest.cxx,v $ ------------------------------------------------------------------------------*/ @@ -168,6 +168,52 @@ WebStorageClientTest :: firstTest(void) eMsg += e.what(); CPPUNIT_FAIL(eMsg); } +} + + +/*------------------------------------------------------------------------------ + * Testing the playlist operations + *----------------------------------------------------------------------------*/ +void +WebStorageClientTest :: playlistTest(void) + throw (CPPUNIT_NS::Exception) +{ + Ptr::Ref> >::Ref uniqueIdVector; + try { + uniqueIdVector = wsc->reset(); + } + catch (StorageException &e) { + CPPUNIT_FAIL(e.what()); + } + CPPUNIT_ASSERT(uniqueIdVector->size() > 0); +// Ptr::Ref audioClipId01 = uniqueIdVector->at(0); + + Ptr::Ref sessionId; + try { + sessionId = authentication->login("root", "q"); + } + catch (AuthenticationException &e) { + CPPUNIT_FAIL(e.what()); + } + CPPUNIT_ASSERT(sessionId); + + + // test ... + Ptr::Ref playlistId77(new UniqueId(77)); + bool exists = true; + try { + exists = wsc->existsPlaylist(sessionId, playlistId77); + } + catch (StorageException &e) { + CPPUNIT_FAIL(e.what()); + } + CPPUNIT_ASSERT(!exists); + + + + + + } @@ -186,7 +232,7 @@ WebStorageClientTest :: audioClipTest(void) CPPUNIT_FAIL(e.what()); } CPPUNIT_ASSERT(uniqueIdVector->size() > 0); - Ptr::Ref id01 = uniqueIdVector->at(1); + Ptr::Ref id01 = uniqueIdVector->at(0); /* std::cout << "\nReset storage result:\n"; for (unsigned i=0; isize(); i++) { diff --git a/livesupport/modules/storage/src/WebStorageClientTest.h b/livesupport/modules/storage/src/WebStorageClientTest.h index 71918b0ca..7113e0830 100644 --- a/livesupport/modules/storage/src/WebStorageClientTest.h +++ b/livesupport/modules/storage/src/WebStorageClientTest.h @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.4 $ + Version : $Revision: 1.5 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/WebStorageClientTest.h,v $ ------------------------------------------------------------------------------*/ @@ -63,13 +63,14 @@ using namespace LiveSupport::Authentication; * Unit test for the UploadPlaylistMetohd class. * * @author $Author: fgerlits $ - * @version $Revision: 1.4 $ + * @version $Revision: 1.5 $ * @see WebStorageClient */ class WebStorageClientTest : public CPPUNIT_NS::TestFixture { CPPUNIT_TEST_SUITE(WebStorageClientTest); CPPUNIT_TEST(firstTest); + CPPUNIT_TEST(playlistTest); CPPUNIT_TEST(audioClipTest); CPPUNIT_TEST_SUITE_END(); @@ -102,6 +103,14 @@ class WebStorageClientTest : public CPPUNIT_NS::TestFixture void audioClipTest(void) throw (CPPUNIT_NS::Exception); + /** + * Testing the playlist operations. + * + * @exception CPPUNIT_NS::Exception on test failures. + */ + void + playlistTest(void) throw (CPPUNIT_NS::Exception); + public: diff --git a/livesupport/products/scheduler/etc/playlist.xml b/livesupport/products/scheduler/etc/playlist.xml index 9c38aef3d..10b060141 100644 --- a/livesupport/products/scheduler/etc/playlist.xml +++ b/livesupport/products/scheduler/etc/playlist.xml @@ -12,6 +12,7 @@ + @@ -23,10 +24,12 @@ diff --git a/livesupport/products/scheduler/etc/scheduler.xml b/livesupport/products/scheduler/etc/scheduler.xml index a3a6f1f45..4df297026 100644 --- a/livesupport/products/scheduler/etc/scheduler.xml +++ b/livesupport/products/scheduler/etc/scheduler.xml @@ -27,6 +27,7 @@ + @@ -65,16 +66,20 @@ diff --git a/livesupport/products/scheduler/etc/storageClient.xml b/livesupport/products/scheduler/etc/storageClient.xml index 612142b2f..b2f02629c 100644 --- a/livesupport/products/scheduler/etc/storageClient.xml +++ b/livesupport/products/scheduler/etc/storageClient.xml @@ -17,6 +17,7 @@ + @@ -29,16 +30,20 @@