~ubuntu-branches/ubuntu/vivid/guayadeque/vivid

1 by Alessio Treglia
Import upstream version 0.2.5
1
// -------------------------------------------------------------------------------- //
1.1.5 by Alessio Treglia
Import upstream version 0.3.7~ds0
2
//	Copyright (C) 2008-2013 J.Rios
1 by Alessio Treglia
Import upstream version 0.2.5
3
//	anonbeat@gmail.com
4
//
5
//    This Program is free software; you can redistribute it and/or modify
6
//    it under the terms of the GNU General Public License as published by
1.1.3 by Alessio Treglia
Import upstream version 0.3.1~dfsg0
7
//    the Free Software Foundation; either version 3, or (at your option)
1 by Alessio Treglia
Import upstream version 0.2.5
8
//    any later version.
9
//
10
//    This Program is distributed in the hope that it will be useful,
11
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
//    GNU General Public License for more details.
14
//
15
//    You should have received a copy of the GNU General Public License
16
//    along with this program; see the file LICENSE.  If not, write to
17
//    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18
//    http://www.gnu.org/copyleft/gpl.html
19
//
20
// -------------------------------------------------------------------------------- //
21
#include "MusicDns.h"
22
23
#include "Commands.h"
7 by Alessio Treglia
* New upstream release.
24
#include "wx/curl/http.h"
1 by Alessio Treglia
Import upstream version 0.2.5
25
#include "MusicBrainz.h"
26
#include "Utils.h"
1.1.1 by Alessio Treglia
Import upstream version 0.2.7
27
#include "Version.h"
1 by Alessio Treglia
Import upstream version 0.2.5
28
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
29
#include <wx/uri.h>
30
1 by Alessio Treglia
Import upstream version 0.2.5
31
#define guMUSICDNS_CLIENT_ID    "ca3d48c7383db1dcf6dccd1f0cab26e5"
32
#define guMUSICDNS_BASEURL      "http://ofa.musicdns.org/ofa/1/track"
33
34
#define guMUSICDNS_REQSTR_FP    "cid=%s&cvr=%s&fpt=%s&rmd=%d&" \
35
                                "brt=%d&fmt=%s&dur=%ld&art=%s&" \
36
                                "ttl=%s&alb=%s&tnm=%d&gnr=%s&" \
37
                                "yrr=%s&enc=UTF-8&\r\n"
38
39
#define guMUSICDNS_REQSTR_PUID  "cid=%s&cvr=%s&pid=%s&rmd=%d&" \
40
                                "brt=%d&fmt=%s&dur=%ld&art=%s&" \
41
                                "ttl=%s&alb=%s&tnm=%d&gnr=%s&" \
42
                                "yrr=%s&enc=UTF-8&\r\n"
