From 6218cec38a1903688cfeabdf8b3e5deac21d50e1 Mon Sep 17 00:00:00 2001 From: hugolm84 Date: Mon, 5 Sep 2011 15:39:25 +0200 Subject: [PATCH] Adding Itunes parser --- src/libtomahawk/CMakeLists.txt | 2 + src/libtomahawk/dropjob.cpp | 22 +++- src/libtomahawk/utils/itunesparser.cpp | 167 +++++++++++++++++++++++++ src/libtomahawk/utils/itunesparser.h | 69 ++++++++++ 4 files changed, 258 insertions(+), 2 deletions(-) create mode 100644 src/libtomahawk/utils/itunesparser.cpp create mode 100644 src/libtomahawk/utils/itunesparser.h diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 8cf19fe80..eae4c4dac 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -182,6 +182,7 @@ set( libSources utils/xspfgenerator.cpp utils/jspfloader.cpp utils/spotifyparser.cpp + utils/itunesparser.cpp utils/rdioparser.cpp utils/shortenedlinkparser.cpp utils/stylehelper.cpp @@ -386,6 +387,7 @@ set( libHeaders utils/xspfgenerator.h utils/jspfloader.h utils/spotifyparser.h + utils/itunesparser.h utils/rdioparser.h utils/shortenedlinkparser.h diff --git a/src/libtomahawk/dropjob.cpp b/src/libtomahawk/dropjob.cpp index 649bff453..51d77d54f 100644 --- a/src/libtomahawk/dropjob.cpp +++ b/src/libtomahawk/dropjob.cpp @@ -24,6 +24,7 @@ #include "source.h" #include "utils/spotifyparser.h" +#include "utils/itunesparser.h" #include "utils/rdioparser.h" #include "utils/shortenedlinkparser.h" #include "utils/logger.h" @@ -112,13 +113,20 @@ DropJob::acceptsMimeData( const QMimeData* data, DropJob::DropTypes acceptedType ) return true; - // crude check for spotify tracks + // crude check for spotify playlists if ( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "spotify" ) && data->data( "text/plain" ).contains( "playlist" ) && ( acceptedType.testFlag(DropJob::Playlist) || acceptedType.testFlag(DropJob::All) ) ) return true; + // crude check for itunes tracks + if ( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "itunes" ) + && data->data( "text/plain" ).contains( "album" ) + && ( acceptedType.testFlag(DropJob::Track) || acceptedType.testFlag(DropJob::All) ) + ) + return true; + // crude check for spotify tracks if ( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "spotify" ) && data->data( "text/plain" ).contains( "track" ) @@ -184,7 +192,7 @@ DropJob::tracksFromMimeData( const QMimeData* data, bool allowDuplicates, bool o void DropJob::parseMimeData( const QMimeData *data ) { - + qDebug() << Q_FUNC_INFO << data->hasText(); if(dropTypes() & DropJob::Playlist) qDebug() << Q_FUNC_INFO << "DropType is Playlist"; @@ -465,10 +473,20 @@ DropJob::handleTrackUrls( const QString& urls ) qDebug() << Q_FUNC_INFO << urls; + if ( urls.contains( "open.spotify.com/user") || urls.contains( "spotify:user" ) ) handleSpPlaylist( urls, dropAction() ); + else if ( urls.contains( "itunes.apple.com") ) + { + QStringList tracks = urls.split(QRegExp("\\s+"), QString::SkipEmptyParts); + + tDebug() << "Got a list of itunes urls!" << tracks; + ItunesParser* itunes = new ItunesParser( tracks, this ); + connect( itunes, SIGNAL( tracks( QList ) ), this, SLOT( onTracksAdded( QList< Tomahawk::query_ptr > ) ) ); + m_queryCount++; + } else if ( urls.contains( "open.spotify.com/track") || urls.contains( "spotify:track" ) ) { diff --git a/src/libtomahawk/utils/itunesparser.cpp b/src/libtomahawk/utils/itunesparser.cpp new file mode 100644 index 000000000..564c502f6 --- /dev/null +++ b/src/libtomahawk/utils/itunesparser.cpp @@ -0,0 +1,167 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "itunesparser.h" + +#include "utils/logger.h" +#include "utils/tomahawkutils.h" +#include "query.h" +#include "sourcelist.h" +#include + +#include +#include +#include + +using namespace Tomahawk; + +ItunesParser::ItunesParser( const QStringList& Urls, QObject* parent, bool createNewPlaylist) + : QObject ( parent ) + , m_single( false ) + +{ + m_createNewPlaylist = createNewPlaylist; + foreach ( const QString& url, Urls ) + lookupUrl( url ); +} + +ItunesParser::ItunesParser( const QString& Url, QObject* parent, bool createNewPlaylist ) + : QObject ( parent ) + , m_single( true ) +{ + m_createNewPlaylist = createNewPlaylist; + lookupUrl( Url ); +} + +ItunesParser::~ItunesParser() +{ + +} + + +void +ItunesParser::lookupUrl( const QString& link ) +{ + qDebug() << Q_FUNC_INFO; + if( link.contains( "album" ) && link.contains( "?i=")) + lookupTrack(link); + + else return; // We only support tracks and playlists + +} + +void +ItunesParser::lookupTrack( const QString& link ) +{ + + tDebug() << "Got a QString " << link; + if ( !link.contains( "album" ) && !link.contains( "?i=" )) // we only support track links atm + return; + + QRegExp rxlen("(\\d+)(?:\\?i=)(\\d+)(?:\\s*)"); + QString albumId; + QString trackId; + int pos = rxlen.indexIn(link); + if (pos > -1) { + albumId = rxlen.cap(1); + trackId = rxlen.cap(2); + }else return; + + qDebug() << "Got Itunes link with Albumid " << albumId << "and trackid " <get( QNetworkRequest( url ) ); + connect( reply, SIGNAL( finished() ), this, SLOT( itunesTrackLookupFinished() ) ); + + m_queries.insert( reply ); + +} +void +ItunesParser::itunesTrackLookupFinished() +{ + QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() ); + Q_ASSERT( r ); + m_queries.remove( r ); + r->deleteLater(); + + if ( r->error() == QNetworkReply::NoError ) + { + QJson::Parser p; + bool ok; + QVariantMap res = p.parse( r, &ok ).toMap(); + + if ( !ok ) + { + tLog() << "Failed to parse json from Spotify track lookup:" << p.errorString() << "On line" << p.errorLine(); + checkTrackFinished(); + return; + } else if ( !res.contains( "results" ) ) + { + tLog() << "No 'results' item in the itunes track lookup result... not doing anything"; + checkTrackFinished(); + return; + } + + + QString title, artist, album; + QVariantList itunesResponse = res.value( "results" ).toList(); + + // Bad parsing? + foreach(QVariant itune, itunesResponse){ + + title = itune.toMap().value( "trackName" ).toString(); + artist = itune.toMap().value( "artistName" ).toString(); + album = itune.toMap().value( "collectionName" ).toString(); + } + + if ( title.isEmpty() && artist.isEmpty() ) // don't have enough... + { + tLog() << "Didn't get an artist and track name from itunes, not enough to build a query on. Aborting" << title << artist << album; + return; + } + + Tomahawk::query_ptr q = Tomahawk::Query::get( artist, title, album, uuid(), true ); + m_tracks << q; + + } else + { + tLog() << "Error in network request to Spotify for track decoding:" << r->errorString(); + } + + checkTrackFinished(); +} + + + +void +ItunesParser::checkTrackFinished() +{ + if ( m_queries.isEmpty() ) // we're done + { + if ( m_single && !m_tracks.isEmpty() ) + emit track( m_tracks.first() ); + else if ( !m_single && !m_tracks.isEmpty() ) + emit tracks( m_tracks ); + + deleteLater(); + } + +} diff --git a/src/libtomahawk/utils/itunesparser.h b/src/libtomahawk/utils/itunesparser.h new file mode 100644 index 000000000..389700016 --- /dev/null +++ b/src/libtomahawk/utils/itunesparser.h @@ -0,0 +1,69 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef ITUNES_PARSER_H +#define ITUNES_PARSER_H + +#include "dllmacro.h" +#include "typedefs.h" + +#include +#include +#include + +class QNetworkReply; +namespace Tomahawk +{ + +/** + * Small class to parse spotify links into query_ptrs + * + * Connect to the signals to get the results + */ +class DLLEXPORT ItunesParser : public QObject +{ + Q_OBJECT +public: + explicit ItunesParser( const QString& trackUrl, QObject* parent = 0, bool createNewPl = false ); + explicit ItunesParser( const QStringList& trackUrls, QObject* parent = 0, bool createNewPl = false); + virtual ~ItunesParser(); + +signals: + void track( const Tomahawk::query_ptr& track ); + void tracks( const QList< Tomahawk::query_ptr > tracks ); + void playlist( const Tomahawk::query_ptr& playlist ); + +private slots: + void itunesTrackLookupFinished(); + +private: + void lookupUrl( const QString& url ); + void lookupTrack( const QString& track ); + void checkTrackFinished(); + + bool m_single; + bool m_createNewPlaylist; + QList< query_ptr > m_tracks; + QSet< QNetworkReply* > m_queries; + QString m_title, m_info, m_creator; + Tomahawk::playlist_ptr m_playlist; +}; + +} + +#endif