File indexing completed on 2024-05-19 04:50:28
0001 /**************************************************************************************** 0002 * Copyright (c) 2012 Matěj Laitl <matej@laitl.cz> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify it under * 0005 * the terms of the GNU General Public License as published by the Free Software * 0006 * Foundation; either version 2 of the License, or (at your option) any later * 0007 * version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0011 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0012 * * 0013 * You should have received a copy of the GNU General Public License along with * 0014 * this program. If not, see <http://www.gnu.org/licenses/>. * 0015 ****************************************************************************************/ 0016 0017 #include "CollectionProvider.h" 0018 0019 #include "MetaValues.h" 0020 #include "amarokconfig.h" 0021 #include "core/collections/Collection.h" 0022 #include "core/collections/QueryMaker.h" 0023 #include "core/meta/Meta.h" 0024 #include "statsyncing/collection/CollectionTrack.h" 0025 0026 using namespace StatSyncing; 0027 0028 CollectionProvider::CollectionProvider( Collections::Collection *collection ) 0029 : m_coll( collection ) 0030 { 0031 Q_ASSERT( m_coll ); 0032 connect( collection, &Collections::Collection::updated, this, &CollectionProvider::updated ); 0033 connect( this, &CollectionProvider::startArtistSearch, this, &CollectionProvider::slotStartArtistSearch ); 0034 connect( this, &CollectionProvider::startTrackSearch, this, &CollectionProvider::slotStartTrackSearch ); 0035 } 0036 0037 CollectionProvider::~CollectionProvider() 0038 { 0039 } 0040 0041 QString 0042 CollectionProvider::id() const 0043 { 0044 return m_coll ? m_coll->collectionId() : QString(); 0045 } 0046 0047 QString 0048 CollectionProvider::prettyName() const 0049 { 0050 return m_coll ? m_coll->prettyName() : QString(); 0051 } 0052 0053 QIcon 0054 CollectionProvider::icon() const 0055 { 0056 return m_coll ? m_coll->icon() : QIcon(); 0057 } 0058 0059 qint64 0060 CollectionProvider::reliableTrackMetaData() const 0061 { 0062 if( id().startsWith(QLatin1String("amarok-nepomuk:")) ) 0063 return Meta::valTitle | Meta::valArtist | Meta::valAlbum | Meta::valComposer | 0064 Meta::valTrackNr; 0065 else 0066 return Meta::valTitle | Meta::valArtist | Meta::valAlbum | 0067 Meta::valComposer | Meta::valYear | Meta::valTrackNr | Meta::valDiscNr; 0068 } 0069 0070 qint64 0071 CollectionProvider::writableTrackStatsData() const 0072 { 0073 // TODO: this is unreliable and hacky, but serves for now: 0074 if( id() == QLatin1String("localCollection") ) 0075 return Meta::valRating | Meta::valFirstPlayed | Meta::valLastPlayed | Meta::valPlaycount | Meta::valLabel; 0076 else 0077 return Meta::valRating | Meta::valFirstPlayed | Meta::valLastPlayed | Meta::valPlaycount; 0078 } 0079 0080 Provider::Preference 0081 CollectionProvider::defaultPreference() 0082 { 0083 // currently only Local Collection and iPod one have good syncing capabilities 0084 if( id() == QLatin1String("localCollection") ) 0085 return YesByDefault; 0086 if( id().startsWith( QLatin1String("amarok-ipodtrackuid") ) ) 0087 return Ask; 0088 return NoByDefault; 0089 } 0090 0091 QSet<QString> 0092 CollectionProvider::artists() 0093 { 0094 if( !m_coll ) 0095 return QSet<QString>(); 0096 0097 m_foundArtists.clear(); 0098 Q_EMIT startArtistSearch(); 0099 m_queryMakerSemaphore.acquire(); // blocks until slotQueryDone() releases the semaphore 0100 QSet<QString> ret = m_foundArtists; 0101 m_foundArtists.clear(); // don't waste memory 0102 0103 return ret; 0104 } 0105 0106 TrackList 0107 CollectionProvider::artistTracks( const QString &artistName ) 0108 { 0109 if( !m_coll ) 0110 return TrackList(); 0111 0112 m_foundTracks.clear(); 0113 Q_EMIT startTrackSearch( artistName ); 0114 m_queryMakerSemaphore.acquire(); // blocks until slotQueryDone() releases the semaphore 0115 TrackList ret = m_foundTracks; 0116 m_foundTracks.clear(); // don't waste memory 0117 m_currentArtistName.clear(); 0118 0119 return ret; 0120 } 0121 0122 void 0123 CollectionProvider::slotStartArtistSearch() 0124 { 0125 if( !m_coll ) 0126 { 0127 m_queryMakerSemaphore.release(); // prevent deadlock 0128 return; 0129 } 0130 0131 Collections::QueryMaker *qm = m_coll->queryMaker(); 0132 qm->setAutoDelete( true ); 0133 qm->setQueryType( Collections::QueryMaker::Artist ); 0134 connect( qm, &Collections::QueryMaker::newArtistsReady, 0135 this, &CollectionProvider::slotNewArtistsReady ); 0136 connect( qm, &Collections::QueryMaker::queryDone, this, &CollectionProvider::slotQueryDone ); 0137 qm->run(); 0138 } 0139 0140 void 0141 CollectionProvider::slotStartTrackSearch( const QString &artistName ) 0142 { 0143 if( !m_coll ) 0144 { 0145 m_queryMakerSemaphore.release(); // prevent deadlock 0146 return; 0147 } 0148 0149 Collections::QueryMaker *qm = m_coll->queryMaker(); 0150 qm->setAutoDelete( true ); 0151 qm->setQueryType( Collections::QueryMaker::Track ); 0152 m_currentArtistName = artistName; 0153 qm->addFilter( Meta::valArtist, m_currentArtistName, true, true ); 0154 connect( qm, &Collections::QueryMaker::newTracksReady, 0155 this, &CollectionProvider::slotNewTracksReady ); 0156 connect( qm, &Collections::QueryMaker::queryDone, this, &CollectionProvider::slotQueryDone ); 0157 qm->run(); 0158 } 0159 0160 void 0161 CollectionProvider::slotNewArtistsReady( Meta::ArtistList list ) 0162 { 0163 foreach( const Meta::ArtistPtr &artist, list ) 0164 { 0165 m_foundArtists.insert( artist->name() ); 0166 } 0167 } 0168 0169 void 0170 CollectionProvider::slotNewTracksReady( Meta::TrackList list ) 0171 { 0172 foreach( Meta::TrackPtr track, list ) 0173 { 0174 Meta::ArtistPtr artistPtr = track->artist(); 0175 QString artist = artistPtr ? artistPtr->name() : QString(); 0176 // QueryMaker interface is case-insensitive and cannot be configured otherwise. 0177 // StatSyncing::Provicer interface is case-sensitive, so we must filter here 0178 if( artist == m_currentArtistName ) 0179 m_foundTracks.append( TrackPtr( new CollectionTrack( track ) ) ); 0180 } 0181 } 0182 0183 void 0184 CollectionProvider::slotQueryDone() 0185 { 0186 m_queryMakerSemaphore.release(); // unblock method in a worker thread 0187 }