From 4716b9c968e989a01c3440f85364e9ee66a178a3 Mon Sep 17 00:00:00 2001 From: fgerlits Date: Mon, 13 Jun 2005 15:40:53 +0000 Subject: [PATCH] moved AudioClip::readTag from TagConversionTable to MetadataTypeContainer --- livesupport/doc/gui/metadataFields.html | 70 +++---- livesupport/modules/core/etc/audioClip.xml | 2 +- livesupport/modules/core/etc/metadataType.xml | 2 +- .../core/etc/metadataTypeContainer.xml | 138 +++++++++++++- .../core/include/LiveSupport/Core/AudioClip.h | 30 ++- livesupport/modules/core/src/AudioClip.cxx | 146 ++++++++------- .../modules/core/src/AudioClipTest.cxx | 172 +++++++++-------- livesupport/modules/core/src/AudioClipTest.h | 16 +- .../core/src/MetadataTypeContainerTest.cxx | 173 ++++++++---------- .../core/src/MetadataTypeContainerTest.h | 15 +- livesupport/modules/core/var/hu.txt | 5 +- livesupport/modules/core/var/jp.txt | 5 +- livesupport/modules/core/var/root.txt | 40 +++- .../gLiveSupport/etc/gLiveSupport.xml | 67 ++++--- .../etc/gLiveSupport.xml.template | 87 ++++----- livesupport/products/gLiveSupport/var/es.txt | 1 + livesupport/products/gLiveSupport/var/hu.txt | 12 +- .../products/gLiveSupport/var/root.txt | 1 + .../products/gLiveSupport/var/sr_CS.txt | 1 + .../gLiveSupport/var/sr_CS_CYRILLIC.txt | 1 + .../products/scheduler/etc/Makefile.in | 8 +- 21 files changed, 580 insertions(+), 412 deletions(-) diff --git a/livesupport/doc/gui/metadataFields.html b/livesupport/doc/gui/metadataFields.html index 70455f6f1..4ec7a56e3 100644 --- a/livesupport/doc/gui/metadataFields.html +++ b/livesupport/doc/gui/metadataFields.html @@ -753,7 +753,7 @@
- Title + TIT2, Title Title dc:title Text @@ -762,7 +762,7 @@ see main - Artist + TPE1, Artist Creator dc:creator Text @@ -771,7 +771,7 @@ see main - Album + TALB, Album Album dc:source Text @@ -780,7 +780,7 @@
- Year + TYER, Year Year ls:year (by TH instead of dcterms:coverage:temporal:year) Menu @@ -789,7 +789,7 @@
- Genre + TCON, Genre Genre dc:type Menu @@ -798,7 +798,7 @@ see main - Comment + COMM, Comment Description dc:description Longtext @@ -816,7 +816,7 @@ see main - BPM + TBPM BPM ls:bpm Number @@ -825,7 +825,7 @@
- Rating + POPM, Rating Rating ls:rating Number @@ -834,7 +834,7 @@
- Duration + ????, Duration Length dcterms:extent (by TH instead of dcterms:format:extent) Time @@ -861,7 +861,7 @@
- Encoded by + TENC, Encoded by Encoded by ls:encoded_by (by TH instead of Creator.Role.Encoder) Text @@ -870,7 +870,7 @@ count as creator - Track # + TRCK, Track # Track number ls:track_num (by TH instead of Source.Album.TrackNumber) Menu @@ -879,7 +879,7 @@ count as source.album - Disc # + TPOS, Disc # Disc number ls:disc_num (by TH instead of Source.Album.DiscNumber) Menu @@ -888,7 +888,7 @@ count as source.album - Mood + TMOO, Mood Mood ls:mood (by TH instead of Description.Mood) Menu @@ -897,7 +897,7 @@ count as description - Label + TPUB, Label Label dc:publisher Text @@ -906,7 +906,7 @@
- Composer + TCOM, Composer Composer ls:composer (by TH instead of Creator.Role.Composer) Text @@ -915,7 +915,7 @@ count as creator - Bitrate + ????, Bitrate Bitrate ls:bitrate (by TH instead of Format.Medium.Bitrate) Number @@ -924,7 +924,7 @@
- Channels + ????, Channels Channels ls:channels (by TH instead of Format.Medium.Channels) Menu @@ -933,7 +933,7 @@
- Samplerate + ????, Samplerate Sample rate ls:samplerate (by TH instead of Format.Medium.Samplerate) Menu @@ -942,7 +942,7 @@
- Encoder + TSSE, Encoder Encoder software used ls:encoder (by TH instead of Format.Medium.Encoder) Text @@ -951,7 +951,7 @@
- CRC + ????, CRC Checksum ls:crc (by TH instead of Format.CRC) Number @@ -960,7 +960,7 @@
- Lyrics + ????, Lyrics Lyrics ls:lyrics (by TH instead of Description.Lyrics) Longtext @@ -969,7 +969,7 @@ count as description - Orchestra or band + TPE2, Orchestra or band Orchestra or band ls:orchestra (by TH instead of Creator.Role.Orchestra) Text @@ -978,7 +978,7 @@ count as creator - Conductor + TPE3, Conductor Conductor ls:conductor (by TH instead of Creator.Role.Conductor) Text @@ -987,7 +987,7 @@ count as creator - Lyricist + TEXT, Lyricist Lyricist ls:lyricist (by TH instead of Creator.Role.Lyricist) Text @@ -996,7 +996,7 @@ count as creator - Original lyricist + TOLY, Original lyricist Original lyricist ls:originallyricist (by TH instead of Creator.Role.OriginalLyricist) Text @@ -1005,7 +1005,7 @@ count as creator - Radio station name + TRSN, Radio station name Radio station name ls:radiostationname (by TH instead of Creator.Role.RadioStationName) Text @@ -1014,7 +1014,7 @@ count as creator - Audio file information webpage + WOAF, Audio file information webpage Audio file information web page ls:audiofileinfourl (by TH instead of Description.AudioFileInfoURL) URL @@ -1023,7 +1023,7 @@ count as description - Artist webpage + WOAR, Artist webpage Artist web page ls:artisturl (by TH instead of Description.ArtistURL) URL @@ -1032,7 +1032,7 @@ count as description - Audio source webpage + WOAS, Audio source webpage Audio source web page ls:audiosourceurl (by TH instead of Description.AudioSourceURL) URL @@ -1041,7 +1041,7 @@ count as description - Radio station webpage + WORS, Radio station webpage Radio station web page ls:radiostationurl (by TH instead of Description.RadioStationURL) URL @@ -1050,7 +1050,7 @@ count as description - Buy CD webpage + WPAY, Buy CD webpage Buy CD web page ls:buycdurl (by TH instead of Description.BuyCDURL) URL @@ -1059,7 +1059,7 @@ count as description - ISRC # + TSRC, ISRC # ISRC number ls:isrcnumber (by TH instead of Identifier.ISRCNumber) Number @@ -1068,7 +1068,7 @@
- Catalog # + ????, Catalog # Catalog number ls:catalognumber (by TH instead of Identifier.CatalogNumber) Number @@ -1077,7 +1077,7 @@
- Original Artist + TOPE, Original Artist Original artist ls:originalartist (by TH instead of Creator.Role.OriginalArtist) Text @@ -1086,7 +1086,7 @@
- Copyright + TCOP, Copyright Copyright dc:rights or ls:license ? (by TH instead of dc:rights:license) Text diff --git a/livesupport/modules/core/etc/audioClip.xml b/livesupport/modules/core/etc/audioClip.xml index 493430e07..84fccd1d8 100644 --- a/livesupport/modules/core/etc/audioClip.xml +++ b/livesupport/modules/core/etc/audioClip.xml @@ -20,6 +20,6 @@ 00:18:30.000000 online Spatial Coverage - Temporal Covarage + Temporal Coverage diff --git a/livesupport/modules/core/etc/metadataType.xml b/livesupport/modules/core/etc/metadataType.xml index aaa3ced8b..7f23c8604 100644 --- a/livesupport/modules/core/etc/metadataType.xml +++ b/livesupport/modules/core/etc/metadataType.xml @@ -10,6 +10,6 @@ diff --git a/livesupport/modules/core/etc/metadataTypeContainer.xml b/livesupport/modules/core/etc/metadataTypeContainer.xml index c0953d6ce..f1d49e1e3 100644 --- a/livesupport/modules/core/etc/metadataTypeContainer.xml +++ b/livesupport/modules/core/etc/metadataTypeContainer.xml @@ -3,17 +3,149 @@ - - + + ]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h b/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h index b4aa23801..b5266e6c2 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.25 $ + Version : $Revision: 1.26 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h,v $ ------------------------------------------------------------------------------*/ @@ -50,6 +50,7 @@ #include "LiveSupport/Core/UniqueId.h" #include "LiveSupport/Core/Configurable.h" #include "LiveSupport/Core/Playable.h" +#include "LiveSupport/Core/MetadataTypeContainer.h" namespace LiveSupport { @@ -130,7 +131,7 @@ using namespace boost::posix_time; * * * @author $Author: fgerlits $ - * @version $Revision: 1.25 $ + * @version $Revision: 1.26 $ */ class AudioClip : public Configurable, public Playable @@ -562,27 +563,22 @@ class AudioClip : public Configurable, /** - * Read the metadata contained in the id3v2 tag of the mp3 sound - * file. The id3v1 tag is also read; if a field is present in both, - * the id3v2 tag is used. - * - * Ogg Vorbis sound files are not supported yet. If the - * sound file is not in mp3 format, the method returns normally - * and does not do anything; however, some junk is printed on - * the standard error. + * Read the metadata contained in the id3v2 tags of the mp3 sound + * file. If no id3v2 tags are found, the file is searched for other + * (id3v1, APE, XiphComment) tags. * * The tags are processed and translated into Dublin Core - * metadata fields using the TagConversion class. Only those fields - * are processed which have a Dublin Core equivalent listed in the - * xml element used for configuring TagConversion. + * metadata fields using the MetadataTypeContainer object. * - * @exception std::invalid_argument if TagConversion has not been - * configured yet, or if the AudioClip instance does not + * @param metadataTypes contains a list of all supported + * metadata types. + * @exception std::invalid_argument if the AudioClip instance does not * have a uri field, or the file name contained in the uri - * field is invalid + * field is invalid. */ void - readTag() throw (std::invalid_argument); + readTag(Ptr::Ref metadataTypes) + throw (std::invalid_argument); }; diff --git a/livesupport/modules/core/src/AudioClip.cxx b/livesupport/modules/core/src/AudioClip.cxx index 714fa6ea7..8358a0060 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.25 $ + Version : $Revision: 1.26 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/AudioClip.cxx,v $ ------------------------------------------------------------------------------*/ @@ -604,12 +604,9 @@ AudioClip :: getXmlDocumentString() const throw () * Read the metadata contained in the id3v2 tag of the binary sound file. *----------------------------------------------------------------------------*/ void -AudioClip :: readTag() throw (std::invalid_argument) +AudioClip :: readTag(Ptr::Ref metadataTypes) + throw (std::invalid_argument) { - if (!TagConversion::isConfigured()) { - throw std::invalid_argument("tag conversion table not loaded"); - } - if (!getUri()) { throw std::invalid_argument("audio clip has no uri field"); } @@ -618,72 +615,85 @@ AudioClip :: readTag() throw (std::invalid_argument) throw std::invalid_argument("binary sound file not found"); } - TagLib::FileRef genericFileRef(getUri()->c_str()); - TagLib::Tag* tag = genericFileRef.tag(); - if (!tag) { - return; - } - - Ptr::Ref value; // true = unicode - if (TagConversion::existsId3Tag("Artist")) { - value.reset(new const Glib::ustring(tag->artist().to8Bit(true))); - setMetadata(value, TagConversion::id3ToDublinCore("Artist")); - } - - if (TagConversion::existsId3Tag("Title")) { - value.reset(new const Glib::ustring(tag->title().to8Bit(true))); - setMetadata(value, TagConversion::id3ToDublinCore("Title")); - } - - if (TagConversion::existsId3Tag("Album")) { - value.reset(new const Glib::ustring(tag->album().to8Bit(true))); - setMetadata(value, TagConversion::id3ToDublinCore("Album")); - } - - if (TagConversion::existsId3Tag("Comment")) { - value.reset(new const Glib::ustring(tag->comment().to8Bit(true))); - setMetadata(value, TagConversion::id3ToDublinCore("Comment")); - } - - if (TagConversion::existsId3Tag("Genre")) { - value.reset(new const Glib::ustring(tag->genre().to8Bit(true))); - setMetadata(value, TagConversion::id3ToDublinCore("Genre")); - } - - if (TagConversion::existsId3Tag("Year")) { - std::stringstream yearString; - yearString << tag->year(); - value.reset(new const Glib::ustring(yearString.str())); - setMetadata(value, TagConversion::id3ToDublinCore("Year")); - } - - if (TagConversion::existsId3Tag("Track")) { - std::stringstream trackString; - trackString << tag->track(); - value.reset(new const Glib::ustring(trackString.str())); - setMetadata(value, TagConversion::id3ToDublinCore("Track")); - } - TagLib::MPEG::File mpegFile(getUri()->c_str()); TagLib::ID3v2::Tag* id3v2Tag = mpegFile.ID3v2Tag(); - if (!id3v2Tag) { - return; - } - - TagLib::ID3v2::FrameListMap frameListMap = id3v2Tag->frameListMap(); - TagLib::ID3v2::FrameListMap::ConstIterator it = frameListMap.begin(); - while (it != frameListMap.end()) { - const char* keyBuffer = it->first.data(); - std::string keyString(keyBuffer, 4); - if (TagConversion::existsId3Tag(keyString)) { - TagLib::ID3v2::FrameList frameList = it->second; - if (!frameList.isEmpty()) { - value.reset(new const Glib::ustring(frameList.front() - ->toString().to8Bit(true))); - setMetadata(value, TagConversion::id3ToDublinCore(keyString)); + if (id3v2Tag) { + Ptr::Ref metadata; + Ptr::Ref value; + + TagLib::ID3v2::FrameListMap frameListMap = id3v2Tag->frameListMap(); + TagLib::ID3v2::FrameListMap::ConstIterator it; + + for (it = frameListMap.begin(); it != frameListMap.end(); ++it) { + std::string keyString(it->first.data(), 4); + try { + metadata = metadataTypes->getById3Tag(keyString); + TagLib::ID3v2::FrameList frameList = it->second; + if (!frameList.isEmpty()) { + value.reset(new const Glib::ustring( + frameList.front()->toString().to8Bit(true))); + setMetadata(value, *metadata->getDcName()); + } + } catch (std::invalid_argument &e) { + // id3v2 tag name not found in MetadataTypeContainer + // TODO: print warning? } } - ++it; + return; + } + + TagLib::FileRef genericFileRef(getUri()->c_str()); + TagLib::Tag* tag = genericFileRef.tag(); + if (tag) { + TagLib::String stringValue; + TagLib::uint intValue; + Ptr::Ref value; + + stringValue = tag->artist(); + if (!stringValue.isNull()) { + value.reset(new const Glib::ustring(stringValue.to8Bit(true))); + setMetadata(value, "dc:creator"); + } + + stringValue = tag->title(); + if (!stringValue.isNull()) { + value.reset(new const Glib::ustring(stringValue.to8Bit(true))); + setMetadata(value, "dc:title"); + } + + stringValue = tag->album(); + if (!stringValue.isNull()) { + value.reset(new const Glib::ustring(stringValue.to8Bit(true))); + setMetadata(value, "dc:source"); + } + + stringValue = tag->comment(); + if (!stringValue.isNull()) { + value.reset(new const Glib::ustring(stringValue.to8Bit(true))); + setMetadata(value, "dc:description"); + } + + stringValue = tag->genre(); + if (!stringValue.isNull()) { + value.reset(new const Glib::ustring(stringValue.to8Bit(true))); + setMetadata(value, "dc:type"); + } + + intValue = tag->year(); + if (intValue != 0) { + std::stringstream yearString; + yearString << intValue; + value.reset(new const Glib::ustring(yearString.str())); + setMetadata(value, "ls:year"); + } + + intValue = tag->track(); + if (intValue != 0) { + std::stringstream trackString; + trackString << intValue; + value.reset(new const Glib::ustring(trackString.str())); + setMetadata(value, "ls:track_num"); + } } } diff --git a/livesupport/modules/core/src/AudioClipTest.cxx b/livesupport/modules/core/src/AudioClipTest.cxx index aab535749..cda392e6f 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.12 $ + Version : $Revision: 1.13 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/AudioClipTest.cxx,v $ ------------------------------------------------------------------------------*/ @@ -65,9 +65,15 @@ CPPUNIT_TEST_SUITE_REGISTRATION(AudioClipTest); static const std::string configFileName = "etc/audioClip.xml"; /** - * The name of the configuration file for the tag conversion table. + * The name of the configuration file for the resource bundle. */ -static const std::string tagConversionConfig = "etc/tagConversionTable.xml"; +static const std::string bundleConfigFileName = "etc/resourceBundle.xml"; + +/** + * The name of the configuration file for the metadata type container. + */ +static const std::string metadataConfigFileName + = "etc/metadataTypeContainer.xml"; /* =============================================== local function prototypes */ @@ -81,6 +87,57 @@ static const std::string tagConversionConfig = "etc/tagConversionTable.xml"; void AudioClipTest :: setUp(void) throw () { + try { + Ptr::Ref parser( + new xmlpp::DomParser(configFileName, false)); + const xmlpp::Document * document = parser->get_document(); + const xmlpp::Element * root = document->get_root_node(); + + audioClip.reset(new AudioClip()); + audioClip->configure(*root); + + } catch (std::invalid_argument &e) { + CPPUNIT_FAIL("semantic error in audio clip configuration file"); + } catch (xmlpp::exception &e) { + std::string eMsg = "error parsing audio clip configuration file\n"; + eMsg += e.what(); + CPPUNIT_FAIL(eMsg); + } + + Ptr::Ref bundle; + try { + Ptr::Ref parser( + new xmlpp::DomParser(bundleConfigFileName, false)); + const xmlpp::Document * document = parser->get_document(); + const xmlpp::Element * root = document->get_root_node(); + + bundle = LocalizedObject::getBundle(*root); + + } catch (std::invalid_argument &e) { + CPPUNIT_FAIL("semantic error in configuration file"); + } catch (std::exception &e) { + std::string eMsg = "error parsing audio clip configuration file\n"; + eMsg += e.what(); + CPPUNIT_FAIL(eMsg); + } + CPPUNIT_ASSERT(bundle); + + try { + Ptr::Ref parser( + new xmlpp::DomParser(metadataConfigFileName, false)); + const xmlpp::Document * document = parser->get_document(); + const xmlpp::Element * root = document->get_root_node(); + + metadataTypes.reset(new MetadataTypeContainer(bundle)); + metadataTypes->configure(*root); + + } catch (std::invalid_argument &e) { + CPPUNIT_FAIL("semantic error in metadata configuration file"); + } catch (xmlpp::exception &e) { + std::string eMsg = "error parsing metadata configuration file\n"; + eMsg += e.what(); + CPPUNIT_FAIL(eMsg); + } } @@ -100,49 +157,32 @@ void AudioClipTest :: firstTest(void) throw (CPPUNIT_NS::Exception) { - try { - Ptr::Ref parser( - new xmlpp::DomParser(configFileName, false)); - const xmlpp::Document * document = parser->get_document(); - const xmlpp::Element * root = document->get_root_node(); - Ptr::Ref audioClip(new AudioClip()); + CPPUNIT_ASSERT(audioClip->getId()->getId() == 0x1); + Ptr::Ref duration + = audioClip->getPlaylength(); + CPPUNIT_ASSERT(duration->hours() == 0); + CPPUNIT_ASSERT(duration->minutes() == 18); + CPPUNIT_ASSERT(duration->seconds() == 30); - audioClip->configure(*root); + Ptr::Ref title = audioClip->getTitle(); + CPPUNIT_ASSERT(title); + CPPUNIT_ASSERT(*title == "File Title txt"); - CPPUNIT_ASSERT(audioClip->getId()->getId() == 0x1); - Ptr::Ref duration - = audioClip->getPlaylength(); - CPPUNIT_ASSERT(duration->hours() == 0); - CPPUNIT_ASSERT(duration->minutes() == 18); - CPPUNIT_ASSERT(duration->seconds() == 30); + Ptr::Ref subject = audioClip + ->getMetadata("dc:subject"); + CPPUNIT_ASSERT(subject); + CPPUNIT_ASSERT(*subject == "Keywords: qwe, asd, zcx"); - Ptr::Ref title = audioClip->getTitle(); - CPPUNIT_ASSERT(title); - CPPUNIT_ASSERT(*title == "File Title txt"); + Ptr::Ref alternativeTitle = audioClip + ->getMetadata("dcterms:alternative"); + CPPUNIT_ASSERT(alternativeTitle); + CPPUNIT_ASSERT(*alternativeTitle == + "Alternative File Title ín sőmé %$#@* LÁNGŰAGÉ"); - Ptr::Ref subject = audioClip - ->getMetadata("dc:subject"); - CPPUNIT_ASSERT(subject); - CPPUNIT_ASSERT(*subject == "Keywords: qwe, asd, zcx"); - - Ptr::Ref alternativeTitle = audioClip - ->getMetadata("dcterms:alternative"); - CPPUNIT_ASSERT(alternativeTitle); - CPPUNIT_ASSERT(*alternativeTitle == - "Alternative File Title ín sőmé %$#@* LÁNGŰAGÉ"); - - CPPUNIT_ASSERT(*audioClip->getXmlElementString() == - ""); - - } catch (std::invalid_argument &e) { - CPPUNIT_FAIL("semantic error in configuration file"); - } catch (xmlpp::exception &e) { - std::string eMsg = "error parsing configuration file\n"; - eMsg += e.what(); - CPPUNIT_FAIL(eMsg); - } + CPPUNIT_ASSERT(*audioClip->getXmlElementString() == + ""); } @@ -153,23 +193,6 @@ void AudioClipTest :: conversionTest(void) throw (CPPUNIT_NS::Exception) { - Ptr::Ref audioClip(new AudioClip()); - try { - Ptr::Ref parser( - new xmlpp::DomParser(configFileName, false)); - const xmlpp::Document * document = parser->get_document(); - const xmlpp::Element * root = document->get_root_node(); - - audioClip->configure(*root); - - } catch (std::invalid_argument &e) { - CPPUNIT_FAIL("semantic error in configuration file"); - } catch (xmlpp::exception &e) { - std::string eMsg = "error parsing configuration file\n"; - eMsg += e.what(); - CPPUNIT_FAIL(eMsg); - } - Ptr::Ref playable = audioClip; CPPUNIT_ASSERT(playable->getType() == Playable::AudioClipType); @@ -188,24 +211,10 @@ void AudioClipTest :: tagTest(void) throw (CPPUNIT_NS::Exception) { - try { - Ptr::Ref parser( - new xmlpp::DomParser(tagConversionConfig, false)); - const xmlpp::Document * document = parser->get_document(); - const xmlpp::Element * root = document->get_root_node(); - TagConversion::configure(*root); - } catch (std::invalid_argument &e) { - CPPUNIT_FAIL(e.what()); - } catch (xmlpp::exception &e) { - CPPUNIT_FAIL(e.what()); - } - - Ptr::Ref audioClip(new AudioClip()); - Ptr::Ref uri(new std::string("var/test10001.mp3")); audioClip->setUri(uri); try { - audioClip->readTag(); + audioClip->readTag(metadataTypes); } catch (std::invalid_argument &e) { CPPUNIT_FAIL(e.what()); } @@ -227,21 +236,6 @@ void AudioClipTest :: marshallingTest(void) throw (CPPUNIT_NS::Exception) { - Ptr::Ref audioClip(new AudioClip()); - try { - Ptr::Ref parser( - new xmlpp::DomParser(configFileName, false)); - const xmlpp::Document * document = parser->get_document(); - const xmlpp::Element * root = document->get_root_node(); - - audioClip->configure(*root); - - } catch (std::invalid_argument &e) { - CPPUNIT_FAIL(e.what()); - } catch (xmlpp::exception &e) { - CPPUNIT_FAIL(e.what()); - } - XmlRpc::XmlRpcValue xmlRpcValue = *audioClip; CPPUNIT_ASSERT(xmlRpcValue.hasMember("audioClip")); diff --git a/livesupport/modules/core/src/AudioClipTest.h b/livesupport/modules/core/src/AudioClipTest.h index 2a5205ea1..f7f571a0a 100644 --- a/livesupport/modules/core/src/AudioClipTest.h +++ b/livesupport/modules/core/src/AudioClipTest.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/src/AudioClipTest.h,v $ ------------------------------------------------------------------------------*/ @@ -41,6 +41,7 @@ #endif #include +#include "LiveSupport/Core/AudioClip.h" namespace LiveSupport { @@ -58,7 +59,7 @@ namespace Core { * Unit test for the AudioClip class. * * @author $Author: fgerlits $ - * @version $Revision: 1.4 $ + * @version $Revision: 1.5 $ * @see AudioClip */ class AudioClipTest : public CPPUNIT_NS::TestFixture @@ -70,6 +71,17 @@ class AudioClipTest : public CPPUNIT_NS::TestFixture CPPUNIT_TEST(marshallingTest); CPPUNIT_TEST_SUITE_END(); + private: + /** + * The audio clip to test. + */ + Ptr::Ref audioClip; + + /** + * The list of supported metadata types. + */ + Ptr::Ref metadataTypes; + protected: /** diff --git a/livesupport/modules/core/src/MetadataTypeContainerTest.cxx b/livesupport/modules/core/src/MetadataTypeContainerTest.cxx index c9ee98691..c9fd7bd60 100644 --- a/livesupport/modules/core/src/MetadataTypeContainerTest.cxx +++ b/livesupport/modules/core/src/MetadataTypeContainerTest.cxx @@ -21,8 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Author : $Author: maroy $ - Version : $Revision: 1.2 $ + Author : $Author: fgerlits $ + Version : $Revision: 1.3 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/MetadataTypeContainerTest.cxx,v $ ------------------------------------------------------------------------------*/ @@ -83,19 +83,47 @@ static const std::string configFileName = "etc/metadataTypeContainer.xml"; void MetadataTypeContainerTest :: setUp(void) throw () { + Ptr::Ref rootBundle; try { Ptr::Ref parser( new xmlpp::DomParser(bundleConfigFileName, true)); const xmlpp::Document * document = parser->get_document(); const xmlpp::Element * root = document->get_root_node(); - bundle = LocalizedObject::getBundle(*root); + rootBundle = LocalizedObject::getBundle(*root); + } catch (std::invalid_argument &e) { - CPPUNIT_FAIL("semantic error in configuration file"); + CPPUNIT_FAIL("semantic error in bundle configuration file"); } catch (std::exception &e) { - CPPUNIT_FAIL(e.what()); + CPPUNIT_FAIL(std::string("XML error in bundle configuration file:\n") + + e.what()); } - CPPUNIT_ASSERT(bundle.get()); + CPPUNIT_ASSERT(rootBundle); + + UErrorCode icuError = U_ZERO_ERROR; + bundle.reset(new ResourceBundle(rootBundle->get("metadata", icuError))); + CPPUNIT_ASSERT(U_SUCCESS(icuError)); + CPPUNIT_ASSERT(bundle); + + try { + Ptr::Ref parser( + new xmlpp::DomParser(configFileName, true)); + const xmlpp::Document * document = parser->get_document(); + const xmlpp::Element * root = document->get_root_node(); + + container.reset(new MetadataTypeContainer(bundle)); + container->configure(*root); + + } catch (std::invalid_argument &e) { + CPPUNIT_FAIL(std::string("semantic error in metadata container" + " configuration file:\n") + + e.what()); + } catch (xmlpp::exception &e) { + CPPUNIT_FAIL(std::string("XML error in metadata container" + " configuration file:\n") + + e.what()); + } + } @@ -105,7 +133,6 @@ MetadataTypeContainerTest :: setUp(void) throw () void MetadataTypeContainerTest :: tearDown(void) throw () { - bundle.reset(); } @@ -117,27 +144,8 @@ MetadataTypeContainerTest :: firstTest(void) throw (CPPUNIT_NS::Exception) { Ptr::Ref metadataType; - Ptr::Ref container; bool gotException; - // test configuration from a configuration file - try { - Ptr::Ref parser( - new xmlpp::DomParser(configFileName, true)); - const xmlpp::Document * document = parser->get_document(); - const xmlpp::Element * root = document->get_root_node(); - - container.reset(new MetadataTypeContainer(bundle)); - container->configure(*root); - - } catch (std::invalid_argument &e) { - CPPUNIT_FAIL(std::string("semantic error in configuration file:\n") - + e.what()); - } catch (xmlpp::exception &e) { - CPPUNIT_FAIL(std::string("XML error in configuration file:\n") - + e.what()); - } - // test double-configuration try { Ptr::Ref parser( @@ -163,8 +171,8 @@ MetadataTypeContainerTest :: firstTest(void) metadataType = container->getByDcName("dc:creator"); CPPUNIT_ASSERT(*metadataType->getDcName() == "dc:creator"); - CPPUNIT_ASSERT(*metadataType->getId3Tag() == "TPE2"); - CPPUNIT_ASSERT(*metadataType->getLocalizationKey() == "dc_creator"); + CPPUNIT_ASSERT(*metadataType->getId3Tag() == "TPE1"); + CPPUNIT_ASSERT(*metadataType->getLocalizationKey() == "creator"); // a negative check on the DC name CPPUNIT_ASSERT(!container->existsByDcName("dc:nonExistent")); @@ -178,19 +186,19 @@ MetadataTypeContainerTest :: firstTest(void) CPPUNIT_ASSERT(gotException); // a simple positive check on the ID3v2 tag - CPPUNIT_ASSERT(container->existsById3Tag("TPE2")); - metadataType = container->getById3Tag("TPE2"); + CPPUNIT_ASSERT(container->existsById3Tag("TPE1")); + metadataType = container->getById3Tag("TPE1"); CPPUNIT_ASSERT(*metadataType->getDcName() == "dc:creator"); - CPPUNIT_ASSERT(*metadataType->getId3Tag() == "TPE2"); - CPPUNIT_ASSERT(*metadataType->getLocalizationKey() == "dc_creator"); + CPPUNIT_ASSERT(*metadataType->getId3Tag() == "TPE1"); + CPPUNIT_ASSERT(*metadataType->getLocalizationKey() == "creator"); - // a negative check on the DC name - CPPUNIT_ASSERT(!container->existsByDcName("NonExistentTag")); + // a negative check on the ID3v2 tag + CPPUNIT_ASSERT(!container->existsById3Tag("NonExistentTag")); gotException = false; try { - container->getByDcName("NonExistentTag"); + container->getById3Tag("NonExistentTag"); } catch (std::invalid_argument &e) { gotException = true; } @@ -206,46 +214,31 @@ MetadataTypeContainerTest :: iteratorTest(void) throw (CPPUNIT_NS::Exception) { Ptr::Ref metadataType; - Ptr::Ref container; MetadataTypeContainer::Vector::const_iterator it; MetadataTypeContainer::Vector::const_iterator end; + // check the first two elements in the container + it = container->begin(); + end = container->end(); + + CPPUNIT_ASSERT(it != end); + metadataType = (Ptr::Ref) *it; + CPPUNIT_ASSERT(*metadataType->getDcName() == "dc:title"); + CPPUNIT_ASSERT(*metadataType->getId3Tag() == "TIT2"); + CPPUNIT_ASSERT(*metadataType->getLocalizationKey() == "title"); + + ++it; + CPPUNIT_ASSERT(it != end); + metadataType = (Ptr::Ref) *it; + CPPUNIT_ASSERT(*metadataType->getDcName() == "dc:creator"); + CPPUNIT_ASSERT(*metadataType->getId3Tag() == "TPE1"); + CPPUNIT_ASSERT(*metadataType->getLocalizationKey() == "creator"); + // test on an empty container container.reset(new MetadataTypeContainer(bundle)); it = container->begin(); end = container->end(); CPPUNIT_ASSERT(it == end); - container.reset(); - - // test configuration from a configuration file - try { - Ptr::Ref parser( - new xmlpp::DomParser(configFileName, true)); - const xmlpp::Document * document = parser->get_document(); - const xmlpp::Element * root = document->get_root_node(); - - container.reset(new MetadataTypeContainer(bundle)); - container->configure(*root); - - } catch (std::invalid_argument &e) { - CPPUNIT_FAIL(std::string("semantic error in configuration file:\n") - + e.what()); - } catch (xmlpp::exception &e) { - CPPUNIT_FAIL(std::string("XML error in configuration file:\n") - + e.what()); - } - - // cycle through the iterator, should be one element - it = container->begin(); - end = container->end(); - while (it != end) { - metadataType = (Ptr::Ref) *it; - CPPUNIT_ASSERT(*metadataType->getDcName() == "dc:creator"); - CPPUNIT_ASSERT(*metadataType->getId3Tag() == "TPE2"); - CPPUNIT_ASSERT(*metadataType->getLocalizationKey() == "dc_creator"); - - ++it; - } } @@ -257,25 +250,6 @@ MetadataTypeContainerTest :: localizedTest(void) throw (CPPUNIT_NS::Exception) { Ptr::Ref metadataType; - Ptr::Ref container; - - // test configuration from a configuration file - try { - Ptr::Ref parser( - new xmlpp::DomParser(configFileName, true)); - const xmlpp::Document * document = parser->get_document(); - const xmlpp::Element * root = document->get_root_node(); - - container.reset(new MetadataTypeContainer(bundle)); - container->configure(*root); - - } catch (std::invalid_argument &e) { - CPPUNIT_FAIL(std::string("semantic error in configuration file:\n") - + e.what()); - } catch (xmlpp::exception &e) { - CPPUNIT_FAIL(std::string("XML error in configuration file:\n") - + e.what()); - } CPPUNIT_ASSERT(container->existsByDcName("dc:creator")); metadataType = container->getByDcName("dc:creator"); @@ -283,36 +257,41 @@ MetadataTypeContainerTest :: localizedTest(void) CPPUNIT_ASSERT(*metadataType->getLocalizedName() == "Creator"); UErrorCode status = U_ZERO_ERROR; + Ptr::Ref rootBundle; Ptr::Ref huBundle; Ptr::Ref jpBundle; Ptr::Ref ustr; // test with hungarian - huBundle.reset(new ResourceBundle("./tmp/" PACKAGE_NAME, "hu", status)); + rootBundle.reset(new ResourceBundle("./tmp/" PACKAGE_NAME, "hu", status)); + CPPUNIT_ASSERT(U_SUCCESS(status)); + huBundle.reset(new ResourceBundle(rootBundle->get("metadata", status))); CPPUNIT_ASSERT(U_SUCCESS(status)); container->setBundle(huBundle); ustr = metadataType->getLocalizedName(); - CPPUNIT_ASSERT((*ustr)[0] == 0x004c); // 'L' - CPPUNIT_ASSERT((*ustr)[1] == 0x00e9); // 'e' with acute - CPPUNIT_ASSERT((*ustr)[2] == 0x0074); // 't' - CPPUNIT_ASSERT((*ustr)[3] == 0x0072); // 'r' - CPPUNIT_ASSERT((*ustr)[4] == 0x0065); // 'e' - CPPUNIT_ASSERT((*ustr)[5] == 0x0068); // 'h' - CPPUNIT_ASSERT((*ustr)[6] == 0x006f); // 'o' - CPPUNIT_ASSERT((*ustr)[7] == 0x007a); // 'z' - CPPUNIT_ASSERT((*ustr)[8] == 0x00f3); // 'o' with acute + CPPUNIT_ASSERT(ustr->length() == 6); + CPPUNIT_ASSERT((*ustr)[0] == 0x0045); // 'E' + CPPUNIT_ASSERT((*ustr)[1] == 0x006C); // 'l' + CPPUNIT_ASSERT((*ustr)[2] == 0x0151); // 'o' with double acute + CPPUNIT_ASSERT((*ustr)[3] == 0x0061); // 'a' + CPPUNIT_ASSERT((*ustr)[4] == 0x0064); // 'd' + CPPUNIT_ASSERT((*ustr)[5] == 0x00F3); // 'o' with acute // test with japanese - jpBundle.reset(new ResourceBundle("./tmp/" PACKAGE_NAME, "jp", status)); + rootBundle.reset(new ResourceBundle("./tmp/" PACKAGE_NAME, "jp", status)); + CPPUNIT_ASSERT(U_SUCCESS(status)); + jpBundle.reset(new ResourceBundle(rootBundle->get("metadata", status))); CPPUNIT_ASSERT(U_SUCCESS(status)); container->setBundle(jpBundle); ustr = metadataType->getLocalizedName(); + CPPUNIT_ASSERT(ustr->length() == 6); CPPUNIT_ASSERT((*ustr)[0] == 0x30af); // katakana ku CPPUNIT_ASSERT((*ustr)[1] == 0x30ea); // katakana ri CPPUNIT_ASSERT((*ustr)[2] == 0x30a8); // katakana e CPPUNIT_ASSERT((*ustr)[3] == 0x30fc); // katakana '-' CPPUNIT_ASSERT((*ustr)[4] == 0x30bf); // katakana ta + CPPUNIT_ASSERT((*ustr)[5] == 0x30fc); // katakana '-' } diff --git a/livesupport/modules/core/src/MetadataTypeContainerTest.h b/livesupport/modules/core/src/MetadataTypeContainerTest.h index d34232f22..9f442a366 100644 --- a/livesupport/modules/core/src/MetadataTypeContainerTest.h +++ b/livesupport/modules/core/src/MetadataTypeContainerTest.h @@ -21,8 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Author : $Author: maroy $ - Version : $Revision: 1.2 $ + Author : $Author: fgerlits $ + Version : $Revision: 1.3 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/MetadataTypeContainerTest.h,v $ ------------------------------------------------------------------------------*/ @@ -57,8 +57,8 @@ namespace Core { /** * Unit test for the MetadataTypeContainer class. * - * @author $Author: maroy $ - * @version $Revision: 1.2 $ + * @author $Author: fgerlits $ + * @version $Revision: 1.3 $ * @see MetadataTypeContainer */ class MetadataTypeContainerTest : public CPPUNIT_NS::TestFixture @@ -74,7 +74,12 @@ class MetadataTypeContainerTest : public CPPUNIT_NS::TestFixture /** * The resource bundle used by the container. */ - Ptr::Ref bundle; + Ptr::Ref bundle; + + /** + * The metadata container used in the tests. + */ + Ptr::Ref container; /** * A simple test. diff --git a/livesupport/modules/core/var/hu.txt b/livesupport/modules/core/var/hu.txt index 40f248202..894de6442 100644 --- a/livesupport/modules/core/var/hu.txt +++ b/livesupport/modules/core/var/hu.txt @@ -6,6 +6,9 @@ hu:table bar:string { "bár" } } - dc_creator:string { "Létrehozó" } + metadata:table + { + creator:string { "Előadó" } + } } diff --git a/livesupport/modules/core/var/jp.txt b/livesupport/modules/core/var/jp.txt index 050f069be..df95b8b0c 100644 --- a/livesupport/modules/core/var/jp.txt +++ b/livesupport/modules/core/var/jp.txt @@ -6,6 +6,9 @@ jp:table bar:string { "ばる" } } - dc_creator:string { "クリエーター" } + metadata:table + { + creator:string { "クリエーター" } + } } diff --git a/livesupport/modules/core/var/root.txt b/livesupport/modules/core/var/root.txt index 66a3657ac..c2a668faf 100644 --- a/livesupport/modules/core/var/root.txt +++ b/livesupport/modules/core/var/root.txt @@ -12,6 +12,44 @@ root:table aMessage3Args:string { "p0: {0}, p2: {2}, p1: {1}" } } - dc_creator:string { "Creator" } + metadata:table + { + title:string { "Title" } + creator:string { "Creator" } + album:string { "Album" } + year:string { "Year" } + genre:string { "Genre" } + description:string { "Description" } + format:string { "Format" } + length:string { "Length" } + bpm:string { "BPM" } + rating:string { "Rating" } + encoded_by:string { "Encoded by" } + track_number:string { "Track number" } + disc_number:string { "Disc number" } + mood:string { "Mood" } + publishing_label:string { "Publishing label" } + composer:string { "Composer" } + bitrate:string { "Bitrate" } + channels:string { "Channels" } + sample_rate:string { "Sample rate" } + encoding_software:string { "Encoding software" } + checksum:string { "Checksum" } + lyrics:string { "Lyrics" } + orchestra_or_band:string { "Orchestra or band" } + conductor:string { "Conductor" } + lyricist:string { "Lyricist" } + original_lyricist:string { "Original lyricist" } + radio_station_name:string { "Radio station name" } + audio_file_info_url:string { "File info web page" } + artist_url:string { "Artist web page" } + audio_source_url:string { "Source web page" } + radio_station_url:string { "Radio station web page" } + buy_cd_url:string { "Buy CD web page" } + isrc_number:string { "ISRC number" } + catalog_number:string { "Catalog number" } + original_artist:string { "Original artist" } + copyright:string { "Copyright" } + } } diff --git a/livesupport/products/gLiveSupport/etc/gLiveSupport.xml b/livesupport/products/gLiveSupport/etc/gLiveSupport.xml index 0f1f7e6de..81b15d898 100644 --- a/livesupport/products/gLiveSupport/etc/gLiveSupport.xml +++ b/livesupport/products/gLiveSupport/etc/gLiveSupport.xml @@ -147,144 +147,141 @@ + /> + - diff --git a/livesupport/products/gLiveSupport/etc/gLiveSupport.xml.template b/livesupport/products/gLiveSupport/etc/gLiveSupport.xml.template index 4763018d8..f69a47e6f 100644 --- a/livesupport/products/gLiveSupport/etc/gLiveSupport.xml.template +++ b/livesupport/products/gLiveSupport/etc/gLiveSupport.xml.template @@ -147,140 +147,141 @@ + + + - - - + + /> + - diff --git a/livesupport/products/gLiveSupport/var/es.txt b/livesupport/products/gLiveSupport/var/es.txt index ba55a5f56..ff867c82c 100644 --- a/livesupport/products/gLiveSupport/var/es.txt +++ b/livesupport/products/gLiveSupport/var/es.txt @@ -213,6 +213,7 @@ es:table audio_file_info_url:string { "Sitio web con información del archivo" } artist_url:string { "Sitio web del artista" } audio_source_url:string { "Sitio web de la fuente" } + radio_station_url:string { "Sitio web de la estación de radio" } buy_cd_url:string { "Sitio web para comprar CD" } isrc_number:string { "número ISRC" } catalog_number:string { "número de catálogo" } diff --git a/livesupport/products/gLiveSupport/var/hu.txt b/livesupport/products/gLiveSupport/var/hu.txt index 54f0459b4..167ab838d 100644 --- a/livesupport/products/gLiveSupport/var/hu.txt +++ b/livesupport/products/gLiveSupport/var/hu.txt @@ -149,17 +149,6 @@ hu:table creatorColumnLabel:string { "Előadó" } lengthColumnLabel:string { "Hossz" } - genreMetadataDisplay:string { "Műfaj" } - genreMetadataSearchKey:string { "dc:type" } - creatorMetadataDisplay:string { "Előadó" } - creatorMetadataSearchKey:string { "dc:creator" } - albumMetadataDisplay:string { "Lemez" } - albumMetadataSearchKey:string { "dc:source" } - titleMetadataDisplay:string { "Cím" } - titleMetadataSearchKey:string { "dc:title" } - lengthMetadataDisplay:string { "Hossz" } - lengthMetadataSearchKey:string { "dcterms:extent" } - partialOperatorDisplay:string { "része" } partialOperatorSearchKey:string { "partial" } prefixOperatorDisplay:string { "kezdete" } @@ -222,6 +211,7 @@ hu:table audio_file_info_url:string { "Zeneszám honlapja" } artist_url:string { "Előadó honlapja" } audio_source_url:string { "Forrás honlapja" } + radio_station_url:string { "Rádióadó honlapja" } buy_cd_url:string { "CD-bolt honlapja" } isrc_number:string { "ISRC-szám" } catalog_number:string { "Katalógusszám" } diff --git a/livesupport/products/gLiveSupport/var/root.txt b/livesupport/products/gLiveSupport/var/root.txt index 3c7138a5b..1ea0875a0 100644 --- a/livesupport/products/gLiveSupport/var/root.txt +++ b/livesupport/products/gLiveSupport/var/root.txt @@ -213,6 +213,7 @@ root:table audio_file_info_url:string { "File info web page" } artist_url:string { "Artist web page" } audio_source_url:string { "Source web page" } + radio_station_url:string { "Radio station web page" } buy_cd_url:string { "Buy CD web page" } isrc_number:string { "ISRC number" } catalog_number:string { "Catalog number" } diff --git a/livesupport/products/gLiveSupport/var/sr_CS.txt b/livesupport/products/gLiveSupport/var/sr_CS.txt index 235cfcd6b..0a054fb5e 100644 --- a/livesupport/products/gLiveSupport/var/sr_CS.txt +++ b/livesupport/products/gLiveSupport/var/sr_CS.txt @@ -213,6 +213,7 @@ sr_CS:table audio_file_info_url:string { "Web strana sa informacijama o fajlu" } artist_url:string { "Web strana izvođača" } audio_source_url:string { "Web strana izvora" } + radio_station_url:string { "Web strana radio stanice" } buy_cd_url:string { "Kupi CD preko web strane" } isrc_number:string { "ISRC broj" } catalog_number:string { "Kataloški broj" } diff --git a/livesupport/products/gLiveSupport/var/sr_CS_CYRILLIC.txt b/livesupport/products/gLiveSupport/var/sr_CS_CYRILLIC.txt index d673f3790..6817d96ea 100644 --- a/livesupport/products/gLiveSupport/var/sr_CS_CYRILLIC.txt +++ b/livesupport/products/gLiveSupport/var/sr_CS_CYRILLIC.txt @@ -212,6 +212,7 @@ sr_CS_CYRILLIC:table audio_file_info_url:string { "Веб страна са информацијама о фајлу" } artist_url:string { "Веб страна извођача" } audio_source_url:string { "Веб страна извора" } + radio_station_url:string { "Веб страна радио станице" } buy_cd_url:string { "Купи ЦД преко веб стране" } isrc_number:string { "ISRC број" } catalog_number:string { "Каталошки број" } diff --git a/livesupport/products/scheduler/etc/Makefile.in b/livesupport/products/scheduler/etc/Makefile.in index cd5d5cff3..1b26b2429 100644 --- a/livesupport/products/scheduler/etc/Makefile.in +++ b/livesupport/products/scheduler/etc/Makefile.in @@ -20,8 +20,8 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # -# Author : $Author: maroy $ -# Version : $Revision: 1.57 $ +# Author : $Author: fgerlits $ +# Version : $Revision: 1.58 $ # Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/etc/Makefile.in,v $ # # @configure_input@ @@ -73,6 +73,9 @@ LIBODBCXX_LIBS=@LIBODBCXX_LIBS@ CURL_LIBS=`${USR_DIR}/bin/curl-config --libs` +# TODO: move ICU flag determination to configure script +ICU_LIBS=`${USR_DIR}/bin/icu-config --ldflags --ldflags-toolutil --ldflags-icuio` + TAGLIB_CFLAGS =`${USR_DIR}/bin/taglib-config --cflags` TAGLIB_LIBS =`${USR_DIR}/bin/taglib-config --libs` @@ -156,6 +159,7 @@ LDFLAGS = @LDFLAGS@ -pthread \ ${LIBODBCXX_LIBS} \ ${GSTREAMER_LIBS} \ ${CURL_LIBS} \ + ${ICU_LIBS} \ ${TAGLIB_LIBS} \ -L${USR_LIB_DIR} \ -L${HELIX_LIB_DIR} \