diff --git a/src/libtomahawk/database/databasecommand_addfiles.cpp b/src/libtomahawk/database/databasecommand_addfiles.cpp index 56f36ebbe..8eec10a93 100644 --- a/src/libtomahawk/database/databasecommand_addfiles.cpp +++ b/src/libtomahawk/database/databasecommand_addfiles.cpp @@ -2,6 +2,8 @@ #include +#include "artist.h" +#include "album.h" #include "collection.h" #include "database/database.h" #include "databasecommand_collectionstats.h" @@ -105,7 +107,7 @@ DatabaseCommand_AddFiles::exec( DatabaseImpl* dbi ) int albumpos = m.value( "albumpos" ).toInt(); int year = m.value( "year" ).toInt(); - int fileid = 0; + int fileid = 0, artistid = 0, albumid = 0, trackid = 0; query_file_del.bindValue( 0, url ); query_file_del.exec(); @@ -127,53 +129,67 @@ DatabaseCommand_AddFiles::exec( DatabaseImpl* dbi ) } else { - if( added % 100 == 0 ) + if( added % 1000 == 0 ) qDebug() << "Inserted" << added; } // get internal IDs for art/alb/trk fileid = query_file.lastInsertId().toInt(); - - // insert the new fileid, set the url for our use: m.insert( "id", fileid ); - if( !source()->isLocal() ) - m["url"] = QString( "servent://%1\t%2" ) - .arg( source()->userName() ) - .arg( fileid ); + // this is the qvariant(map) the remote will get v = m; + if( !source()->isLocal() ) + url = QString( "servent://%1\t%2" ) + .arg( source()->userName() ) + .arg( url ); + bool isnew; - m["artistid"] = dbi->artistId( artist, isnew ); - if( m["artistid"].toInt() < 1 ) continue; - - m["trackid"] = dbi->trackId( m["artistid"].toInt(), track, isnew ); - if( m["trackid"].toInt() < 1 ) continue; - - m["albumid"] = dbi->albumId( m["artistid"].toInt(), album, isnew ); + artistid = dbi->artistId( artist, isnew ); + if ( artistid < 1 ) + continue; + trackid = dbi->trackId( artistid, track, isnew ); + if ( trackid < 1 ) + continue; + albumid = dbi->albumId( artistid, album, isnew ); // Now add the association query_filejoin.bindValue( 0, fileid ); - query_filejoin.bindValue( 1, m["artistid"].toInt() ); - query_filejoin.bindValue( 2, m["albumid"].toInt() > 0 ? m["albumid"].toInt() : QVariant( QVariant::Int ) ); - query_filejoin.bindValue( 3, m["trackid"].toInt() ); + query_filejoin.bindValue( 1, artistid ); + query_filejoin.bindValue( 2, albumid > 0 ? albumid : QVariant( QVariant::Int ) ); + query_filejoin.bindValue( 3, trackid ); query_filejoin.bindValue( 4, albumpos ); - if( !query_filejoin.exec() ) + if ( !query_filejoin.exec() ) { qDebug() << "Error inserting into file_join table"; continue; } - query_trackattr.bindValue( 0, m["trackid"].toInt() ); + query_trackattr.bindValue( 0, trackid ); query_trackattr.bindValue( 1, "releaseyear" ); query_trackattr.bindValue( 2, year ); query_trackattr.exec(); QVariantMap attr; - Tomahawk::query_ptr query = Tomahawk::Query::get( m, false ); - m["score"] = 1.0; + Tomahawk::query_ptr query = Tomahawk::Query::get( artist, track, album ); attr["releaseyear"] = m.value( "year" ); - Tomahawk::result_ptr result = Tomahawk::result_ptr( new Tomahawk::Result( m, source()->collection() ) ); + Tomahawk::artist_ptr artistptr = Tomahawk::Artist::get( artistid, artist, source()->collection() ); + Tomahawk::album_ptr albumptr = Tomahawk::Album::get( albumid, album, artistptr, source()->collection() ); + Tomahawk::result_ptr result = Tomahawk::result_ptr( new Tomahawk::Result() ); + result->setModificationTime( mtime ); + result->setSize( size ); + result->setMimetype( mimetype ); + result->setDuration( duration ); + result->setBitrate( bitrate ); + result->setArtist( artistptr ); + result->setAlbum( albumptr ); + result->setTrack( track ); + result->setAlbumPos( albumpos ); result->setAttributes( attr ); + result->setCollection( source()->collection() ); + result->setScore( 1.0 ); + result->setUrl( url ); + result->setId( trackid ); QList results; results << result; diff --git a/src/libtomahawk/database/databasecommand_alltracks.cpp b/src/libtomahawk/database/databasecommand_alltracks.cpp index 13b721c0d..41205f8c0 100644 --- a/src/libtomahawk/database/databasecommand_alltracks.cpp +++ b/src/libtomahawk/database/databasecommand_alltracks.cpp @@ -3,6 +3,9 @@ #include #include "databaseimpl.h" +#include "artist.h" +#include "album.h" + void DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi ) @@ -56,52 +59,54 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi ) int i = 0; while( query.next() ) { - QVariantMap t; + Tomahawk::result_ptr result = Tomahawk::result_ptr( new Tomahawk::Result() ); QVariantMap attr; - QString url; TomahawkSqlQuery attrQuery = dbi->newquery(); - url = query.value( 7 ).toString(); if( m_collection->source()->isLocal() ) - t["url"] = url; + result->setUrl( query.value( 7 ).toString() ); else - t["url"] = QString( "servent://%1\t%2" ).arg( m_collection->source()->userName() ).arg( url ); + result->setUrl( QString( "servent://%1\t%2" ).arg( m_collection->source()->userName() ).arg( query.value( 7 ).toString() ) ); - t["id"] = QString( "%1" ).arg( query.value( 0 ).toInt() ); - t["artist"] = query.value( 1 ).toString(); - t["artistid"] = query.value( 12 ).toUInt(); - t["album"] = query.value( 2 ).toString(); - t["albumid"] = query.value( 13 ).toUInt(); - t["track"] = query.value( 3 ).toString(); - t["size"] = query.value( 4 ).toInt(); - t["duration"] = query.value( 5 ).toInt(); - t["bitrate"] = query.value( 6 ).toInt(); - t["mtime"] = query.value( 9 ).toInt(); - t["mimetype"] = query.value( 10 ).toString(); - t["albumpos"] = query.value( 11 ).toUInt(); - t["trackid"] = query.value( 14 ).toUInt(); + QString artist, track, album; + artist = query.value( 1 ).toString(); + album = query.value( 2 ).toString(); + track = query.value( 3 ).toString(); + Tomahawk::query_ptr qry = Tomahawk::Query::get( artist, track, album ); + Tomahawk::artist_ptr artistptr = Tomahawk::Artist::get( query.value( 12 ).toUInt(), artist, m_collection ); + Tomahawk::album_ptr albumptr = Tomahawk::Album::get( query.value( 13 ).toUInt(), album, artistptr, m_collection ); + + result->setId( query.value( 14 ).toUInt() ); + result->setArtist( artistptr ); + result->setAlbum( albumptr ); + result->setTrack( query.value( 3 ).toString() ); + result->setSize( query.value( 4 ).toUInt() ); + result->setDuration( query.value( 5 ).toUInt() ); + result->setBitrate( query.value( 6 ).toUInt() ); + result->setModificationTime( query.value( 9 ).toUInt() ); + result->setMimetype( query.value( 10 ).toString() ); + result->setAlbumPos( query.value( 11 ).toUInt() ); + result->setScore( 1.0 ); + result->setCollection( m_collection ); + attrQuery.prepare( "SELECT k, v FROM track_attributes WHERE id = ?" ); - attrQuery.bindValue( 0, t["trackid"] ); + attrQuery.bindValue( 0, result->dbid() ); attrQuery.exec(); while ( attrQuery.next() ) { attr[ attrQuery.value( 0 ).toString() ] = attrQuery.value( 1 ).toString(); } - Tomahawk::query_ptr query = Tomahawk::Query::get( t, false ); - t["score"] = 1.0; - - Tomahawk::result_ptr result = Tomahawk::result_ptr( new Tomahawk::Result( t, m_collection ) ); result->setAttributes( attr ); QList results; results << result; - query->addResults( results ); + qry->addResults( results ); - ql << query; + ql << qry; - if ( ++i % 1000 == 0 ) + if ( ++i % 5000 == 0 ) { emit tracks( ql, m_collection ); ql.clear(); diff --git a/src/libtomahawk/database/databasecommand_loadfile.cpp b/src/libtomahawk/database/databasecommand_loadfile.cpp index 6b1870e26..b54c601b2 100644 --- a/src/libtomahawk/database/databasecommand_loadfile.cpp +++ b/src/libtomahawk/database/databasecommand_loadfile.cpp @@ -14,7 +14,7 @@ DatabaseCommand_LoadFile::DatabaseCommand_LoadFile( const QString& id, QObject* void DatabaseCommand_LoadFile::exec( DatabaseImpl* dbi ) { - QVariantMap r; + Tomahawk::result_ptr r; // file ids internally are really ints, at least for now: bool ok; do @@ -26,5 +26,5 @@ DatabaseCommand_LoadFile::exec( DatabaseImpl* dbi ) r = dbi->file( fid ); } while( false ); - emit result( Tomahawk::result_ptr( new Tomahawk::Result( r, Tomahawk::collection_ptr() ) ) ); + emit result( r ); } diff --git a/src/libtomahawk/database/databasecommand_loadfile.h b/src/libtomahawk/database/databasecommand_loadfile.h index 7cc2fdf89..1bc04b6bc 100644 --- a/src/libtomahawk/database/databasecommand_loadfile.h +++ b/src/libtomahawk/database/databasecommand_loadfile.h @@ -20,7 +20,7 @@ public: virtual QString commandname() const { return "loadfile"; } signals: - void result( const Tomahawk::result_ptr result ); + void result( const Tomahawk::result_ptr& result ); private: QString m_id; diff --git a/src/libtomahawk/database/databasecommand_loadplaylistentries.cpp b/src/libtomahawk/database/databasecommand_loadplaylistentries.cpp index 05fc5cd11..1f6a9a155 100644 --- a/src/libtomahawk/database/databasecommand_loadplaylistentries.cpp +++ b/src/libtomahawk/database/databasecommand_loadplaylistentries.cpp @@ -56,14 +56,8 @@ void DatabaseCommand_LoadPlaylistEntries::generateEntries( DatabaseImpl* dbi ) e->setLastmodified( 0 ); // TODO e->lastmodified = query.value(6).toInt(); e->setResultHint( query.value( 8 ).toString() ); - QVariantMap m; - m.insert( "artist", query.value( 2 ).toString() ); - m.insert( "album", query.value( 3 ).toString() ); - m.insert( "track", query.value( 1 ).toString() ); - m.insert( "resulthint", query.value( 8 ).toString() ); - m.insert( "qid", uuid() ); - - Tomahawk::query_ptr q = Tomahawk::Query::get( m, false ); + Tomahawk::query_ptr q = Tomahawk::Query::get( query.value( 2 ).toString(), query.value( 1 ).toString(), query.value( 3 ).toString(), false ); + q->setResultHint( query.value( 8 ).toString() ); e->setQuery( q ); m_entrymap.insert( e->guid(), e ); diff --git a/src/libtomahawk/database/databasecommand_logplayback.cpp b/src/libtomahawk/database/databasecommand_logplayback.cpp index 283291d23..e08f071d5 100644 --- a/src/libtomahawk/database/databasecommand_logplayback.cpp +++ b/src/libtomahawk/database/databasecommand_logplayback.cpp @@ -26,11 +26,7 @@ DatabaseCommand_LogPlayback::postCommitHook() connect( this, SIGNAL( trackPlayed( Tomahawk::query_ptr ) ), source().data(), SLOT( onPlaybackFinished( Tomahawk::query_ptr ) ), Qt::QueuedConnection ); - QVariantMap m; - m.insert( "track", m_track ); - m.insert( "artist", m_artist ); - m.insert( "qid", uuid() ); - Tomahawk::query_ptr q = Tomahawk::Query::get( m ); + Tomahawk::query_ptr q = Tomahawk::Query::get( m_artist, m_track, QString(), uuid() ); if ( m_action == Finished ) { diff --git a/src/libtomahawk/database/databasecommand_playbackhistory.cpp b/src/libtomahawk/database/databasecommand_playbackhistory.cpp index e7f7b8979..d3356b841 100644 --- a/src/libtomahawk/database/databasecommand_playbackhistory.cpp +++ b/src/libtomahawk/database/databasecommand_playbackhistory.cpp @@ -44,12 +44,7 @@ DatabaseCommand_PlaybackHistory::exec( DatabaseImpl* dbi ) if ( query_track.next() ) { - QVariantMap m; - m.insert( "track", query_track.value( 0 ).toString() ); - m.insert( "artist", query_track.value( 1 ).toString() ); - m.insert( "qid", uuid() ); - - Tomahawk::query_ptr q = Tomahawk::Query::get( m ); + Tomahawk::query_ptr q = Tomahawk::Query::get( query_track.value( 1 ).toString(), query_track.value( 0 ).toString(), QString(), uuid() ); ql << q; } } diff --git a/src/libtomahawk/database/databasecommand_resolve.cpp b/src/libtomahawk/database/databasecommand_resolve.cpp index 2cc5d6cb4..8dcb3937c 100644 --- a/src/libtomahawk/database/databasecommand_resolve.cpp +++ b/src/libtomahawk/database/databasecommand_resolve.cpp @@ -8,9 +8,9 @@ using namespace Tomahawk; -DatabaseCommand_Resolve::DatabaseCommand_Resolve( const QVariant& v ) +DatabaseCommand_Resolve::DatabaseCommand_Resolve( const query_ptr& query ) : DatabaseCommand() - , m_v( v ) + , m_query( query ) { } @@ -18,39 +18,16 @@ DatabaseCommand_Resolve::DatabaseCommand_Resolve( const QVariant& v ) void DatabaseCommand_Resolve::exec( DatabaseImpl* lib ) { - const QMap map = m_v.toMap(); - - const Tomahawk::QID qid = map.value( "qid" ).toString(); - const QString artistname = map.value( "artist" ).toString(); - const QString albumname = map.value( "album" ).toString(); - const QString trackname = map.value( "track" ).toString(); - const QString resulthint = map.value( "resulthint" ).toString(); - - collection_ptr coll; QList res; - if ( !resulthint.isEmpty() ) + if ( !m_query->resultHint().isEmpty() ) { - qDebug() << "Using result-hint to speed up resolving:" << resulthint; + qDebug() << "Using result-hint to speed up resolving:" << m_query->resultHint(); - QVariantMap m = lib->result( resulthint ); - if ( !m.isEmpty() ) + Tomahawk::result_ptr result = lib->result( m_query->resultHint() ); + if ( !result.isNull() ) { - if ( m.value( "srcid" ).toUInt() > 0 ) - { - source_ptr s = SourceList::instance()->get( m.value( "srcid" ).toUInt() ); - if ( !s.isNull() ) - coll = s->collection(); - } - else - coll = SourceList::instance()->getLocal()->collection(); - - if ( !coll.isNull() ) - { - res << Tomahawk::result_ptr( new Tomahawk::Result( m, coll ) ); - emit results( qid, res ); - - return; - } + emit results( m_query->id(), res ); + return; } } @@ -64,14 +41,14 @@ DatabaseCommand_Resolve::exec( DatabaseImpl* lib ) typedef QPair scorepair_t; // STEP 1 - QList< int > artists = lib->searchTable( "artist", artistname, 10 ); - QList< int > tracks = lib->searchTable( "track", trackname, 10 ); - QList< int > albums = lib->searchTable( "album", albumname, 10 ); + QList< int > artists = lib->searchTable( "artist", m_query->artist(), 10 ); + QList< int > tracks = lib->searchTable( "track", m_query->track(), 10 ); + QList< int > albums = lib->searchTable( "album", m_query->album(), 10 ); if( artists.length() == 0 || tracks.length() == 0 ) { - //qDebug() << "No candidates found in first pass, aborting resolve" << artistname << trackname; - emit results( qid, res ); + qDebug() << "No candidates found in first pass, aborting resolve" << m_query->artist() << m_query->track(); + emit results( m_query->id(), res ); return; } @@ -109,73 +86,68 @@ DatabaseCommand_Resolve::exec( DatabaseImpl* lib ) while( files_query.next() ) { - QVariantMap m; - - m["mtime"] = files_query.value( 1 ).toString(); - m["size"] = files_query.value( 2 ).toInt(); - m["hash"] = files_query.value( 3 ).toString(); - m["mimetype"] = files_query.value( 4 ).toString(); - m["duration"] = files_query.value( 5 ).toInt(); - m["bitrate"] = files_query.value( 6 ).toInt(); - m["artist"] = files_query.value( 10 ).toString(); - m["artistid"] = files_query.value( 15 ).toUInt(); - m["album"] = files_query.value( 11 ).toString(); - m["albumid"] = files_query.value( 16 ).toUInt(); - m["track"] = files_query.value( 12 ).toString(); - m["srcid"] = files_query.value( 13 ).toInt(); - m["albumpos"] = files_query.value( 14 ).toUInt(); - m["sid"] = uuid(); - + Tomahawk::result_ptr result( new Tomahawk::Result() ); source_ptr s; + const QString url_str = files_query.value( 0 ).toString(); if( files_query.value( 13 ).toUInt() == 0 ) { s = SourceList::instance()->getLocal(); - m["url"] = url_str; - m["source"] = "Local Database"; // TODO + result->setUrl( url_str ); } else { s = SourceList::instance()->get( files_query.value( 13 ).toUInt() ); if( s.isNull() ) { - qDebug() << "Skipping result for offline sourceid:" << files_query.value( 13 ).toUInt(); - // will happen for valid sources which are offline (and thus not in the sourcelist) + Q_ASSERT( false ); continue; } - m.insert( "url", QString( "servent://%1\t%2" ).arg( s->userName() ).arg( url_str ) ); - m.insert( "source", s->friendlyName() ); + result->setUrl( QString( "servent://%1\t%2" ).arg( s->userName() ).arg( url_str ) ); } - float score = how_similar( m_v.toMap(), m ); - //qDebug() << "Score calc:" << timer.elapsed() << "ms"; + Tomahawk::artist_ptr artist = Tomahawk::Artist::get( files_query.value( 15 ).toUInt(), files_query.value( 10 ).toString(), s->collection() ); + Tomahawk::album_ptr album = Tomahawk::Album::get( files_query.value( 16 ).toUInt(), files_query.value( 11 ).toString(), artist, s->collection() ); - m["score"] = score; + result->setModificationTime( files_query.value( 1 ).toUInt() ); + result->setSize( files_query.value( 2 ).toUInt() ); + result->setMimetype( files_query.value( 4 ).toString() ); + result->setDuration( files_query.value( 5 ).toUInt() ); + result->setBitrate( files_query.value( 6 ).toUInt() ); + result->setArtist( artist ); + result->setAlbum( album ); + result->setTrack( files_query.value( 12 ).toString() ); + result->setRID( uuid() ); + result->setAlbumPos( files_query.value( 14 ).toUInt() ); + result->setId( files_query.value( 9 ).toUInt() ); + + float score = how_similar( m_query, result ); + result->setScore( score ); if( score < MINSCORE ) continue; - coll = s->collection(); - res << Tomahawk::result_ptr( new Tomahawk::Result( m, coll ) ); + result->setCollection( s->collection() ); + res << result; } - emit results( qid, res ); + emit results( m_query->id(), res ); } // TODO make clever (ft. featuring live (stuff) etc) float -DatabaseCommand_Resolve::how_similar( const QVariantMap& q, const QVariantMap& r ) +DatabaseCommand_Resolve::how_similar( const Tomahawk::query_ptr& q, const Tomahawk::result_ptr& r ) { // query values - const QString qArtistname = DatabaseImpl::sortname( q.value( "artist" ).toString() ); - const QString qAlbumname = DatabaseImpl::sortname( q.value( "album" ).toString() ); - const QString qTrackname = DatabaseImpl::sortname( q.value( "track" ).toString() ); + const QString qArtistname = DatabaseImpl::sortname( q->artist() ); + const QString qAlbumname = DatabaseImpl::sortname( q->album() ); + const QString qTrackname = DatabaseImpl::sortname( q->track() ); // result values - const QString rArtistname = DatabaseImpl::sortname( r.value( "artist" ).toString() ); - const QString rAlbumname = DatabaseImpl::sortname( r.value( "album" ).toString() ); - const QString rTrackname = DatabaseImpl::sortname( r.value( "track" ).toString() ); + const QString rArtistname = DatabaseImpl::sortname( r->artist()->name() ); + const QString rAlbumname = DatabaseImpl::sortname( r->album()->name() ); + const QString rTrackname = DatabaseImpl::sortname( r->track() ); // normal edit distance int artdist = levenshtein( qArtistname, rArtistname ); diff --git a/src/libtomahawk/database/databasecommand_resolve.h b/src/libtomahawk/database/databasecommand_resolve.h index e62ce076a..d09ad70af 100644 --- a/src/libtomahawk/database/databasecommand_resolve.h +++ b/src/libtomahawk/database/databasecommand_resolve.h @@ -13,7 +13,7 @@ class DLLEXPORT DatabaseCommand_Resolve : public DatabaseCommand { Q_OBJECT public: - explicit DatabaseCommand_Resolve( const QVariant& v ); + explicit DatabaseCommand_Resolve( const Tomahawk::query_ptr& query ); virtual QString commandname() const { return "dbresolve"; } virtual bool doesMutates() const { return false; } @@ -26,9 +26,9 @@ signals: public slots: private: - QVariant m_v; + Tomahawk::query_ptr m_query; - float how_similar( const QVariantMap& q, const QVariantMap& r ); + float how_similar( const Tomahawk::query_ptr& q, const Tomahawk::result_ptr& r ); static int levenshtein( const QString& source, const QString& target ); }; diff --git a/src/libtomahawk/database/databaseimpl.cpp b/src/libtomahawk/database/databaseimpl.cpp index 5652dfae8..6199b2b1a 100644 --- a/src/libtomahawk/database/databaseimpl.cpp +++ b/src/libtomahawk/database/databaseimpl.cpp @@ -9,6 +9,9 @@ #include "database/database.h" #include "databasecommand_updatesearchindex.h" #include "sourcelist.h" +#include "result.h" +#include "artist.h" +#include "album.h" /* !!!! You need to manually generate schema.sql.h when the schema changes: cd src/libtomahawk/database @@ -18,6 +21,7 @@ #define CURRENT_SCHEMA_VERSION 21 + DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) : QObject( (QObject*) parent ) , m_lastartid( 0 ) @@ -152,39 +156,59 @@ DatabaseImpl::updateSchema( int currentver ) } -QVariantMap +Tomahawk::result_ptr DatabaseImpl::file( int fid ) { - QVariantMap m; + Tomahawk::result_ptr r = Tomahawk::result_ptr( new Tomahawk::Result() ); TomahawkSqlQuery query = newquery(); query.exec( QString( "SELECT url, mtime, size, md5, mimetype, duration, bitrate, " "file_join.artist, file_join.album, file_join.track, " "(select name from artist where id = file_join.artist) as artname, " "(select name from album where id = file_join.album) as albname, " - "(select name from track where id = file_join.track) as trkname " + "(select name from track where id = file_join.track) as trkname, " + "source " "FROM file, file_join " "WHERE file.id = file_join.file AND file.id = %1" ) .arg( fid ) ); if( query.next() ) { - m["url"] = query.value( 0 ).toString(); - m["mtime"] = query.value( 1 ).toString(); - m["size"] = query.value( 2 ).toInt(); - m["hash"] = query.value( 3 ).toString(); - m["mimetype"] = query.value( 4 ).toString(); - m["duration"] = query.value( 5 ).toInt(); - m["bitrate"] = query.value( 6 ).toInt(); - m["artistid"] = query.value( 7 ).toInt(); - m["albumid"] = query.value( 8 ).toInt(); - m["trackid"] = query.value( 9 ).toInt(); - m["artist"] = query.value( 10 ).toString(); - m["album"] = query.value( 11 ).toString(); - m["track"] = query.value( 12 ).toString(); + Tomahawk::source_ptr s; + + const QString url_str = query.value( 0 ).toString(); + if ( query.value( 13 ).toUInt() == 0 ) + { + s = SourceList::instance()->getLocal(); + } + else + { + s = SourceList::instance()->get( query.value( 13 ).toUInt() ); + if ( s.isNull() ) + { + return r; + } + + r->setUrl( QString( "servent://%1\t%2" ).arg( s->userName() ).arg( url_str ) ); + } + + Tomahawk::artist_ptr artist = Tomahawk::Artist::get( query.value( 7 ).toUInt(), query.value( 10 ).toString(), s->collection() ); + Tomahawk::album_ptr album = Tomahawk::Album::get( query.value( 8 ).toUInt(), query.value( 11 ).toString(), artist, s->collection() ); + + r->setUrl( query.value( 0 ).toString() ); + r->setModificationTime( query.value( 1 ).toUInt() ); + r->setSize( query.value( 2 ).toUInt() ); + r->setMimetype( query.value( 4 ).toString() ); + r->setDuration( query.value( 5 ).toUInt() ); + r->setBitrate( query.value( 6 ).toUInt() ); + r->setArtist( artist ); + r->setAlbum( album ); + r->setTrack( query.value( 12 ).toString() ); + r->setId( query.value( 9 ).toUInt() ); + r->setCollection( s->collection() ); + r->setScore( 1.0 ); } - //qDebug() << m; - return m; + return r; } @@ -430,12 +454,12 @@ DatabaseImpl::album( int id ) } -QVariantMap +Tomahawk::result_ptr DatabaseImpl::result( const QString& url ) { TomahawkSqlQuery query = newquery(); Tomahawk::source_ptr s; - QVariantMap m; + Tomahawk::result_ptr res; QString fileUrl; if ( url.contains( "servent://" ) ) @@ -445,7 +469,7 @@ DatabaseImpl::result( const QString& url ) fileUrl = parts.at( 1 ); if ( s.isNull() ) - return m; + return res; } else if ( url.contains( "file://" ) ) { @@ -482,43 +506,40 @@ DatabaseImpl::result( const QString& url ) if( query.next() ) { + Tomahawk::source_ptr s; + const QString url_str = query.value( 0 ).toString(); - if( searchlocal ) + if ( query.value( 13 ).toUInt() == 0 ) { - m["url"] = url_str; - m["source"] = "Local Database"; // TODO + s = SourceList::instance()->getLocal(); } else { - Tomahawk::source_ptr s; s = SourceList::instance()->get( query.value( 13 ).toUInt() ); - if( s.isNull() ) + if ( s.isNull() ) { - //qDebug() << "Skipping result for offline sourceid:" << files_query.value( 13 ).toUInt(); - // will happen for valid sources which are offline (and thus not in the sourcelist) - return m; + return res; } - - m.insert( "url", QString( "servent://%1\t%2" ).arg( s->userName() ).arg( url_str ) ); - m.insert( "source", s->friendlyName() ); + + res->setUrl( QString( "servent://%1\t%2" ).arg( s->userName() ).arg( url_str ) ); } - - m["mtime"] = query.value( 1 ).toString(); - m["size"] = query.value( 2 ).toInt(); - m["hash"] = query.value( 3 ).toString(); - m["mimetype"] = query.value( 4 ).toString(); - m["duration"] = query.value( 5 ).toInt(); - m["bitrate"] = query.value( 6 ).toInt(); - m["artist"] = query.value( 10 ).toString(); - m["artistid"] = query.value( 15 ).toUInt(); - m["album"] = query.value( 11 ).toString(); - m["albumid"] = query.value( 16 ).toUInt(); - m["track"] = query.value( 12 ).toString(); - m["srcid"] = query.value( 13 ).toInt(); - m["albumpos"] = query.value( 14 ).toUInt(); - m["sid"] = uuid(); - m["score"] = 1.0; + + Tomahawk::artist_ptr artist = Tomahawk::Artist::get( query.value( 15 ).toUInt(), query.value( 10 ).toString(), s->collection() ); + Tomahawk::album_ptr album = Tomahawk::Album::get( query.value( 16 ).toUInt(), query.value( 11 ).toString(), artist, s->collection() ); + + res->setModificationTime( query.value( 1 ).toUInt() ); + res->setSize( query.value( 2 ).toUInt() ); + res->setMimetype( query.value( 4 ).toString() ); + res->setDuration( query.value( 5 ).toInt() ); + res->setBitrate( query.value( 6 ).toInt() ); + res->setArtist( artist ); + res->setAlbum( album ); + res->setScore( 1.0 ); + res->setTrack( query.value( 12 ).toString() ); + res->setAlbumPos( query.value( 14 ).toUInt() ); + res->setRID( uuid() ); + res->setId( query.value( 9 ).toUInt() ); } - return m; + return res; } diff --git a/src/libtomahawk/database/databaseimpl.h b/src/libtomahawk/database/databaseimpl.h index ab3cc319e..4f00ad5de 100644 --- a/src/libtomahawk/database/databaseimpl.h +++ b/src/libtomahawk/database/databaseimpl.h @@ -15,6 +15,7 @@ #include "tomahawksqlquery.h" #include "fuzzyindex.h" +#include "typedefs.h" class Database; @@ -44,8 +45,8 @@ public: QVariantMap artist( int id ); QVariantMap album( int id ); QVariantMap track( int id ); - QVariantMap file( int fid ); - QVariantMap result( const QString& url ); + Tomahawk::result_ptr file( int fid ); + Tomahawk::result_ptr result( const QString& url ); static bool scorepairSorter( const QPair& left, const QPair& right ) { diff --git a/src/libtomahawk/database/databaseresolver.cpp b/src/libtomahawk/database/databaseresolver.cpp index a58204a2a..799803176 100644 --- a/src/libtomahawk/database/databaseresolver.cpp +++ b/src/libtomahawk/database/databaseresolver.cpp @@ -4,6 +4,7 @@ #include "database/database.h" #include "database/databasecommand_resolve.h" + DatabaseResolver::DatabaseResolver( int weight ) : Resolver() , m_weight( weight ) @@ -12,14 +13,12 @@ DatabaseResolver::DatabaseResolver( int weight ) void -DatabaseResolver::resolve( const QVariant& v ) +DatabaseResolver::resolve( const Tomahawk::query_ptr& query ) { - //qDebug() << Q_FUNC_INFO << v; + DatabaseCommand_Resolve* cmd = new DatabaseCommand_Resolve( query ); - DatabaseCommand_Resolve* cmd = new DatabaseCommand_Resolve( v ); - - connect( cmd, SIGNAL( results( Tomahawk::QID, QList< Tomahawk::result_ptr> ) ), - SLOT( gotResults( Tomahawk::QID, QList< Tomahawk::result_ptr> ) ), Qt::QueuedConnection ); + connect( cmd, SIGNAL( results( Tomahawk::QID, QList< Tomahawk::result_ptr > ) ), + SLOT( gotResults( Tomahawk::QID, QList< Tomahawk::result_ptr > ) ), Qt::QueuedConnection ); Database::instance()->enqueue( QSharedPointer( cmd ) ); diff --git a/src/libtomahawk/database/databaseresolver.h b/src/libtomahawk/database/databaseresolver.h index 81bfca9d4..ff929efad 100644 --- a/src/libtomahawk/database/databaseresolver.h +++ b/src/libtomahawk/database/databaseresolver.h @@ -20,7 +20,7 @@ public: virtual unsigned int preference() const { return 100; } virtual unsigned int timeout() const { return 1000; } - virtual void resolve( const QVariant& v ); + virtual void resolve( const Tomahawk::query_ptr& query ); private slots: void gotResults( const Tomahawk::QID qid, QList< Tomahawk::result_ptr> results ); diff --git a/src/libtomahawk/network/servent.cpp b/src/libtomahawk/network/servent.cpp index 44525742b..1c3fae85f 100644 --- a/src/libtomahawk/network/servent.cpp +++ b/src/libtomahawk/network/servent.cpp @@ -711,7 +711,7 @@ Servent::triggerDBSync() if ( src.isNull() || src->isLocal() ) continue; - if ( src->controlConnection() ) // source online? + if ( src->controlConnection() && src->controlConnection()->dbSyncConnection() ) // source online? src->controlConnection()->dbSyncConnection()->trigger(); } } diff --git a/src/libtomahawk/pipeline.cpp b/src/libtomahawk/pipeline.cpp index 1e3e83d9a..fa42cda84 100644 --- a/src/libtomahawk/pipeline.cpp +++ b/src/libtomahawk/pipeline.cpp @@ -133,7 +133,7 @@ Pipeline::resolve( QID qid, bool prioritized ) void Pipeline::reportResults( QID qid, const QList< result_ptr >& results ) { - unsigned int state = 0; + int state = 0; { QMutexLocker lock( &m_mut ); @@ -154,9 +154,15 @@ Pipeline::reportResults( QID qid, const QList< result_ptr >& results ) state = m_qidsState.value( qid ) - 1; if ( state ) + { + qDebug() << Q_FUNC_INFO << "replacing" << qid << state; m_qidsState.insert( qid, state ); + } else + { + qDebug() << Q_FUNC_INFO << "removing" << qid << state; m_qidsState.remove( qid ); + } if ( !results.isEmpty() ) { @@ -252,9 +258,21 @@ Pipeline::shunt( const query_ptr& q ) // resolvers aren't allowed to block in this call: //qDebug() << "Dispaching to resolver" << r->name(); - unsigned int state = m_qidsState.value( q->id() ); - m_qidsState.insert( q->id(), state + 1 ); - r->resolve( q->toVariant() ); + { + QMutexLocker lock( &m_mut ); + int state = 0; + qDebug() << "Checking qidsstate:" << q->id(); + + if ( m_qidsState.contains( q->id() ) ) + { + state = m_qidsState.value( q->id() ); + } + + qDebug() << Q_FUNC_INFO << "inserting to qidsstate:" << q->id() << state + 1; + m_qidsState.insert( q->id(), state + 1 ); + } + + r->resolve( q ); } else break; diff --git a/src/libtomahawk/playlist.cpp b/src/libtomahawk/playlist.cpp index f3b92f5fe..b6d3bcb3a 100644 --- a/src/libtomahawk/playlist.cpp +++ b/src/libtomahawk/playlist.cpp @@ -22,14 +22,25 @@ PlaylistEntry::~PlaylistEntry() {} void PlaylistEntry::setQueryVariant( const QVariant& v ) { - m_query = Tomahawk::Query::get( v, false ); + QVariantMap m = v.toMap(); + + QString artist = m.value( "artist" ).toString(); + QString album = m.value( "album" ).toString(); + QString track = m.value( "track" ).toString(); + m_query = Tomahawk::Query::get( artist, track, album, false ); } QVariant PlaylistEntry::queryVariant() const { - return m_query->toVariant(); + QVariantMap m; + + m[ "artist" ] = m_query->artist(); + m[ "album" ] = m_query->album(); + m[ "track" ] = m_query->track(); + + return m; } diff --git a/src/libtomahawk/playlist/collectionflatmodel.cpp b/src/libtomahawk/playlist/collectionflatmodel.cpp index 6e63feeba..bfaa3d259 100644 --- a/src/libtomahawk/playlist/collectionflatmodel.cpp +++ b/src/libtomahawk/playlist/collectionflatmodel.cpp @@ -57,9 +57,9 @@ CollectionFlatModel::addCollection( const collection_ptr& collection ) onTracksAdded( collection->tracks(), collection ); connect( collection.data(), SIGNAL( tracksAdded( QList, Tomahawk::collection_ptr ) ), - SLOT( onTracksAdded( QList, Tomahawk::collection_ptr ) ) ); + SLOT( onTracksAdded( QList, Tomahawk::collection_ptr ) ) ); connect( collection.data(), SIGNAL( tracksFinished( Tomahawk::collection_ptr ) ), - SLOT( onTracksAddingFinished( Tomahawk::collection_ptr ) ) ); + SLOT( onTracksAddingFinished( Tomahawk::collection_ptr ) ) ); if ( collection->source()->isLocal() ) setTitle( tr( "Your Collection" ) ); diff --git a/src/libtomahawk/playlist/collectionmodel.cpp b/src/libtomahawk/playlist/collectionmodel.cpp index 212f60c79..5aaf21d57 100644 --- a/src/libtomahawk/playlist/collectionmodel.cpp +++ b/src/libtomahawk/playlist/collectionmodel.cpp @@ -166,18 +166,18 @@ CollectionModel::addCollection( const collection_ptr& collection ) emit loadingStarts(); - connect( collection.data(), SIGNAL( tracksAdded( QList, Tomahawk::collection_ptr ) ), - SLOT( onTracksAdded( QList, Tomahawk::collection_ptr ) ) ); + connect( collection.data(), SIGNAL( tracksAdded( QList, Tomahawk::collection_ptr ) ), + SLOT( onTracksAdded( QList, Tomahawk::collection_ptr ) ) ); connect( collection.data(), SIGNAL( tracksFinished( Tomahawk::collection_ptr ) ), - SLOT( onTracksAddingFinished( Tomahawk::collection_ptr ) ) ); + SLOT( onTracksAddingFinished( Tomahawk::collection_ptr ) ) ); } void CollectionModel::removeCollection( const collection_ptr& collection ) { - disconnect( collection.data(), SIGNAL( tracksAdded( QList, Tomahawk::collection_ptr ) ), - this, SLOT( onTracksAdded( QList, Tomahawk::collection_ptr ) ) ); + disconnect( collection.data(), SIGNAL( tracksAdded( QList, Tomahawk::collection_ptr ) ), + this, SLOT( onTracksAdded( QList, Tomahawk::collection_ptr ) ) ); disconnect( collection.data(), SIGNAL( tracksFinished( Tomahawk::collection_ptr ) ), this, SLOT( onTracksAddingFinished( Tomahawk::collection_ptr ) ) ); @@ -188,24 +188,13 @@ CollectionModel::removeCollection( const collection_ptr& collection ) void -CollectionModel::onTracksAdded( const QList& tracks, const collection_ptr& collection ) +CollectionModel::onTracksAdded( const QList& tracks, const collection_ptr& collection ) { // int c = rowCount( QModelIndex() ); PlItem* plitem; - foreach( const QVariant& v, tracks ) + foreach( const Tomahawk::query_ptr& query, tracks ) { - Tomahawk::query_ptr query = Tomahawk::Query::get( v, false ); - - // FIXME: needs merging - // Manually add a result, since it's coming from the local collection - QVariantMap t = query->toVariant().toMap(); - t["score"] = 1.0; - QList results; - result_ptr result = result_ptr( new Result( t, collection ) ); - results << result; - query->addResults( results ); - PlItem* parent = m_rootItem; if ( parent->hash.contains( query->artist() ) ) { diff --git a/src/libtomahawk/playlist/collectionmodel.h b/src/libtomahawk/playlist/collectionmodel.h index 3fdcad115..31f1ab779 100644 --- a/src/libtomahawk/playlist/collectionmodel.h +++ b/src/libtomahawk/playlist/collectionmodel.h @@ -55,7 +55,7 @@ signals: void trackCountChanged( unsigned int tracks ); private slots: - void onTracksAdded( const QList& tracks, const Tomahawk::collection_ptr& collection ); + void onTracksAdded( const QList& tracks, const Tomahawk::collection_ptr& collection ); void onTracksAddingFinished( const Tomahawk::collection_ptr& collection ); void onSourceOffline( Tomahawk::source_ptr src ); diff --git a/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp b/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp index f80c9132f..3f55f924b 100644 --- a/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp +++ b/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp @@ -284,11 +284,8 @@ EchonestGenerator::appendRadioType( Echonest::DynamicPlaylist::PlaylistParams& p query_ptr EchonestGenerator::queryFromSong(const Echonest::Song& song) { - QVariantMap track; - track[ "artist" ] = song.artistName(); // track[ "album" ] = song.release(); // TODO should we include it? can be quite specific - track[ "track" ] = song.title(); - return Query::get( track ); + return Query::get( song.artistName(), song.title(), QString() ); } QWidget* diff --git a/src/libtomahawk/query.cpp b/src/libtomahawk/query.cpp index 7e53c9f9d..d9407bc08 100644 --- a/src/libtomahawk/query.cpp +++ b/src/libtomahawk/query.cpp @@ -4,6 +4,9 @@ #include #include "database/database.h" +#include "database/databasecommand_logplayback.h" +#include "database/databasecommand_playbackhistory.h" +#include "database/databasecommand_loadplaylistentries.h" #include "pipeline.h" #include "sourcelist.h" @@ -11,30 +14,27 @@ using namespace Tomahawk; query_ptr -Query::get( const QVariant& v, bool autoResolve ) +Query::get( const QString& artist, const QString& track, const QString& album, const QID& qid ) { - query_ptr q = query_ptr( new Query( v, autoResolve ) ); + query_ptr q = query_ptr( new Query( artist, track, album, qid ) ); - if ( autoResolve ) + if ( !qid.isEmpty() ) Pipeline::instance()->resolve( q ); return q; } -Query::Query( const QVariant& v, bool autoResolve ) - : m_v( v ) - , m_solved( false ) +Query::Query( const QString& artist, const QString& track, const QString& album, const QID& qid ) + : m_solved( false ) + , m_artist( artist ) + , m_album( album ) + , m_track( track ) + , m_duration( -1 ) { - QVariantMap m = m_v.toMap(); - - m_artist = m.value( "artist" ).toString(); - m_album = m.value( "album" ).toString(); - m_track = m.value( "track" ).toString(); - - m_qid = m.value( "qid" ).toString(); - - if ( autoResolve ) + if ( !qid.isEmpty() ) + { connect( Database::instance(), SIGNAL( indexReady() ), SLOT( refreshResults() ), Qt::QueuedConnection ); + } } @@ -119,12 +119,8 @@ Query::id() const if ( m_qid.isEmpty() ) { m_qid = uuid(); - - QVariantMap m = m_v.toMap(); - m.insert( "qid", m_qid ); - - m_v = m; } + return m_qid; } diff --git a/src/libtomahawk/query.h b/src/libtomahawk/query.h index bfd712ba0..fa8641dbe 100644 --- a/src/libtomahawk/query.h +++ b/src/libtomahawk/query.h @@ -11,6 +11,10 @@ #include "dllmacro.h" +class DatabaseCommand_LogPlayback; +class DatabaseCommand_PlaybackHistory; +class DatabaseCommand_LoadPlaylistEntries; + namespace Tomahawk { @@ -18,11 +22,13 @@ class DLLEXPORT Query : public QObject { Q_OBJECT -public: - static query_ptr get( const QVariant& v, bool autoResolve = true ); - explicit Query( const QVariant& v, bool autoResolve ); +friend class ::DatabaseCommand_LogPlayback; +friend class ::DatabaseCommand_PlaybackHistory; +friend class ::DatabaseCommand_LoadPlaylistEntries; - QVariant toVariant() const { return m_v; } +public: + static query_ptr get( const QString& artist, const QString& track, const QString& album, const QID& qid = QString() ); + explicit Query( const QString& artist, const QString& track, const QString& album, const QID& qid ); /// returns list of all results so far QList< result_ptr > results() const; @@ -41,16 +47,25 @@ public: unsigned int lastPipelineWeight() const { return m_lastpipelineweight; } void setLastPipelineWeight( unsigned int w ) { m_lastpipelineweight = w; } + void setArtist( const QString& artist ) { m_artist = artist; } + void setAlbum( const QString& album ) { m_album = album; } + void setTrack( const QString& track ) { m_track = track; } + void setResultHint( const QString& resultHint ) { m_resultHint = resultHint; } + void setDuration( int duration ) { m_duration = duration; } +// void setQID( const QString& qid ) { m_qid = qid; } + /// for debug output: QString toString() const { return QString( "Query(%1, %2 - %3)" ).arg( id() ).arg( artist() ).arg( track() ); } + QString resultHint() const { return m_resultHint; } QString artist() const { return m_artist; } QString album() const { return m_album; } QString track() const { return m_track; } - + int duration() const { return m_duration; } + signals: void resultsAdded( const QList& ); void resultsRemoved( const Tomahawk::result_ptr& ); @@ -75,15 +90,18 @@ private: void checkResults(); mutable QMutex m_mut; - mutable QVariant m_v; QList< Tomahawk::result_ptr > m_results; bool m_solved; mutable QID m_qid; unsigned int m_lastpipelineweight; + int m_duration; + QString m_artist; QString m_album; QString m_track; + + QString m_resultHint; }; }; //ns diff --git a/src/libtomahawk/resolver.h b/src/libtomahawk/resolver.h index da898d6b2..d69be45d0 100644 --- a/src/libtomahawk/resolver.h +++ b/src/libtomahawk/resolver.h @@ -30,7 +30,7 @@ public: virtual unsigned int weight() const = 0; virtual unsigned int preference() const { return 100; }; virtual unsigned int timeout() const = 0; - virtual void resolve( const QVariant& ) = 0; + virtual void resolve( const Tomahawk::query_ptr& query ) = 0; //virtual QWidget * configUI() { return 0; }; //etc diff --git a/src/libtomahawk/result.cpp b/src/libtomahawk/result.cpp index 658d7681f..b4284e513 100644 --- a/src/libtomahawk/result.cpp +++ b/src/libtomahawk/result.cpp @@ -2,39 +2,18 @@ #include "album.h" #include "collection.h" +#include "database/databasecommand_resolve.h" +#include "database/databasecommand_alltracks.h" +#include "database/databasecommand_addfiles.h" +#include "database/databasecommand_loadfile.h" using namespace Tomahawk; -Result::Result() {} -Result::Result( const QVariant& v, const collection_ptr& collection ) +Result::Result() : QObject() - , m_v( v ) - , m_collection( collection ) + , m_year( 0 ) { - QVariantMap m = m_v.toMap(); - - m_artist = Artist::get( m.value( "artistid" ).toUInt(), m.value( "artist" ).toString(), collection ); - m_album = Album::get( m.value( "albumid" ).toUInt(), m.value( "album" ).toString(), m_artist, collection ); - m_track = m.value( "track" ).toString(); - m_url = m.value( "url" ).toString(); - m_mimetype = m.value( "mimetype" ).toString(); - - m_duration = m.value( "duration" ).toUInt(); - m_bitrate = m.value( "bitrate" ).toUInt(); - m_size = m.value( "size" ).toUInt(); - m_albumpos = m.value( "albumpos" ).toUInt(); - m_modtime = m.value( "mtime" ).toUInt(); - m_score = m.value( "score" ).toFloat(); - m_year = 0; - - m_id = m.value( "id" ).toUInt(); - - if ( !m_collection.isNull() ) - { - connect( m_collection->source().data(), SIGNAL( online() ), SLOT( onOnline() ), Qt::QueuedConnection ); - connect( m_collection->source().data(), SIGNAL( offline() ), SLOT( onOffline() ), Qt::QueuedConnection ); - } } @@ -97,7 +76,7 @@ Result::toString() const Tomahawk::query_ptr Result::toQuery() const { - Tomahawk::query_ptr query = Tomahawk::Query::get( toVariant(), false ); + Tomahawk::query_ptr query = Tomahawk::Query::get( artist()->name(), track(), album()->name() ); return query; } @@ -126,3 +105,26 @@ Result::onOffline() // qDebug() << Q_FUNC_INFO << toString(); emit statusChanged(); } + + +void +Result::setArtist( const Tomahawk::artist_ptr& artist ) +{ + m_artist = artist; +} + + +void +Result::setAlbum( const Tomahawk::album_ptr& album ) +{ + m_album = album; +} + + +void +Result::setCollection( const Tomahawk::collection_ptr& collection ) +{ + m_collection = collection; + connect( m_collection->source().data(), SIGNAL( online() ), SLOT( onOnline() ), Qt::QueuedConnection ); + connect( m_collection->source().data(), SIGNAL( offline() ), SLOT( onOffline() ), Qt::QueuedConnection ); +} diff --git a/src/libtomahawk/result.h b/src/libtomahawk/result.h index 3bc9d02f4..d62090c8e 100644 --- a/src/libtomahawk/result.h +++ b/src/libtomahawk/result.h @@ -10,6 +10,11 @@ #include "dllmacro.h" +class DatabaseCommand_Resolve; +class DatabaseCommand_AllTracks; +class DatabaseCommand_AddFiles; +class DatabaseCommand_LoadFile; + namespace Tomahawk { @@ -17,9 +22,13 @@ class DLLEXPORT Result : public QObject { Q_OBJECT +friend class ::DatabaseCommand_Resolve; +friend class ::DatabaseCommand_AllTracks; +friend class ::DatabaseCommand_AddFiles; +friend class ::DatabaseCommand_LoadFile; + public: - Result(); - explicit Result( const QVariant& v, const collection_ptr& collection ); + explicit Result(); virtual ~Result(); QVariant toVariant() const { return m_v; } @@ -42,6 +51,21 @@ public: unsigned int modificationTime() const { return m_modtime; } int year() const { return m_year; } + void setScore( float score ) { m_score = score; } + void setId( unsigned int id ) { m_id = id; } + void setRID( RID id ) { m_rid = id; } + void setCollection( const Tomahawk::collection_ptr& collection ); + void setArtist( const Tomahawk::artist_ptr& artist ); + void setAlbum( const Tomahawk::album_ptr& album ); + void setTrack( const QString& track ) { m_track = track; } + void setUrl( const QString& url ) { m_url = url; } + void setMimetype( const QString& mimetype ) { m_mimetype = mimetype; } + void setDuration( unsigned int duration ) { m_duration = duration; } + void setBitrate( unsigned int bitrate ) { m_bitrate = bitrate; } + void setSize( unsigned int size ) { m_size = size; } + void setAlbumPos( unsigned int albumpos ) { m_albumpos = albumpos; } + void setModificationTime( unsigned int modtime ) { m_modtime = modtime; } + QVariantMap attributes() const { return m_attributes; } void setAttributes( const QVariantMap& map ) { m_attributes = map; updateAttributes(); } diff --git a/src/libtomahawk/sourcelist.cpp b/src/libtomahawk/sourcelist.cpp index 45a2c74ce..490b26c5d 100644 --- a/src/libtomahawk/sourcelist.cpp +++ b/src/libtomahawk/sourcelist.cpp @@ -95,6 +95,7 @@ SourceList::add( const source_ptr& source ) collection_ptr coll( new RemoteCollection( source ) ); source->addCollection( coll ); + source->collection()->tracks(); emit sourceAdded( source ); } diff --git a/src/libtomahawk/utils/xspfloader.cpp b/src/libtomahawk/utils/xspfloader.cpp index f8125c945..9b68b342c 100644 --- a/src/libtomahawk/utils/xspfloader.cpp +++ b/src/libtomahawk/utils/xspfloader.cpp @@ -99,13 +99,13 @@ XSPFLoader::gotBody() p->setLastmodified( 0 ); p->setAnnotation( e.firstChildElement( "annotation" ).text() ); - QVariantMap v; - v.insert( "duration", e.firstChildElement( "duration" ).text().toInt() / 1000 ); - v.insert( "artist", e.firstChildElement( "creator" ).text() ); - v.insert( "album", e.firstChildElement( "album" ).text() ); - v.insert( "track", e.firstChildElement( "title" ).text() ); + QString artist, album, track; + artist = e.firstChildElement( "creator" ).text(); + album = e.firstChildElement( "album" ).text(); + track = e.firstChildElement( "title" ).text(); - p->setQuery( Tomahawk::Query::get( v ) ); + p->setQuery( Tomahawk::Query::get( artist, track, album ) ); + p->query()->setDuration( e.firstChildElement( "duration" ).text().toInt() / 1000 ); m_entries << p; } diff --git a/src/scriptresolver.cpp b/src/scriptresolver.cpp index bb74f13ef..dddf75a89 100644 --- a/src/scriptresolver.cpp +++ b/src/scriptresolver.cpp @@ -101,7 +101,8 @@ void ScriptResolver::handleMsg( const QByteArray& msg ) foreach( const QVariant& rv, reslist ) { qDebug() << "RES" << rv; - Tomahawk::result_ptr rp( new Tomahawk::Result( rv, coll ) ); + Tomahawk::result_ptr rp( new Tomahawk::Result() ); + rp->setCollection( coll ); results << rp; } Tomahawk::Pipeline::instance()->reportResults( qid, results ); @@ -128,13 +129,12 @@ void ScriptResolver::cmdExited(int code, QProcess::ExitStatus status) } -void ScriptResolver::resolve( const QVariant& v ) +void ScriptResolver::resolve( const Tomahawk::query_ptr& query ) { - QVariantMap m = v.toMap(); - m.insert( "_msgtype", "rq" ); +/* m.insert( "_msgtype", "rq" ); const QByteArray msg = m_serializer.serialize( m ); qDebug() << "ASKING SCRIPT RESOLVER TO RESOLVE:" << msg; - sendMsg( msg ); + sendMsg( msg );*/ } diff --git a/src/scriptresolver.h b/src/scriptresolver.h index 8d83e3656..bf7ae163a 100644 --- a/src/scriptresolver.h +++ b/src/scriptresolver.h @@ -8,6 +8,7 @@ #include #include "resolver.h" +#include "query.h" #include "result.h" class ScriptResolver : public Tomahawk::Resolver @@ -22,7 +23,7 @@ public: virtual unsigned int preference() const { return m_preference; } virtual unsigned int timeout() const { return m_timeout; } - virtual void resolve( const QVariant& v ); + virtual void resolve( const Tomahawk::query_ptr& query ); QString exe() const { return m_cmd; } signals: diff --git a/src/web/api_v1.h b/src/web/api_v1.h index daaacc4fb..1991e7cc2 100644 --- a/src/web/api_v1.h +++ b/src/web/api_v1.h @@ -33,8 +33,8 @@ Q_OBJECT public: - Api_v1(QxtAbstractWebSessionManager * sm, QObject * parent = 0 ) - : QxtWebSlotService(sm, parent) + Api_v1( QxtAbstractWebSessionManager* sm, QObject* parent = 0 ) + : QxtWebSlotService( sm, parent ) { } @@ -42,21 +42,28 @@ public slots: // authenticating uses /auth_1 // we redirect to /auth_2 for the callback - void auth_1( QxtWebRequestEvent* event ) { + void auth_1( QxtWebRequestEvent* event ) + { qDebug() << "AUTH_1 HTTP" << event->url.toString(); - if( !event->url.hasQueryItem( "website" ) || !event->url.hasQueryItem( "name" ) ) { + if ( !event->url.hasQueryItem( "website" ) || !event->url.hasQueryItem( "name" ) ) + { qDebug() << "Malformed HTTP resolve request"; send404( event ); } QString formToken = uuid(); - if( event->url.hasQueryItem( "json" ) ) { // JSON response + if ( event->url.hasQueryItem( "json" ) ) + { + // JSON response QVariantMap m; m[ "formtoken" ] = formToken; sendJSON( m, event ); - } else { // webpage request + } + else + { + // webpage request QString authPage = RESPATH "www/auth.html"; QHash< QString, QString > args; if( event->url.hasQueryItem( "receiverurl" ) ) @@ -68,13 +75,14 @@ public slots: } } - void auth_2( QxtWebRequestEvent* event ) { - + void auth_2( QxtWebRequestEvent* event ) + { qDebug() << "AUTH_2 HTTP" << event->url.toString(); QUrl url = event->url; url.setEncodedQuery( event->content->readAll() ); - if( !url.hasQueryItem( "website" ) || !url.hasQueryItem( "name" ) || !url.hasQueryItem( "formtoken" ) ) { + if( !url.hasQueryItem( "website" ) || !url.hasQueryItem( "name" ) || !url.hasQueryItem( "formtoken" ) ) + { qDebug() << "Malformed HTTP resolve request"; qDebug() << url.hasQueryItem( "website" ) << url.hasQueryItem( "name" ) << url.hasQueryItem( "formtoken" ); send404( event ); @@ -85,14 +93,19 @@ public slots: QString name = QUrl::fromPercentEncoding( url.queryItemValue( "name" ).toUtf8() ); QByteArray authtoken = uuid().toLatin1(); qDebug() << "HEADERS:" << event->headers; - if( !url.hasQueryItem( "receiverurl" ) && url.queryItemValue( "receiverurl" ).isEmpty() ) { //no receiver url, so do it ourselves + if( !url.hasQueryItem( "receiverurl" ) && url.queryItemValue( "receiverurl" ).isEmpty() ) + { + //no receiver url, so do it ourselves QString receiverUrl = QUrl::fromPercentEncoding( url.queryItemValue( "receiverurl" ).toUtf8() ); - if( url.hasQueryItem( "json" ) ) { + if( url.hasQueryItem( "json" ) ) + { QVariantMap m; m[ "authtoken" ] = authtoken; sendJSON( m, event ); - } else { + } + else + { QString authPage = RESPATH "www/auth.na.html"; QHash< QString, QString > args; args[ "authcode" ] = authPage; @@ -100,7 +113,10 @@ public slots: args[ "name" ] = QUrl::fromPercentEncoding( url.queryItemValue( "name" ).toUtf8() ); sendWebpageWithArgs( event, authPage, args ); } - } else { // do what the client wants + } + else + { + // do what the client wants QUrl receiverurl = QUrl( url.queryItemValue( "receiverurl" ).toUtf8(), QUrl::TolerantMode ); receiverurl.addEncodedQueryItem( "authtoken", "#" + authtoken ); qDebug() << "Got receiver url:" << receiverurl.toString(); @@ -115,7 +131,7 @@ public slots: } // all v1 api calls go to /api/ - void api(QxtWebRequestEvent* event) + void api( QxtWebRequestEvent* event ) { qDebug() << "HTTP" << event->url.toString(); @@ -124,42 +140,44 @@ public slots: { const QString method = url.queryItemValue( "method" ); - if( method == "stat" ) return stat(event); - if( method == "resolve" ) return resolve(event); - if( method == "get_results" ) return get_results(event); + if( method == "stat" ) return stat( event ); + if( method == "resolve" ) return resolve( event ); + if( method == "get_results" ) return get_results( event ); } send404( event ); } // request for stream: /sid/ - void sid(QxtWebRequestEvent* event, QString unused = "") + void sid( QxtWebRequestEvent* event, QString unused = "" ) { using namespace Tomahawk; - RID rid = event->url.path().mid(5); + RID rid = event->url.path().mid( 5 ); qDebug() << "Request for sid " << rid; + result_ptr rp = Pipeline::instance()->result( rid ); if( rp.isNull() ) { return send404( event ); } + QSharedPointer iodev = Servent::instance()->getIODeviceForUrl( rp ); if( iodev.isNull() ) { return send404( event ); // 503? } + QxtWebPageEvent* e = new QxtWebPageEvent( event->sessionID, event->requestID, iodev ); e->streaming = iodev->isSequential(); e->contentType = rp->mimetype().toAscii(); e->headers.insert("Content-Length", QString::number( rp->size() ) ); - postEvent(e); - return; + postEvent( e ); } void send404( QxtWebRequestEvent* event ) { qDebug() << "404" << event->url.toString(); - QxtWebPageEvent* wpe = new QxtWebPageEvent(event->sessionID, event->requestID, "