43
44
extern "C" {
45
46
//#include <gstofa.h>
47
// From gstofa.h
48
#define GST_TAG_OFA_FINGERPRINT "ofa-fingerprint"
49
50
//// -------------------------------------------------------------------------------- //
51
//void list_tags( const GstTagList * list, const gchar * tag, gpointer user_data )
52
//{
53
//    printf( "Tag: %s\n", tag );
54
//}
55
56
// -------------------------------------------------------------------------------- //
57
static gboolean gst_bus_async_callback( GstBus * bus, GstMessage * message, guMusicDnsThread * pobj )
58
{
59
    //guLogMessage( wxT( "Got gstreamer message %u" ), GST_MESSAGE_TYPE( message ) );
60
    switch( GST_MESSAGE_TYPE( message ) )
61
    {
62
        case GST_MESSAGE_ERROR :
63
        {
64
            GError * err;
65
            gchar * debug;
66
            gst_message_parse_error( message, &err, &debug );
67
            guLogError( wxT( "Gstreamer error '%s'" ), wxString( err->message, wxConvUTF8 ).c_str() );
68
            g_error_free( err );
69
            g_free( debug );
70
71
            pobj->Stop();
72
            break;
73
        }
74
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
75
//        case GST_MESSAGE_STATE_CHANGED:
76
//        {
77
//            GstState oldstate, newstate, pendingstate;
78
//            gst_message_parse_state_changed( message, &oldstate, &newstate, &pendingstate );
79
//            //guLogMessage( wxT( "State changed... %u  %u  %u" ), oldstate, newstate, pendingstate );
80
//            break;
81
//        }
1 by Alessio Treglia
Import upstream version 0.2.5
82
83
//        case GST_MESSAGE_BUFFERING :
84
//        {
85
//            guLogMessage( wxT( "Buffering..." ) );
86
//            break;
87
//        }
88
89
        case GST_MESSAGE_EOS :
90
        {
91
          //guLogMessage( wxT( "EOS Detected..." ) );
92
          pobj->Stop();
93
          break;
94
        }
95
96
        case GST_MESSAGE_TAG :
97
        {
98
            /* The stream discovered new tags. */
99
            GstTagList * tags;
100
            gchar * fingerprint = NULL;
101
            /* Extract from the message the GstTagList.
102
            * This generates a copy, so we must remember to free it.*/
103
            gst_message_parse_tag( message, &tags );
104
105
            //gst_tag_list_foreach( tags, ( GstTagForeachFunc ) list_tags, NULL );
106
107
            /* Extract the title and artist tags - if they exist */
108
            gst_tag_list_get_string( tags, GST_TAG_OFA_FINGERPRINT, &fingerprint );
109
110
            if( fingerprint )
111
            {
112
                //guLogMessage( wxT( "Gstreamer got fingerprint '%s'" ), wxString( fingerprint, wxConvUTF8 ).c_str() );
113
                pobj->SetFingerprint( fingerprint );
1.1.1 by Alessio Treglia
Import upstream version 0.2.7
114
                g_free( fingerprint );
1 by Alessio Treglia
Import upstream version 0.2.5
115
            }
116
117
            /* Free the tag list */
118
            gst_tag_list_free( tags );
119
            break;
120
        }
121
122
        default:
123
            break;
124
    }
125
126
    return TRUE;
127
}
128
129
// -------------------------------------------------------------------------------- //
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
130
static void on_pad_added( GstElement * comp, GstPad * pad, GstElement * conv )
1 by Alessio Treglia
Import upstream version 0.2.5
131
{
132
  GstCaps * caps;
133
  GstStructure * str;
134
  GstPad * convpad;
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
135
136
  //guLogMessage( wxT( "New pad created..." ) );
137
138
  convpad = gst_element_get_static_pad( conv, "sink" );
139
  if( GST_PAD_IS_LINKED( convpad ) )
140
  {
141
      g_object_unref( convpad );
142
      return;
143
  }
1 by Alessio Treglia
Import upstream version 0.2.5
144
145
  /* check media type */
146
  caps = gst_pad_get_caps( pad );
147
  str = gst_caps_get_structure( caps, 0 );
148
  if( !g_strrstr( gst_structure_get_name( str ), "audio" ) )
149
  {
150
    gst_caps_unref( caps );
151
    gst_object_unref( convpad );
152
    return;
153
  }
154
  gst_caps_unref( caps );
155
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
156
  //guLogMessage( wxT( "Linked composer and converter..." ) );
1 by Alessio Treglia
Import upstream version 0.2.5
157
  /* link'n'play */
158
  gst_pad_link( pad, convpad );
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
159
  g_object_unref( convpad );
1 by Alessio Treglia
Import upstream version 0.2.5
160
}
161
162
163
}
164
165
// -------------------------------------------------------------------------------- //
166
// guMusicDnsThread
167
// -------------------------------------------------------------------------------- //
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
168
guMusicDnsThread::guMusicDnsThread( guMusicDns * musicdns, const wxChar * filename,
169
        const unsigned int start, const unsigned int length )
