File indexing completed on 2024-05-19 04:50:11
0001 /**************************************************************************************** 0002 * Copyright (c) 2007 Nikolaj Hald Nielsen <nhn@kde.org> * 0003 * Copyright (c) 2007 Adam Pigg <adam@piggz.co.uk> * 0004 * Copyright (c) 2007 Casey Link <unnamedrambler@gmail.com> * 0005 * (c) 2013 Ralf Engels <ralf-engels@gmx.de> * 0006 * * 0007 * This program is free software; you can redistribute it and/or modify it under * 0008 * the terms of the GNU General Public License as published by the Free Software * 0009 * Foundation; either version 2 of the License, or (at your option) any later * 0010 * version. * 0011 * * 0012 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0013 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0014 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0015 * * 0016 * You should have received a copy of the GNU General Public License along with * 0017 * this program. If not, see <http://www.gnu.org/licenses/>. * 0018 ****************************************************************************************/ 0019 0020 #define DEBUG_PREFIX "AmpacheServiceQueryMaker" 0021 0022 #include "AmpacheServiceQueryMaker.h" 0023 0024 #include "AmpacheMeta.h" 0025 #include "core/meta/Statistics.h" 0026 #include "core/support/Amarok.h" 0027 #include "core/support/Debug.h" 0028 #include "core/meta/support/MetaConstants.h" 0029 #include "core-impl/collections/support/MemoryMatcher.h" 0030 0031 #include <QAtomicInt> 0032 #include <QDomDocument> 0033 #include <QSet> 0034 #include <QUrlQuery> 0035 0036 using namespace Collections; 0037 0038 struct AmpacheServiceQueryMaker::Private 0039 { 0040 AmpacheServiceCollection* collection; 0041 0042 QueryMaker::QueryType type; 0043 int maxsize; 0044 0045 QAtomicInt expectedReplies; 0046 0047 QUrl server; 0048 QString sessionId; 0049 QList<int> parentTrackIds; 0050 QList<int> parentAlbumIds; 0051 QList<int> parentArtistIds; 0052 uint dateFilter; 0053 QString artistFilter; 0054 QString albumFilter; 0055 0056 /** We are collecting the results of the queries and submit them 0057 in one block to ensure that we don't report albums twice 0058 and because the CollectionTreeItemModelBase does not handle 0059 multiple results correctly (which it should). 0060 */ 0061 Meta::AlbumList albumResults; 0062 Meta::ArtistList artistResults; 0063 Meta::TrackList trackResults; 0064 }; 0065 0066 AmpacheServiceQueryMaker::AmpacheServiceQueryMaker( AmpacheServiceCollection * collection, const QUrl &server, const QString &sessionId ) 0067 : DynamicServiceQueryMaker() 0068 , d( new Private ) 0069 { 0070 d->collection = collection; 0071 d->type = QueryMaker::None; 0072 d->maxsize = 0; 0073 d->server = server; 0074 d->sessionId = sessionId; 0075 d->dateFilter = 0; 0076 } 0077 0078 AmpacheServiceQueryMaker::~AmpacheServiceQueryMaker() 0079 { 0080 delete d; 0081 } 0082 0083 void 0084 AmpacheServiceQueryMaker::run() 0085 { 0086 DEBUG_BLOCK 0087 0088 if( d->expectedReplies ) // still running an old query 0089 return; 0090 0091 //naive implementation, fix this 0092 //note: we are not handling filtering yet 0093 0094 d->collection->acquireReadLock(); 0095 0096 if ( d->type == QueryMaker::Artist ) 0097 fetchArtists(); 0098 else if( d->type == QueryMaker::Album ) 0099 fetchAlbums(); 0100 else if( d->type == QueryMaker::Track ) 0101 fetchTracks(); 0102 else 0103 warning() << "Requested unhandled query type"; //TODO error handling 0104 0105 d->collection->releaseLock(); 0106 } 0107 0108 void 0109 AmpacheServiceQueryMaker::abortQuery() 0110 { 0111 } 0112 0113 QueryMaker * 0114 AmpacheServiceQueryMaker::setQueryType( QueryType type ) 0115 { 0116 d->type = type; 0117 0118 return this; 0119 } 0120 0121 QueryMaker* 0122 AmpacheServiceQueryMaker::addMatch( const Meta::TrackPtr &track ) 0123 { 0124 DEBUG_BLOCK 0125 0126 const Meta::AmpacheTrack* serviceTrack = dynamic_cast< const Meta::AmpacheTrack * >( track.data() ); 0127 if( serviceTrack ) 0128 { 0129 d->parentTrackIds << serviceTrack->id(); 0130 debug() << "parent id set to: " << d->parentTrackIds; 0131 } 0132 else 0133 { 0134 // searching for something from another collection 0135 //hmm, not sure what to do now 0136 } 0137 0138 return this; 0139 } 0140 0141 QueryMaker* 0142 AmpacheServiceQueryMaker::addMatch( const Meta::ArtistPtr &artist, ArtistMatchBehaviour behaviour ) 0143 { 0144 Q_UNUSED( behaviour ) // TODO 0145 DEBUG_BLOCK 0146 0147 if( d->parentAlbumIds.isEmpty() ) 0148 { 0149 const Meta::AmpacheArtist* serviceArtist = dynamic_cast< const Meta::AmpacheArtist * >( artist.data() ); 0150 if( serviceArtist ) 0151 { 0152 d->parentArtistIds << serviceArtist->id(); 0153 } 0154 else 0155 { 0156 // searching for something from another collection 0157 if( d->collection->artistMap().contains( artist->name() ) ) 0158 { 0159 serviceArtist = static_cast< const Meta::AmpacheArtist* >( d->collection->artistMap().value( artist->name() ).data() ); 0160 d->parentArtistIds << serviceArtist->id(); 0161 } 0162 else 0163 { 0164 //hmm, not sure what to do now 0165 } 0166 } 0167 } 0168 return this; 0169 } 0170 0171 QueryMaker * 0172 AmpacheServiceQueryMaker::addMatch( const Meta::AlbumPtr & album ) 0173 { 0174 DEBUG_BLOCK 0175 const Meta::AmpacheAlbum* serviceAlbum = dynamic_cast< const Meta::AmpacheAlbum * >( album.data() ); 0176 if( serviceAlbum ) 0177 { 0178 d->parentAlbumIds << serviceAlbum->ids(); 0179 debug() << "parent id set to: " << d->parentAlbumIds; 0180 d->parentArtistIds.clear(); 0181 } 0182 else 0183 { 0184 // searching for something from another collection 0185 if( d->collection->albumMap().contains( album ) ) // compares albums by value 0186 { 0187 serviceAlbum = static_cast< const Meta::AmpacheAlbum* >( d->collection->albumMap().value( album ).data() ); 0188 d->parentAlbumIds << serviceAlbum->ids(); 0189 d->parentArtistIds.clear(); 0190 } 0191 else 0192 { 0193 //hmm, not sure what to do now 0194 } 0195 } 0196 0197 return this; 0198 } 0199 0200 void 0201 AmpacheServiceQueryMaker::fetchArtists() 0202 { 0203 DEBUG_BLOCK 0204 0205 Meta::ArtistList artists; 0206 0207 // first try the cache 0208 if( !d->parentArtistIds.isEmpty() ) 0209 { 0210 for( int artistId : qAsConst(d->parentArtistIds) ) 0211 artists << d->collection->artistById( artistId ); 0212 } 0213 0214 if( !artists.isEmpty() ) 0215 { 0216 debug() << "got" << artists.count() << "artists from the memory collection"; 0217 Q_EMIT newArtistsReady( artists ); 0218 Q_EMIT queryDone(); 0219 return; 0220 } 0221 0222 QUrl request = getRequestUrl( "artists" ); 0223 QUrlQuery query( request ); 0224 0225 if ( !d->artistFilter.isEmpty() ) 0226 { 0227 query.addQueryItem( "filter", d->artistFilter ); 0228 request.setQuery( query ); 0229 } 0230 0231 d->expectedReplies.ref(); 0232 The::networkAccessManager()->getData( request, this, &AmpacheServiceQueryMaker::artistDownloadComplete ); 0233 } 0234 0235 void 0236 AmpacheServiceQueryMaker::fetchAlbums() 0237 { 0238 DEBUG_BLOCK 0239 0240 Meta::AlbumList albums; 0241 0242 // first try the cache 0243 if( !d->parentArtistIds.isEmpty() ) 0244 { 0245 foreach( int artistId, d->parentArtistIds ) 0246 albums << matchAlbums( d->collection, d->collection->artistById( artistId ) ); 0247 } 0248 if( !albums.isEmpty() ) 0249 { 0250 debug() << "got" << albums.count() << "albums from the memory collection"; 0251 Q_EMIT newAlbumsReady( albums ); 0252 Q_EMIT queryDone(); 0253 return; 0254 } 0255 0256 if( !d->parentArtistIds.isEmpty() ) 0257 { 0258 foreach( int id, d->parentArtistIds ) 0259 { 0260 QUrl request = getRequestUrl( "artist_albums" ); 0261 QUrlQuery query( request ); 0262 query.addQueryItem( "filter", QString::number( id ) ); 0263 request.setQuery( query ); 0264 0265 d->expectedReplies.ref(); 0266 The::networkAccessManager()->getData( request, this, &AmpacheServiceQueryMaker::albumDownloadComplete ); 0267 } 0268 } 0269 else 0270 { 0271 QUrl request = getRequestUrl( "albums" ); 0272 QUrlQuery query( request ); 0273 0274 if ( !d->albumFilter.isEmpty() ) 0275 { 0276 query.addQueryItem( "filter", d->albumFilter ); 0277 request.setQuery( query ); 0278 } 0279 0280 d->expectedReplies.ref(); 0281 The::networkAccessManager()->getData( request, this, &AmpacheServiceQueryMaker::albumDownloadComplete ); 0282 } 0283 } 0284 0285 void 0286 AmpacheServiceQueryMaker::fetchTracks() 0287 { 0288 DEBUG_BLOCK 0289 0290 Meta::TrackList tracks; 0291 0292 //debug() << "parent album id: " << d->parentAlbumId; 0293 0294 // first try the cache 0295 // TODO: this is fishy as we cannot be sure that the cache contains 0296 // everything 0297 // we should cache database query results instead 0298 if( !d->parentTrackIds.isEmpty() ) 0299 { 0300 foreach( int trackId, d->parentTrackIds ) 0301 { 0302 tracks << d->collection->trackById( trackId ); 0303 } 0304 } 0305 else if( !d->parentAlbumIds.isEmpty() ) 0306 { 0307 foreach( int albumId, d->parentAlbumIds ) 0308 { 0309 AlbumMatcher albumMatcher( d->collection->albumById( albumId ) ); 0310 tracks << albumMatcher.match( d->collection->trackMap().values() ); 0311 } 0312 } 0313 else if( d->parentArtistIds.isEmpty() ) 0314 { 0315 foreach( int artistId, d->parentArtistIds ) 0316 { 0317 ArtistMatcher artistMatcher( d->collection->artistById( artistId ) ); 0318 tracks << artistMatcher.match( d->collection->trackMap().values() ); 0319 } 0320 } 0321 0322 if( !tracks.isEmpty() ) 0323 { 0324 debug() << "got" << tracks.count() << "tracks from the memory collection"; 0325 Q_EMIT newTracksReady( tracks ); 0326 Q_EMIT queryDone(); 0327 return; 0328 } 0329 0330 QUrl request = getRequestUrl(); 0331 0332 0333 if( !d->parentAlbumIds.isEmpty() ) 0334 { 0335 foreach( int id, d->parentAlbumIds ) 0336 { 0337 QUrl request = getRequestUrl( "album_songs" ); 0338 QUrlQuery query( request ); 0339 query.addQueryItem( "filter", QString::number( id ) ); 0340 request.setQuery( query ); 0341 0342 d->expectedReplies.ref(); 0343 The::networkAccessManager()->getData( request, this, &AmpacheServiceQueryMaker::trackDownloadComplete ); 0344 } 0345 } 0346 else if( !d->parentArtistIds.isEmpty() ) 0347 { 0348 foreach( int id, d->parentArtistIds ) 0349 { 0350 QUrl request = getRequestUrl( "artist_songs" ); 0351 QUrlQuery query( request ); 0352 query.addQueryItem( "filter", QString::number( id ) ); 0353 request.setQuery( query ); 0354 0355 d->expectedReplies.ref(); 0356 The::networkAccessManager()->getData( request, this, &AmpacheServiceQueryMaker::trackDownloadComplete ); 0357 } 0358 } 0359 else 0360 { 0361 QUrl request = getRequestUrl( "songs" ); 0362 0363 d->expectedReplies.ref(); 0364 The::networkAccessManager()->getData( request, this, &AmpacheServiceQueryMaker::trackDownloadComplete ); 0365 } 0366 } 0367 0368 void 0369 AmpacheServiceQueryMaker::artistDownloadComplete( const QUrl &url, const QByteArray &data, const NetworkAccessManagerProxy::Error &e ) 0370 { 0371 Q_UNUSED( url ); 0372 0373 if( e.code != QNetworkReply::NoError ) 0374 { 0375 warning() << "Artist download error:" << e.description; 0376 if( !d->expectedReplies.deref() ) 0377 Q_EMIT queryDone(); 0378 return; 0379 } 0380 0381 // DEBUG_BLOCK 0382 0383 // so lets figure out what we got here: 0384 QDomDocument doc( "reply" ); 0385 doc.setContent( data ); 0386 QDomElement root = doc.firstChildElement( "root" ); 0387 0388 // Is this an error, if so we need to 'un-ready' the service and re-authenticate before continuing 0389 QDomElement domError = root.firstChildElement( "error" ); 0390 0391 if ( !domError.isNull() ) 0392 { 0393 warning() << "Error getting Artist List" << domError.text() << "Code:" << domError.attribute("code"); 0394 AmpacheService *parentService = dynamic_cast< AmpacheService * >( d->collection->service() ); 0395 if( !parentService ) 0396 return; 0397 else 0398 parentService->reauthenticate(); 0399 } 0400 0401 for( QDomNode n = root.firstChild(); !n.isNull(); n = n.nextSibling() ) 0402 { 0403 QDomElement e = n.toElement(); // try to convert the node to an element. 0404 0405 QDomElement element = n.firstChildElement( "name" ); 0406 int artistId = e.attribute( "id", "0").toInt(); 0407 0408 // check if we have the artist already 0409 Meta::ArtistPtr artistPtr = d->collection->artistById( artistId ); 0410 0411 if( !artistPtr ) 0412 { 0413 // new artist 0414 Meta::ServiceArtist* artist = new Meta::AmpacheArtist( element.text(), d->collection->service() ); 0415 artist->setId( artistId ); 0416 0417 // debug() << "Adding artist: " << element.text() << " with id: " << artistId; 0418 0419 artistPtr = artist; 0420 0421 d->collection->acquireWriteLock(); 0422 d->collection->addArtist( artistPtr ); 0423 d->collection->releaseLock(); 0424 } 0425 0426 if( !d->artistResults.contains( artistPtr ) ) 0427 d->artistResults.push_back( artistPtr ); 0428 } 0429 0430 if( !d->expectedReplies.deref() ) 0431 { 0432 Q_EMIT newArtistsReady( d->artistResults ); 0433 Q_EMIT queryDone(); 0434 d->artistResults.clear(); 0435 } 0436 } 0437 0438 void 0439 AmpacheServiceQueryMaker::albumDownloadComplete( const QUrl &url, const QByteArray &data, const NetworkAccessManagerProxy::Error &e ) 0440 { 0441 Q_UNUSED( url ); 0442 0443 if( e.code != QNetworkReply::NoError ) 0444 { 0445 warning() << "Album download error:" << e.description; 0446 if( !d->expectedReplies.deref() ) 0447 Q_EMIT queryDone(); 0448 return; 0449 } 0450 0451 // DEBUG_BLOCK 0452 0453 //so lets figure out what we got here: 0454 QDomDocument doc( "reply" ); 0455 doc.setContent( data ); 0456 QDomElement root = doc.firstChildElement( "root" ); 0457 0458 // Is this an error, if so we need to 'un-ready' the service and re-authenticate before continuing 0459 QDomElement domError = root.firstChildElement( "error" ); 0460 0461 if( !domError.isNull() ) 0462 { 0463 warning() << "Error getting Album List" << domError.text() << "Code:" << domError.attribute("code"); 0464 AmpacheService *parentService = dynamic_cast< AmpacheService * >(d->collection->service()); 0465 if( parentService == nullptr ) 0466 return; 0467 else 0468 parentService->reauthenticate(); 0469 } 0470 0471 for( QDomNode n = root.firstChild(); !n.isNull(); n = n.nextSibling() ) 0472 { 0473 QDomElement e = n.toElement(); // try to convert the node to an element. 0474 0475 // --- the album artist 0476 Meta::ArtistPtr artistPtr; 0477 QDomElement artistElement = n.firstChildElement( "artist" ); 0478 if( !artistElement.isNull() ) 0479 { 0480 int artistId = artistElement.attribute( "id", "0").toInt(); 0481 // check if we already know the artist 0482 artistPtr = d->collection->artistById( artistId ); 0483 if( !artistPtr.data() ) 0484 { 0485 // new artist. 0486 Meta::ServiceArtist* artist = new Meta::AmpacheArtist( artistElement.text(), d->collection->service() ); 0487 artistPtr = artist; 0488 0489 artist->setId( artistId ); 0490 // debug() << "Adding artist: " << artistElement.text() << " with id: " << artistId; 0491 0492 d->collection->acquireWriteLock(); 0493 d->collection->addArtist( artistPtr ); 0494 d->collection->releaseLock(); 0495 } 0496 } 0497 0498 QDomElement element = n.firstChildElement( "name" ); 0499 QString title = element.text(); 0500 0501 Meta::AmpacheAlbum::AmpacheAlbumInfo info; 0502 info.id = e.attribute( "id", "0" ).toInt(); 0503 0504 element = n.firstChildElement( "disk" ); 0505 info.discNumber = element.text().toInt(); 0506 0507 element = n.firstChildElement( "year" ); 0508 info.year = element.text().toInt(); 0509 0510 // check if we have the album already 0511 Meta::AlbumPtr albumPtr = d->collection->albumById( info.id ); 0512 0513 if( !albumPtr ) 0514 { 0515 // check if we at least have an album with the same title and artist 0516 Meta::AmpacheAlbum* album = static_cast<Meta::AmpacheAlbum*>( 0517 const_cast<Meta::Album*>( d->collection->albumMap().value( title, artistPtr ? artistPtr->name() : QString() ).data() ) ); 0518 0519 if( !album ) 0520 { 0521 // new album 0522 album = new Meta::AmpacheAlbum( title ); 0523 album->setAlbumArtist( artistPtr ); 0524 0525 // -- cover 0526 element = n.firstChildElement( "art" ); 0527 0528 QString coverUrl = element.text(); 0529 album->setCoverUrl( coverUrl ); 0530 } 0531 album->addInfo( info ); 0532 0533 // debug() << "Adding album" << title << "with id:" << info.id; 0534 0535 albumPtr = album; 0536 0537 // register a new id with the ServiceCollection 0538 album->setId( info.id ); 0539 d->collection->acquireWriteLock(); 0540 d->collection->addAlbum( albumPtr ); 0541 d->collection->releaseLock(); 0542 } 0543 0544 if( !d->albumResults.contains( albumPtr ) ) 0545 d->albumResults.push_back( albumPtr ); 0546 } 0547 0548 if( !d->expectedReplies.deref() ) 0549 { 0550 Q_EMIT newAlbumsReady( d->albumResults ); 0551 Q_EMIT queryDone(); 0552 d->albumResults.clear(); 0553 } 0554 } 0555 0556 void 0557 AmpacheServiceQueryMaker::trackDownloadComplete( const QUrl &url, const QByteArray &data, const NetworkAccessManagerProxy::Error &e ) 0558 { 0559 Q_UNUSED( url ); 0560 0561 if( e.code != QNetworkReply::NoError ) 0562 { 0563 warning() << "Track download error:" << e.description; 0564 if( !d->expectedReplies.deref() ) 0565 Q_EMIT queryDone(); 0566 return; 0567 } 0568 0569 // DEBUG_BLOCK 0570 0571 //so lets figure out what we got here: 0572 QDomDocument doc( "reply" ); 0573 doc.setContent( data ); 0574 QDomElement root = doc.firstChildElement( "root" ); 0575 0576 // Is this an error, if so we need to 'un-ready' the service and re-authenticate before continuing 0577 QDomElement domError = root.firstChildElement( "error" ); 0578 0579 if( !domError.isNull() ) 0580 { 0581 warning() << "Error getting Track Download " << domError.text() << "Code:" << domError.attribute("code"); 0582 AmpacheService *parentService = dynamic_cast< AmpacheService * >( d->collection->service() ); 0583 if( parentService == nullptr ) 0584 return; 0585 else 0586 parentService->reauthenticate(); 0587 } 0588 0589 for( QDomNode n = root.firstChild(); !n.isNull(); n = n.nextSibling() ) 0590 { 0591 QDomElement e = n.toElement(); // try to convert the node to an element. 0592 0593 int trackId = e.attribute( "id", "0" ).toInt(); 0594 Meta::TrackPtr trackPtr = d->collection->trackById( trackId ); 0595 0596 if( !trackPtr ) 0597 { 0598 // new track 0599 0600 QDomElement element = n.firstChildElement( "title" ); 0601 QString title = element.text(); 0602 Meta::AmpacheTrack * track = new Meta::AmpacheTrack( title, d->collection->service() ); 0603 trackPtr = track; 0604 0605 track->setId( trackId ); 0606 0607 element = n.firstChildElement( "url" ); 0608 track->setUidUrl( element.text() ); 0609 0610 element = n.firstChildElement( "time" ); 0611 track->setLength( element.text().toInt() * 1000 ); 0612 0613 element = n.firstChildElement( "track" ); 0614 track->setTrackNumber( element.text().toInt() ); 0615 0616 element = n.firstChildElement( "rating" ); 0617 track->statistics()->setRating( element.text().toDouble() * 2.0 ); 0618 0619 QDomElement albumElement = n.firstChildElement( "album" ); 0620 int albumId = albumElement.attribute( "id", "0").toInt(); 0621 0622 QDomElement artistElement = n.firstChildElement( "artist" ); 0623 int artistId = artistElement.attribute( "id", "0").toInt(); 0624 0625 Meta::ArtistPtr artistPtr = d->collection->artistById( artistId ); 0626 // TODO: this assumes that we query all artist before tracks 0627 if( artistPtr ) 0628 { 0629 // debug() << "Found parent artist " << artistPtr->name(); 0630 Meta::ServiceArtist *artist = dynamic_cast< Meta::ServiceArtist * > ( artistPtr.data() ); 0631 track->setArtist( artistPtr ); 0632 artist->addTrack( trackPtr ); 0633 } 0634 0635 Meta::AlbumPtr albumPtr = d->collection->albumById( albumId ); 0636 // TODO: this assumes that we query all albums before tracks 0637 if( albumPtr ) 0638 { 0639 // debug() << "Found parent album " << albumPtr->name() << albumId; 0640 Meta::AmpacheAlbum *album = dynamic_cast< Meta::AmpacheAlbum * > ( albumPtr.data() ); 0641 track->setDiscNumber( album->getInfo( albumId ).discNumber ); 0642 track->setYear( album->getInfo( albumId ).year ); 0643 track->setAlbumPtr( albumPtr ); 0644 // debug() << " parent album with"<<track->discNumber()<<track->year(); 0645 album->addTrack( trackPtr ); 0646 } 0647 0648 // debug() << "Adding track: " << title << " with id: " << trackId; 0649 0650 d->collection->acquireWriteLock(); 0651 d->collection->addTrack( trackPtr ); 0652 d->collection->releaseLock(); 0653 } 0654 0655 if( !d->trackResults.contains( trackPtr ) ) 0656 d->trackResults.push_back( trackPtr ); 0657 } 0658 0659 if( !d->expectedReplies.deref() ) 0660 { 0661 Q_EMIT newTracksReady( d->trackResults ); 0662 Q_EMIT queryDone(); 0663 d->trackResults.clear(); 0664 } 0665 } 0666 0667 QueryMaker * 0668 AmpacheServiceQueryMaker::addFilter( qint64 value, const QString & filter, bool matchBegin, bool matchEnd ) 0669 { 0670 Q_UNUSED( matchBegin ) 0671 Q_UNUSED( matchEnd ) 0672 0673 //for now, only accept artist filters 0674 // TODO: What about albumArtist? 0675 if( value == Meta::valArtist ) 0676 { 0677 d->artistFilter = filter; 0678 } 0679 else if( value == Meta::valAlbum ) 0680 { 0681 d->albumFilter = filter; 0682 } 0683 else 0684 { 0685 warning() << "unsupported filter" << Meta::nameForField( value ); 0686 } 0687 return this; 0688 } 0689 0690 QueryMaker* 0691 AmpacheServiceQueryMaker::addNumberFilter( qint64 value, qint64 filter, QueryMaker::NumberComparison compare ) 0692 { 0693 if( value == Meta::valCreateDate && compare == QueryMaker::GreaterThan ) 0694 { 0695 debug() << "asking to filter based on added date"; 0696 d->dateFilter = filter; 0697 debug() << "setting dateFilter to:" << d->dateFilter; 0698 } 0699 else 0700 { 0701 warning() << "unsupported filter" << Meta::nameForField( value ); 0702 } 0703 return this; 0704 } 0705 0706 int 0707 AmpacheServiceQueryMaker::validFilterMask() 0708 { 0709 //we only support artist and album filters for now... 0710 return ArtistFilter | AlbumFilter; 0711 } 0712 0713 QueryMaker * 0714 AmpacheServiceQueryMaker::limitMaxResultSize( int size ) 0715 { 0716 d->maxsize = size; 0717 return this; 0718 } 0719 0720 QUrl 0721 AmpacheServiceQueryMaker::getRequestUrl( const QString &action ) const 0722 { 0723 QUrl url = d->server; 0724 QString scheme = url.scheme(); 0725 0726 if( scheme != "http" && scheme != "https" ) 0727 url.setScheme( "http" ); 0728 0729 QUrlQuery query( url ); 0730 0731 url = url.adjusted( QUrl::StripTrailingSlash ); 0732 url.setPath( url.path() + "/server/xml.server.php" ); 0733 0734 query.addQueryItem( "auth", d->sessionId ); 0735 0736 if( !action.isEmpty() ) 0737 query.addQueryItem( "action", action ); 0738 0739 if( d->dateFilter > 0 ) 0740 { 0741 QDateTime from; 0742 from.setSecsSinceEpoch( d->dateFilter ); 0743 query.addQueryItem( "add", from.toString( Qt::ISODate ) ); 0744 } 0745 query.addQueryItem( "limit", QString::number( d->maxsize ) ); 0746 url.setQuery( query ); 0747 0748 return url; 0749 } 0750 0751