/src/libtomahawk/utils/JspfLoader.cpp

http://github.com/tomahawk-player/tomahawk · C++ · 231 lines · 168 code · 45 blank · 18 comment · 22 complexity · b6244219c2715e8169b237f8f0dcbe2b MD5 · raw file

  1. /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2. *
  3. * Copyright 2010-2011, Leo Franchi <lfranchi@kde.org
  4. * Copyright 2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
  5. *
  6. * Tomahawk is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Tomahawk is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "JspfLoader.h"
  20. #include "utils/Json.h"
  21. #include "utils/Logger.h"
  22. #include "utils/NetworkReply.h"
  23. #include "utils/TomahawkUtils.h"
  24. #include "utils/NetworkAccessManager.h"
  25. #include "Playlist.h"
  26. #include "SourceList.h"
  27. #include "Track.h"
  28. #include <QApplication>
  29. #include <QDomDocument>
  30. #include <QMessageBox>
  31. using namespace Tomahawk;
  32. JSPFLoader::JSPFLoader( bool autoCreate, QObject* parent )
  33. : QObject( parent )
  34. , m_autoCreate( autoCreate )
  35. , m_autoDelete( true )
  36. {
  37. }
  38. JSPFLoader::~JSPFLoader()
  39. {
  40. }
  41. QList< Tomahawk::query_ptr >
  42. JSPFLoader::entries() const
  43. {
  44. return m_entries;
  45. }
  46. void
  47. JSPFLoader::load( const QUrl& url )
  48. {
  49. QNetworkRequest request( url );
  50. Q_ASSERT( Tomahawk::Utils::nam() != 0 );
  51. NetworkReply* reply = new NetworkReply( Tomahawk::Utils::nam()->get( request ) );
  52. connect( reply, SIGNAL( finished() ), SLOT( networkLoadFinished() ) );
  53. connect( reply, SIGNAL( error( QNetworkReply::NetworkError ) ), SLOT( networkError( QNetworkReply::NetworkError ) ) );
  54. }
  55. void
  56. JSPFLoader::load( QFile& file )
  57. {
  58. if ( file.open( QFile::ReadOnly ) )
  59. {
  60. m_body = file.readAll();
  61. gotBody();
  62. }
  63. else
  64. {
  65. tLog() << "Failed to open jspf file";
  66. reportError();
  67. }
  68. }
  69. void
  70. JSPFLoader::reportError()
  71. {
  72. emit failed();
  73. if ( m_autoDelete )
  74. deleteLater();
  75. }
  76. void
  77. JSPFLoader::networkLoadFinished()
  78. {
  79. NetworkReply* r = qobject_cast<NetworkReply*>( sender() );
  80. r->deleteLater();
  81. if ( r->reply()->error() == QNetworkReply::NoError )
  82. {
  83. m_body = r->reply()->readAll();
  84. gotBody();
  85. }
  86. }
  87. void
  88. JSPFLoader::networkError( QNetworkReply::NetworkError e )
  89. {
  90. Q_UNUSED( e );
  91. reportError();
  92. NetworkReply* r = qobject_cast<NetworkReply*>( sender() );
  93. r->deleteLater();
  94. }
  95. void
  96. JSPFLoader::gotBody()
  97. {
  98. bool retOk;
  99. QVariantMap wrapper = TomahawkUtils::parseJson( m_body, &retOk ).toMap();
  100. if ( !retOk )
  101. {
  102. tLog() << "Failed to parse jspf json: " << m_body;
  103. return;
  104. }
  105. if ( !wrapper.contains( "playlist" ) )
  106. {
  107. tLog() << "No playlist element in JSPF!";
  108. return;
  109. }
  110. QVariantMap pl = wrapper.value( "playlist" ).toMap();
  111. QString origTitle = pl.value( "title" ).toString();
  112. m_info = pl.value( "info" ).toString();
  113. m_creator = pl.value( "creator" ).toString();
  114. m_title = origTitle;
  115. if ( m_title.isEmpty() )
  116. m_title = tr( "New Playlist" );
  117. if ( !m_overrideTitle.isEmpty() )
  118. m_title = m_overrideTitle;
  119. if ( pl.contains( "track" ) )
  120. {
  121. QVariantList tracks = pl.value( "track" ).toList();
  122. bool shownError = false;
  123. foreach ( const QVariant& currentTrack, tracks )
  124. {
  125. QVariantMap tM = currentTrack.toMap();
  126. QString artist, album, track, duration, annotation, url;
  127. artist = tM.value( "creator" ).toString();
  128. album = tM.value( "album" ).toString();
  129. track = tM.value( "title" ).toString();
  130. duration = tM.value( "duration" ).toString();
  131. annotation = tM.value( "annotation" ).toString();
  132. if ( tM.value( "location" ).toList().size() > 0 )
  133. url = tM.value( "location" ).toList().first().toString();
  134. if ( artist.isEmpty() || track.isEmpty() )
  135. {
  136. if ( !shownError )
  137. {
  138. QMessageBox::warning( 0, tr( "Failed to save tracks" ), tr( "Some tracks in the playlist do not contain an artist and a title. They will be ignored." ), QMessageBox::Ok );
  139. shownError = true;
  140. }
  141. continue;
  142. }
  143. track_ptr t = Tomahawk::Track::get( artist, track, album, QString(), duration.toInt() / 1000 );
  144. query_ptr q = Tomahawk::Query::get( t );
  145. if ( !q )
  146. continue;
  147. if ( !url.isEmpty() )
  148. {
  149. q->setResultHint( url );
  150. q->setSaveHTTPResultHint( true );
  151. }
  152. m_entries << q;
  153. }
  154. }
  155. if ( origTitle.isEmpty() && m_entries.isEmpty() )
  156. {
  157. if ( m_autoCreate )
  158. {
  159. QMessageBox::critical( 0, tr( "XSPF Error" ), tr( "This is not a valid XSPF playlist." ) );
  160. return;
  161. }
  162. else
  163. {
  164. emit failed();
  165. return;
  166. }
  167. }
  168. if ( m_autoCreate )
  169. {
  170. m_playlist = Playlist::create( SourceList::instance()->getLocal(),
  171. uuid(),
  172. m_title,
  173. m_info,
  174. m_creator,
  175. false,
  176. m_entries );
  177. emit ok( m_playlist );
  178. }
  179. else
  180. {
  181. if ( !m_entries.isEmpty() )
  182. emit tracks( m_entries );
  183. }
  184. if ( m_autoDelete )
  185. deleteLater();
  186. }