1 by Alessio Treglia
Import upstream version 0.2.5
170
{
171
  //guLogMessage( wxT( "guMusicDnsThread..." ) );
172
  m_MusicDns = musicdns;
173
  m_FileName = wxString( filename );
174
  m_Running = false;
175
  int Error = guMDNS_STATUS_ERROR_GSTREAMER;
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
176
  m_Start = start;
177
  m_Length = length;
178
179
  if( BuildPipeline() )
180
  {
181
    if( Create() == wxTHREAD_NO_ERROR )
182
    {
183
      SetPriority( WXTHREAD_DEFAULT_PRIORITY - 30 );
184
      Run();
185
    }
186
    else
187
    {
188
      Error = guMDNS_STATUS_ERROR_THREAD;
189
      m_MusicDns->SetStatus( Error );
190
    }
191
  }
192
}
193
194
// -------------------------------------------------------------------------------- //
195
guMusicDnsThread::~guMusicDnsThread()
196
{
197
    if( GST_IS_ELEMENT( m_Pipeline ) )
198
    {
199
        gst_element_set_state( m_Pipeline, GST_STATE_NULL );
200
        gst_object_unref( GST_OBJECT( m_Pipeline ) );
201
    }
202
    m_MusicDns->ClearMusicDnsThread();
203
    //guLogMessage( wxT( "Destroyed MusicDnsThread..." ) );
204
}
205
206
// -------------------------------------------------------------------------------- //
207
bool guMusicDnsThread::BuildPipeline( void )
208
{
1 by Alessio Treglia
Import upstream version 0.2.5
209
  m_Pipeline = gst_pipeline_new( "guPipeline" );
210
  if( GST_IS_ELEMENT( m_Pipeline ) )
211
  {
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
212
    GstElement * comp = gst_element_factory_make( "gnlcomposition", "guComposition" );
213
    if( GST_IS_ELEMENT( comp ) )
1 by Alessio Treglia
Import upstream version 0.2.5
214
    {
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
215
      GstElement * conv = gst_element_factory_make( "audioconvert", "guConverter" );
216
      if( GST_IS_ELEMENT( conv ) )
1 by Alessio Treglia
Import upstream version 0.2.5
217
      {
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
218
        GstElement * ofa = gst_element_factory_make( "ofa", "guOFA" );
219
        if( GST_IS_ELEMENT( ofa ) )
1 by Alessio Treglia
Import upstream version 0.2.5
220
        {
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
221
          GstElement * fake = gst_element_factory_make( "fakesink", "guFakeSink" );
222
          if( GST_IS_ELEMENT( fake ) )
1 by Alessio Treglia
Import upstream version 0.2.5
223
          {
224
            g_object_set( G_OBJECT( fake ), "sync", 0, NULL );
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
225
226
            gst_bin_add_many( GST_BIN( m_Pipeline ), comp, conv, ofa, fake, NULL );
227
228
            g_object_set( m_Pipeline, "async-handling", true, NULL );
229
230
            GstBus * bus = gst_pipeline_get_bus( GST_PIPELINE( m_Pipeline ) );
231
            gst_bus_add_watch( bus, ( GstBusFunc ) gst_bus_async_callback, this );
232
            gst_object_unref( G_OBJECT( bus ) );
233
234
            g_signal_connect( comp, "pad-added", G_CALLBACK( on_pad_added ), conv );
235
236
            if( gst_element_link_many( conv, ofa, fake, NULL ) )
1 by Alessio Treglia
Import upstream version 0.2.5
237
            {
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
238
              GstElement * src = gst_element_factory_make( "gnlfilesource", "guTransSource" );
239
              if( GST_IS_ELEMENT( src ) )
1 by Alessio Treglia
Import upstream version 0.2.5
240
              {
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
241
                wxString Location;
242
                wxURI URI( m_FileName );
243
                if( URI.IsReference() )
244
                {
245
                  Location = wxT( "file://" ) + m_FileName;
246
                }
247
                else
248
                {
249
                  if( !URI.HasScheme() )
1 by Alessio Treglia
Import upstream version 0.2.5
250
                  {
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
251
                    Location = wxT( "http://" ) + m_FileName;
1 by Alessio Treglia
Import upstream version 0.2.5
252
                  }
253
                  else
254
                  {
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
255
                    Location = m_FileName;
1 by Alessio Treglia
Import upstream version 0.2.5
256
                  }
257
                }
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
258
259
                g_object_set( G_OBJECT( src ), "location", ( const char * ) Location.mb_str( wxConvFile ), NULL );
260
                g_object_set( G_OBJECT( src ), "start", 0, NULL );
261
                g_object_set( G_OBJECT( src ), "duration", m_Length * GST_MSECOND, NULL );
262
                g_object_set( G_OBJECT( src ), "media-start", m_Start * GST_MSECOND, NULL );
263
                g_object_set( G_OBJECT( src ), "media-duration", m_Length * GST_MSECOND, NULL );
264
265
                gst_bin_add_many( GST_BIN( comp ), src, NULL );
266
267
                gst_element_set_state( m_Pipeline, GST_STATE_PAUSED );
268
269
                //guLogMessage( wxT( "Created the pipeline..." ) );
270
                return true;
271
              }
1 by Alessio Treglia
Import upstream version 0.2.5
272
            }
273
            else
274
            {
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
275
              guLogError( wxT( "Error linking the objects conv, ofa, fake" ) );
1 by Alessio Treglia
Import upstream version 0.2.5
276
            }
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
277
278
            gst_object_unref( fake );
1 by Alessio Treglia
Import upstream version 0.2.5
279
          }
280
          else
281
          {
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
282
            guLogError( wxT( "Error creating the MusicDns fakeout" ) );
1 by Alessio Treglia
Import upstream version 0.2.5
283
          }
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
284
          gst_object_unref( ofa );
1 by Alessio Treglia
Import upstream version 0.2.5
285
        }
286
        else
287
        {
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
288
          guLogError( wxT( "Error creating the MusicDns ofa" ) );
1 by Alessio Treglia
Import upstream version 0.2.5
289
        }
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
290
        gst_object_unref( conv );
1 by Alessio Treglia
Import upstream version 0.2.5
291
      }
292
      else
293
      {
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
294
        guLogError( wxT( "Error creating the MusicDns converter" ) );
1 by Alessio Treglia
Import upstream version 0.2.5
295
      }
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
296
297
      gst_object_unref( comp );
1 by Alessio Treglia
Import upstream version 0.2.5
298
    }
299
    else
300
    {
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
301
        guLogError( wxT( "Error creating the MusicDns composer" ) );
1 by Alessio Treglia
Import upstream version 0.2.5
302
    }
303
    gst_object_unref( m_Pipeline );
304
  }
305
  else
306
  {
307
        guLogError( wxT( "Error creating the MusicDns pipeline" ) );
308
  }
309
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
310
  return false;
1 by Alessio Treglia
Import upstream version 0.2.5
311
}
312
313
// -------------------------------------------------------------------------------- //
314
guMusicDnsThread::ExitCode guMusicDnsThread::Entry()
315
{
316
    gst_element_set_state( m_Pipeline, GST_STATE_PLAYING );
317
318
    m_Running = true;
319
    while( !TestDestroy() && m_Running )
320
    {
321
        Sleep( 20 );
322
    }
323
    //guLogMessage( wxT( "Finished guMusicDnsThread..." ) );
324
    return 0;
325
}
326
327
// -------------------------------------------------------------------------------- //
328
void guMusicDnsThread::SetFingerprint( const char * fingerprint )
329
{
330
    m_MusicDns->SetFingerprint( fingerprint );
331
    Stop();
332
}
333
334
// -------------------------------------------------------------------------------- //
335
void guMusicDnsThread::Stop( void )
336
{
337
    m_Running = false;
338
}
339
340
// -------------------------------------------------------------------------------- //
341
// guMusicDns
342
// -------------------------------------------------------------------------------- //
343
guMusicDns::guMusicDns( guMusicBrainz * musicbrainz )
344
{
345
    m_MusicDnsThread = NULL;
346
    m_MusicBrainz = musicbrainz;
347
    m_Status = guMDNS_STATUS_OK;
348
}
349
350
// -------------------------------------------------------------------------------- //
351
guMusicDns::~guMusicDns()
352
{
353
    if( m_MusicDnsThread )
354
    {
355
        m_MusicDnsThread->Pause();
356
        m_MusicDnsThread->Delete();
357
    }
358
}
359
360
// -------------------------------------------------------------------------------- //
361
void guMusicDns::SetTrack( const guTrack * track )
362
{
363
    m_Track = track;
364
    m_Fingerprint = wxT( "" );
365
    m_PUID = wxT( "" );
366
    DoGetFingerprint();
367
}
368
369
// -------------------------------------------------------------------------------- //
370
wxString guMusicDns::GetXmlDoc( void )
371
{
372
    return m_XmlDoc;
373
}
374
375
// -------------------------------------------------------------------------------- //
376
wxString guMusicDns::GetFingerprint( void )
377
{
378
    return m_Fingerprint;
379
}
380
381
// -------------------------------------------------------------------------------- //
382
void guMusicDns::SetFingerprint( const wxString &fingerprint )
383
{
384
    m_Fingerprint = fingerprint;
385
    if( !m_Fingerprint.IsEmpty() )
386
        DoGetMetadata();
387
    else
388
        m_Status = guMDNS_STATUS_ERROR_NO_FINGERPRINT;
389
}
390
391
// -------------------------------------------------------------------------------- //
392
void guMusicDns::SetFingerprint( const char * fingerprint )
393
{
394
    SetFingerprint( wxString( fingerprint, wxConvUTF8 ) );
395
}
396
397
// -------------------------------------------------------------------------------- //
398
void guMusicDns::SetXmlDoc( const wxString &xmldoc )
399
{
400
    int EndPos = xmldoc.Find( wxT( "</metadata>" ) ) + 11;
401
    m_XmlDoc = xmldoc.Mid( 0, EndPos );
402
    //guLogMessage( wxT( "XmlDoc:\n%s" ), m_XmlDoc.c_str() );
403
    if( !m_XmlDoc.IsEmpty() )
404
        DoParseXmlDoc();
405
    else
406
        m_Status = guMDNS_STATUS_ERROR_NOXMLDATA;
407
}
408
409
// -------------------------------------------------------------------------------- //
410
wxString guMusicDns::GetPUID( void )
411
{
412
    return m_PUID;
413
}
414
415
// -------------------------------------------------------------------------------- //
416
void guMusicDns::SetPUID( const wxString &puid )
417
{
418
    m_PUID = puid;
419
    if( m_MusicDnsThread )
420
    {
421
        CancelSearch();
422
    }
423
    //guLogMessage( wxT( "Calling FoundPUID..." ) );
424
    m_MusicBrainz->FoundPUID( m_PUID );
425
}
426
427
// -------------------------------------------------------------------------------- //
428
void guMusicDns::SetPUID( const char * puid )
429
{
430
    SetPUID( wxString( puid, wxConvUTF8 ) );
431
}
432
433
// -------------------------------------------------------------------------------- //
434
void guMusicDns::ClearMusicDnsThread( void )
435
{
436
    m_MusicDnsThread = NULL;
437
}
438
439
// -------------------------------------------------------------------------------- //
440
bool guMusicDns::IsRunning( void )
441
{
442
    return m_MusicDnsThread != NULL;
443
}
444
445
// -------------------------------------------------------------------------------- //
446
void guMusicDns::CancelSearch( void )
447
{
448
    if( m_MusicDnsThread )
449
    {
450
        m_MusicDnsThread->Pause();
451
        m_MusicDnsThread->Delete();
452
        m_MusicDnsThread = NULL;
453
    }
454
}
455
456
// -------------------------------------------------------------------------------- //
457
bool guMusicDns::DoGetFingerprint( void )
458
{
459
    //guLogMessage( wxT( "DoGetFingerprint..." ) );
460
    if( m_Track )
461
    {
462
        m_MusicDnsThread = new guMusicDnsThread( this, m_Track->m_FileName.c_str() );
463
    }
464
    return m_MusicDnsThread != NULL;
465
}
466
467
// -------------------------------------------------------------------------------- //
468
bool guMusicDns::DoGetMetadata( void )
469
{
470
    wxString HtmlData = wxString::Format( wxT( guMUSICDNS_REQSTR_FP ),
471
        wxT( guMUSICDNS_CLIENT_ID ),
472
        wxT( ID_GUAYADEQUE_VERSION ),
473
        m_Fingerprint.c_str(),
474
        0,  // only return PUID
475
        m_Track->m_Bitrate,
476
        m_Track->m_FileName.AfterLast( wxT( '.' ) ).c_str(),
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
477
        m_Track->m_Length,
1 by Alessio Treglia
Import upstream version 0.2.5
478
        !m_Track->m_ArtistName.IsEmpty() ? m_Track->m_ArtistName.c_str() : wxT( "unknown" ),
479
        !m_Track->m_SongName.IsEmpty() ? m_Track->m_SongName.c_str() : wxT( "unknown" ),
480
        !m_Track->m_AlbumName.IsEmpty() ? m_Track->m_AlbumName.c_str() : wxT( "unknown" ),
481
        m_Track->m_Number,
482
        !m_Track->m_GenreName.IsEmpty() ? m_Track->m_GenreName.c_str() : wxT( "unknown" ),
483
        wxString::Format( wxT( "%u" ), m_Track->m_Year ).c_str() );
484
485
486
    //guLogMessage( wxT( guMUSICDNS_BASEURL ) wxT( "%s" ), HtmlData.c_str() );
487
    wxCurlHTTP  http;
1.1.1 by Alessio Treglia
Import upstream version 0.2.7
488
    http.AddHeader( wxT( "User-Agent: " ) guDEFAULT_BROWSER_USER_AGENT );
1 by Alessio Treglia
Import upstream version 0.2.5
489
    http.AddHeader( wxT( "Accept: text/html" ) );
490
    http.AddHeader( wxT( "Accept-Charset: utf-8" ) );
1.1.1 by Alessio Treglia
Import upstream version 0.2.7
491
    http.SetOpt( CURLOPT_FOLLOWLOCATION, 1 );
1 by Alessio Treglia
Import upstream version 0.2.5
492
    if( http.Post( wxCURL_STRING2BUF( HtmlData ), HtmlData.Length(), wxT( guMUSICDNS_BASEURL ) ) )
493
    {
494
        SetXmlDoc( http.GetResponseBody() );
495
        return true;
496
    }
497
    else
498
    {
1.1.4 by Alessio Treglia
Import upstream version 0.3.5~ds0
499
        //guLogMessage( wxT( guMUSICDNS_BASEURL ) wxT( "\n%s" ), HtmlData.c_str() );
1 by Alessio Treglia
Import upstream version 0.2.5
500
        m_Status = guMDNS_STATUS_ERROR_HTTP;
501
    }
502
    return false;
503
}
504
505
// -------------------------------------------------------------------------------- //
506
bool guMusicDns::ReadTrackInfo( wxXmlNode * XmlNode )
507
{
508
//    <?xml version="1.0" encoding="UTF-8"?>
509
//    <metadata xmlns="http://musicbrainz.org/ns/mmd-1.0#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:mip="http://musicip.com/ns/mip-1.0#">
510
//      <track>
511
//        <title>Song Title</title>
512
//        <artist>
513
//          <name>Artist Name</name>
514
//        </artist>
515
//        <puid-list>
516
//          <puid id="2c43ec65-b629-f449-3f5e-c0b69527d771"/>
517
//        </puid-list>
518
//      </track>
519
//    </metadata>
520
    if( XmlNode && XmlNode->GetName() == wxT( "track" ) )
521
    {
522
        XmlNode = XmlNode->GetChildren();
523
        while( XmlNode )
524
        {
525
            if( XmlNode->GetName() == wxT( "puid-list" ) )
526
            {
527
                XmlNode = XmlNode->GetChildren();
528
                continue;
529
            }
530
            else if( XmlNode->GetName() == wxT( "puid" ) )
531
            {
532
                wxString PUId;
533
                XmlNode->GetPropVal( wxT( "id" ), &PUId );
534
                SetPUID( PUId );
535
                return true;
536
            }
537
            XmlNode = XmlNode->GetNext();
538
        }
539
    }
540
    m_Status = guMDNS_STATUS_ERROR_XMLPARSE;
541
    return false;
542
}
543
544
// -------------------------------------------------------------------------------- //
545
bool guMusicDns::DoParseXmlDoc( void )
546
{
547
    wxStringInputStream ins( m_XmlDoc );
548
    wxXmlDocument XmlDoc( ins );
549
    wxXmlNode * XmlNode = XmlDoc.GetRoot();
550
    if( XmlNode && ( XmlNode->GetName() == wxT( "metadata" ) ) )
551
    {
552
        return ReadTrackInfo( XmlNode->GetChildren() );
553
    }
554
    else
555
        m_Status = guMDNS_STATUS_ERROR_XMLERROR;
556
    return false;
557
}
558
559
// -------------------------------------------------------------------------------- //
560
void guMusicDns::SetStatus( const int status )
561
{
562
    m_Status = status;
563
}
564
565
// -------------------------------------------------------------------------------- //
566
int guMusicDns::GetStatus( void )
567
{
568
    return m_Status;
569
}
570
571
// -------------------------------------------------------------------------------- //
572
bool guMusicDns::IsOk( void )
573
{
574
    return m_Status == guMDNS_STATUS_OK;
575
}
576
577
// -------------------------------------------------------------------------------- //