Not Found

"); + QxtWebPageEvent* wpe = new QxtWebPageEvent( event->sessionID, event->requestID, "

Not Found

" ); wpe->status = 404; wpe->statusMessage = "not feventound"; postEvent( wpe ); @@ -169,19 +187,25 @@ public slots: { qDebug() << "Got Stat request:" << event->url.toString(); m_storedEvent = event; + if( !event->content.isNull() ) qDebug() << "BODY:" << event->content->readAll(); - if( event->url.hasQueryItem( "auth" ) ) { // check for auth status + + if( event->url.hasQueryItem( "auth" ) ) + { + // check for auth status DatabaseCommand_ClientAuthValid* dbcmd = new DatabaseCommand_ClientAuthValid( event->url.queryItemValue( "auth" ), this ); connect( dbcmd, SIGNAL( authValid( QString, QString, bool ) ), this, SLOT( statResult( QString, QString, bool ) ) ); Database::instance()->enqueue( QSharedPointer(dbcmd) ); - - } else { + } + else + { statResult( QString(), QString(), false ); } } - void statResult( const QString& clientToken, const QString& name, bool valid ) { + void statResult( const QString& clientToken, const QString& name, bool valid ) + { QVariantMap m; m.insert( "name", "playdar" ); m.insert( "version", "0.1.1" ); // TODO (needs to be >=0.1.1 for JS to work) @@ -194,31 +218,30 @@ public slots: void resolve( QxtWebRequestEvent* event ) { - if( !event->url.hasQueryItem("artist") || - !event->url.hasQueryItem("track") ) + if( !event->url.hasQueryItem( "artist" ) || + !event->url.hasQueryItem( "track" ) ) { qDebug() << "Malformed HTTP resolve request"; send404(event); } + QString qid; - if( event->url.hasQueryItem("qid") ) qid = event->url.queryItemValue("qid"); - else qid = uuid(); + if( event->url.hasQueryItem( "qid" ) ) + qid = event->url.queryItemValue( "qid" ); + else + qid = uuid(); - QVariantMap m; - m.insert( "artist", event->url.queryItemValue("artist") ); - m.insert( "album", event->url.queryItemValue("album") ); - m.insert( "track", event->url.queryItemValue("track") ); - m.insert( "qid", qid ); - - Tomahawk::query_ptr qry = Tomahawk::Query::get( m ); + Tomahawk::query_ptr qry = Tomahawk::Query::get( event->url.queryItemValue( "artist" ), event->url.queryItemValue( "track" ), event->url.queryItemValue( "album" ), qid ); QVariantMap r; r.insert( "qid", qid ); sendJSON( r, event ); } - void staticdata( QxtWebRequestEvent* event ) { - if( event->url.path().contains( "playdar_auth_logo.gif" ) ) { + void staticdata( QxtWebRequestEvent* event ) + { + if( event->url.path().contains( "playdar_auth_logo.gif" ) ) + { // TODO handle } } @@ -245,7 +268,12 @@ public slots: r.insert( "refresh_interval", 1000 ); r.insert( "poll_limit", 6 ); r.insert( "solved", qry->solved() ); - r.insert( "query", qry->toVariant() ); + + QVariantMap m; + m[ "artist" ] = qry->artist(); + m[ "album" ] = qry->album(); + m[ "track" ] = qry->track(); + r.insert( "query", m ); QVariantList res; foreach( Tomahawk::result_ptr rp, qry->results() ) { @@ -261,6 +289,7 @@ public slots: QJson::Serializer ser; QByteArray ctype; QByteArray body = ser.serialize( m ); + if( event->url.hasQueryItem("jsonp") && !event->url.queryItemValue( "jsonp" ).isEmpty() ) { ctype = "text/javascript; charset=utf-8"; @@ -271,6 +300,7 @@ public slots: { ctype = "appplication/json; charset=utf-8"; } + QxtWebPageEvent * e = new QxtWebPageEvent( event->sessionID, event->requestID, body ); e->contentType = ctype; e->headers.insert( "Content-Length", QString::number( body.length() ) ); @@ -280,7 +310,8 @@ public slots: // load an html template from a file, replace args from map // then serve - void sendWebpageWithArgs( QxtWebRequestEvent* event, const QString& filenameSource, const QHash< QString, QString >& args ) { + void sendWebpageWithArgs( QxtWebRequestEvent* event, const QString& filenameSource, const QHash< QString, QString >& args ) + { if( !QFile::exists( filenameSource ) ) qWarning() << "Passed invalid file for html source:" << filenameSource; @@ -288,7 +319,8 @@ public slots: f.open( QIODevice::ReadOnly ); QByteArray html = f.readAll(); - foreach( const QString& param, args.keys() ) { + foreach( const QString& param, args.keys() ) + { html.replace( QString( "<%%1%>" ).arg( param.toUpper() ), args.value( param ).toUtf8() ); } @@ -296,11 +328,9 @@ public slots: postEvent( e ); } - void index(QxtWebRequestEvent* event) + void index( QxtWebRequestEvent* event ) { send404( event ); - return; - } private: diff --git a/src/xmppbot/xmppbot.cpp b/src/xmppbot/xmppbot.cpp index ccb7cc40c..579aab92a 100644 --- a/src/xmppbot/xmppbot.cpp +++ b/src/xmppbot/xmppbot.cpp @@ -141,10 +141,7 @@ void XMPPBot::handleMessage(const Message& msg, MessageSession* session) if ( tokens.count() < 2 ) AudioEngine::instance()->play(); - QVariantMap qv; - qv["artist"] = tokens.first().trimmed(); - qv["track"] = tokens.last().trimmed(); - Tomahawk::query_ptr q = Tomahawk::Query::get( qv ); + Tomahawk::query_ptr q = Tomahawk::Query::get( tokens.first().trimmed(), tokens.last().trimmed(), QString() ); connect( q.data(), SIGNAL( resultsAdded( QList ) ), SLOT( onResultsAdded( QList ) ) );