File indexing completed on 2024-05-19 04:50:19
0001 /**************************************************************************************** 0002 * Copyright (c) 2006,2007 Nikolaj Hald Nielsen <nhn@kde.org> * 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 "MagnatuneStore.h" 0018 0019 #include "core/support/Amarok.h" 0020 #include "core/support/Components.h" 0021 #include "core/logger/Logger.h" 0022 #include "amarokurls/AmarokUrlHandler.h" 0023 #include "browsers/CollectionTreeItem.h" 0024 #include "browsers/CollectionTreeView.h" 0025 #include "browsers/SingleCollectionTreeItemModel.h" 0026 #include "EngineController.h" 0027 #include "MagnatuneConfig.h" 0028 #include "MagnatuneDatabaseWorker.h" 0029 #include "MagnatuneInfoParser.h" 0030 #include "MagnatuneNeedUpdateWidget.h" 0031 #include "browsers/InfoProxy.h" 0032 #include "MagnatuneUrlRunner.h" 0033 0034 #include "ui_MagnatuneSignupDialogBase.h" 0035 0036 #include "../ServiceSqlRegistry.h" 0037 #include "core-impl/collections/support/CollectionManager.h" 0038 #include "core/support/Debug.h" 0039 #include "playlist/PlaylistModelStack.h" 0040 #include "widgets/SearchWidget.h" 0041 0042 #include <QAction> 0043 #include <QDateTime> 0044 #include <QMenu> 0045 #include <QStandardPaths> 0046 #include <QTemporaryFile> 0047 #include <QToolBar> 0048 #include <QToolButton> 0049 #include <QUrl> 0050 0051 #include <KSharedConfig> 0052 #include <ThreadWeaver/ThreadWeaver> 0053 #include <ThreadWeaver/Queue> 0054 0055 0056 //////////////////////////////////////////////////////////////////////////////////////////////////////////// 0057 // class MagnatuneServiceFactory 0058 //////////////////////////////////////////////////////////////////////////////////////////////////////////// 0059 0060 MagnatuneServiceFactory::MagnatuneServiceFactory() 0061 : ServiceFactory() 0062 { 0063 } 0064 0065 void MagnatuneServiceFactory::init() 0066 { 0067 DEBUG_BLOCK 0068 MagnatuneStore* service = new MagnatuneStore( this, "Magnatune.com" ); 0069 m_initialized = true; 0070 Q_EMIT newService( service ); 0071 } 0072 0073 QString MagnatuneServiceFactory::name() 0074 { 0075 return "Magnatune.com"; 0076 } 0077 0078 KConfigGroup MagnatuneServiceFactory::config() 0079 { 0080 return Amarok::config( "Service_Magnatune" ); 0081 } 0082 0083 //////////////////////////////////////////////////////////////////////////////////////////////////////////// 0084 // class MagnatuneStore 0085 //////////////////////////////////////////////////////////////////////////////////////////////////////////// 0086 0087 MagnatuneStore::MagnatuneStore( MagnatuneServiceFactory* parent, const char *name ) 0088 : ServiceBase( name, parent ) 0089 , m_downloadHandler( nullptr ) 0090 , m_redownloadHandler( nullptr ) 0091 , m_needUpdateWidget( nullptr ) 0092 , m_downloadInProgress( 0 ) 0093 , m_currentAlbum( nullptr ) 0094 , m_streamType( MagnatuneMetaFactory::OGG ) 0095 , m_magnatuneTimestamp( 0 ) 0096 , m_registry( nullptr ) 0097 , m_signupInfoWidget( nullptr ) 0098 { 0099 DEBUG_BLOCK 0100 setObjectName(name); 0101 //initTopPanel( ); 0102 0103 setShortDescription( i18n( "\"Fair trade\" online music store" ) ); 0104 setIcon( QIcon::fromTheme( "view-services-magnatune-amarok" ) ); 0105 0106 // xgettext: no-c-format 0107 setLongDescription( i18n( "Magnatune.com is a different kind of record company with the motto \"We are not evil!\" 50% of every purchase goes directly to the artist and if you purchase an album through Amarok, the Amarok project receives a 10% commission. Magnatune.com also offers \"all you can eat\" memberships that lets you download as much of their music as you like." ) ); 0108 setImagePath( QStandardPaths::locate( QStandardPaths::GenericDataLocation, "amarok/images/hover_info_magnatune.png" ) ); 0109 0110 0111 //initBottomPanel(); 0112 // m_currentlySelectedItem = 0; 0113 0114 m_polished = false; 0115 //polish( ); //FIXME not happening when shown for some reason 0116 0117 0118 //do this stuff now to make us function properly as a track provider on startup. The expensive stuff will 0119 //not happen until the model is added to the view anyway. 0120 MagnatuneMetaFactory * metaFactory = new MagnatuneMetaFactory( "magnatune", this ); 0121 0122 MagnatuneConfig config; 0123 if ( config.isMember() ) { 0124 setMembership( config.membershipType(), config.username(), config.password() ); 0125 metaFactory->setMembershipInfo( config.membershipPrefix(), m_username, m_password ); 0126 } 0127 0128 setStreamType( config.streamType() ); 0129 0130 metaFactory->setStreamType( m_streamType ); 0131 m_registry = new ServiceSqlRegistry( metaFactory ); 0132 m_collection = new Collections::MagnatuneSqlCollection( "magnatune", "Magnatune.com", metaFactory, m_registry ); 0133 CollectionManager::instance()->addTrackProvider( m_collection ); 0134 setServiceReady( true ); 0135 } 0136 0137 MagnatuneStore::~MagnatuneStore() 0138 { 0139 CollectionManager::instance()->removeTrackProvider( m_collection ); 0140 delete m_registry; 0141 delete m_collection; 0142 } 0143 0144 0145 void MagnatuneStore::download( ) 0146 { 0147 DEBUG_BLOCK 0148 if ( m_downloadInProgress ) 0149 return; 0150 0151 if ( !m_polished ) 0152 polish(); 0153 0154 debug() << "here"; 0155 0156 //check if we need to start a download or show the signup dialog 0157 if( !m_isMember || m_membershipType != MagnatuneConfig::DOWNLOAD ) 0158 { 0159 showSignupDialog(); 0160 return; 0161 } 0162 0163 m_downloadInProgress = true; 0164 m_downloadAlbumButton->setEnabled( false ); 0165 0166 if ( !m_downloadHandler ) 0167 { 0168 m_downloadHandler = new MagnatuneDownloadHandler(); 0169 m_downloadHandler->setParent( this ); 0170 connect( m_downloadHandler, &MagnatuneDownloadHandler::downloadCompleted, 0171 this, &MagnatuneStore::downloadCompleted ); 0172 } 0173 0174 if ( m_currentAlbum != nullptr ) 0175 m_downloadHandler->downloadAlbum( m_currentAlbum ); 0176 } 0177 0178 0179 void MagnatuneStore::downloadTrack( Meta::MagnatuneTrack * track ) 0180 { 0181 Meta::MagnatuneAlbum * album = dynamic_cast<Meta::MagnatuneAlbum *>( track->album().data() ); 0182 if ( album ) 0183 downloadAlbum( album ); 0184 } 0185 0186 void MagnatuneStore::downloadAlbum( Meta::MagnatuneAlbum * album ) 0187 { 0188 DEBUG_BLOCK 0189 if ( m_downloadInProgress ) 0190 return; 0191 0192 if ( !m_polished ) 0193 polish(); 0194 0195 m_downloadInProgress = true; 0196 m_downloadAlbumButton->setEnabled( false ); 0197 0198 if ( !m_downloadHandler ) 0199 { 0200 m_downloadHandler = new MagnatuneDownloadHandler(); 0201 m_downloadHandler->setParent( this ); 0202 connect( m_downloadHandler, &MagnatuneDownloadHandler::downloadCompleted, 0203 this, &MagnatuneStore::downloadCompleted ); 0204 } 0205 0206 m_downloadHandler->downloadAlbum( album ); 0207 } 0208 0209 0210 void MagnatuneStore::initTopPanel( ) 0211 { 0212 QMenu *filterMenu = new QMenu( nullptr ); 0213 0214 QAction *action = filterMenu->addAction( i18n("Artist") ); 0215 connect( action, &QAction::triggered, this, &MagnatuneStore::sortByArtist ); 0216 0217 action = filterMenu->addAction( i18n( "Artist / Album" ) ); 0218 connect( action, &QAction::triggered, this, &MagnatuneStore::sortByArtistAlbum ); 0219 0220 action = filterMenu->addAction( i18n( "Album" ) ) ; 0221 connect( action, &QAction::triggered, this, &MagnatuneStore::sortByAlbum ); 0222 0223 action = filterMenu->addAction( i18n( "Genre / Artist" ) ); 0224 connect( action, &QAction::triggered, this, &MagnatuneStore::sortByGenreArtist ); 0225 0226 action = filterMenu->addAction( i18n( "Genre / Artist / Album" ) ); 0227 connect( action, &QAction::triggered, this, &MagnatuneStore::sortByGenreArtistAlbum ); 0228 0229 QAction *filterMenuAction = new QAction( QIcon::fromTheme( "preferences-other" ), i18n( "Sort Options" ), this ); 0230 filterMenuAction->setMenu( filterMenu ); 0231 0232 m_searchWidget->toolBar()->addSeparator(); 0233 m_searchWidget->toolBar()->addAction( filterMenuAction ); 0234 0235 QToolButton *tbutton = qobject_cast<QToolButton*>( m_searchWidget->toolBar()->widgetForAction( filterMenuAction ) ); 0236 if( tbutton ) 0237 tbutton->setPopupMode( QToolButton::InstantPopup ); 0238 0239 QMenu * actionsMenu = new QMenu( nullptr ); 0240 0241 action = actionsMenu->addAction( i18n( "Re-download" ) ); 0242 connect( action, &QAction::triggered, this, &MagnatuneStore::processRedownload ); 0243 0244 m_updateAction = actionsMenu->addAction( i18n( "Update Database" ) ); 0245 connect( m_updateAction, &QAction::triggered, this, &MagnatuneStore::updateButtonClicked ); 0246 0247 QAction *actionsMenuAction = new QAction( QIcon::fromTheme( "list-add" ), i18n( "Tools" ), this ); 0248 actionsMenuAction->setMenu( actionsMenu ); 0249 0250 m_searchWidget->toolBar()->addAction( actionsMenuAction ); 0251 0252 tbutton = qobject_cast<QToolButton*>( m_searchWidget->toolBar()->widgetForAction( actionsMenuAction ) ); 0253 if( tbutton ) 0254 tbutton->setPopupMode( QToolButton::InstantPopup ); 0255 0256 } 0257 0258 void MagnatuneStore::initBottomPanel() 0259 { 0260 //m_bottomPanel->setMaximumHeight( 24 ); 0261 0262 m_downloadAlbumButton = new QPushButton; 0263 m_downloadAlbumButton->setParent( m_bottomPanel ); 0264 0265 MagnatuneConfig config; 0266 if ( config.isMember() && config.membershipType() == MagnatuneConfig::DOWNLOAD ) 0267 { 0268 m_downloadAlbumButton->setText( i18n( "Download Album" ) ); 0269 m_downloadAlbumButton->setEnabled( false ); 0270 } 0271 else if ( config.isMember() ) 0272 m_downloadAlbumButton->hide(); 0273 else 0274 { 0275 m_downloadAlbumButton->setText( i18n( "Signup" ) ); 0276 m_downloadAlbumButton->setEnabled( true ); 0277 } 0278 0279 m_downloadAlbumButton->setObjectName( "downloadButton" ); 0280 m_downloadAlbumButton->setIcon( QIcon::fromTheme( "download-amarok" ) ); 0281 0282 connect( m_downloadAlbumButton, &QPushButton::clicked, this, &MagnatuneStore::download ); 0283 0284 if ( !config.lastUpdateTimestamp() ) 0285 { 0286 m_needUpdateWidget = new MagnatuneNeedUpdateWidget(m_bottomPanel); 0287 0288 connect( m_needUpdateWidget, &MagnatuneNeedUpdateWidget::wantUpdate, 0289 this, &MagnatuneStore::updateButtonClicked ); 0290 0291 m_downloadAlbumButton->setParent(nullptr); 0292 } 0293 } 0294 0295 0296 void MagnatuneStore::updateButtonClicked() 0297 { 0298 DEBUG_BLOCK 0299 m_updateAction->setEnabled( false ); 0300 if ( m_needUpdateWidget ) 0301 m_needUpdateWidget->disable(); 0302 0303 updateMagnatuneList(); 0304 } 0305 0306 0307 bool MagnatuneStore::updateMagnatuneList() 0308 { 0309 DEBUG_BLOCK 0310 //download new list from magnatune 0311 0312 debug() << "MagnatuneStore: start downloading xml file"; 0313 0314 0315 QTemporaryFile tempFile; 0316 // tempFile.setSuffix( ".bz2" ); 0317 tempFile.setAutoRemove( false ); // file will be removed in MagnatuneXmlParser 0318 if( !tempFile.open() ) 0319 { 0320 return false; //error 0321 } 0322 0323 m_tempFileName = tempFile.fileName(); 0324 0325 m_listDownloadJob = KIO::file_copy( QUrl("http://magnatune.com/info/album_info_xml.bz2"), QUrl::fromLocalFile( m_tempFileName ), 0700 , KIO::HideProgressInfo | KIO::Overwrite ); 0326 Amarok::Logger::newProgressOperation( m_listDownloadJob, i18n( "Downloading Magnatune.com database..." ), this, &MagnatuneStore::listDownloadCancelled ); 0327 0328 connect( m_listDownloadJob, &KJob::result, 0329 this, &MagnatuneStore::listDownloadComplete ); 0330 0331 return true; 0332 } 0333 0334 0335 void MagnatuneStore::listDownloadComplete( KJob * downLoadJob ) 0336 { 0337 DEBUG_BLOCK 0338 debug() << "MagnatuneStore: xml file download complete"; 0339 0340 if ( downLoadJob != m_listDownloadJob ) { 0341 debug() << "wrong job, ignoring...."; 0342 return ; //not the right job, so let's ignore it 0343 } 0344 0345 m_updateAction->setEnabled( true ); 0346 0347 if ( downLoadJob->error() != 0 ) 0348 { 0349 debug() << "Got an error, bailing out: " << downLoadJob->errorString(); 0350 //TODO: error handling here 0351 return ; 0352 } 0353 0354 0355 Amarok::Logger::shortMessage( i18n( "Updating the local Magnatune database." ) ); 0356 MagnatuneXmlParser * parser = new MagnatuneXmlParser( m_tempFileName ); 0357 parser->setDbHandler( new MagnatuneDatabaseHandler() ); 0358 connect( parser, &MagnatuneXmlParser::doneParsing, this, &MagnatuneStore::doneParsing ); 0359 0360 ThreadWeaver::Queue::instance()->enqueue( QSharedPointer<ThreadWeaver::Job>(parser) ); 0361 } 0362 0363 0364 void MagnatuneStore::listDownloadCancelled( ) 0365 { 0366 DEBUG_BLOCK 0367 0368 m_listDownloadJob->kill(); 0369 m_listDownloadJob = nullptr; 0370 debug() << "Aborted xml download"; 0371 0372 m_updateAction->setEnabled( true ); 0373 if ( m_needUpdateWidget ) 0374 m_needUpdateWidget->enable(); 0375 } 0376 0377 0378 0379 void MagnatuneStore::doneParsing() 0380 { 0381 debug() << "MagnatuneStore: done parsing"; 0382 m_collection->emitUpdated(); 0383 0384 //update the last update timestamp 0385 0386 MagnatuneConfig config; 0387 if ( m_magnatuneTimestamp == 0 ) 0388 config.setLastUpdateTimestamp( QDateTime::currentDateTimeUtc().toSecsSinceEpoch() ); 0389 else 0390 config.setLastUpdateTimestamp( m_magnatuneTimestamp ); 0391 0392 config.save(); 0393 0394 if ( m_needUpdateWidget ) 0395 { 0396 m_needUpdateWidget->setParent(nullptr); 0397 m_needUpdateWidget->deleteLater(); 0398 m_needUpdateWidget = nullptr; 0399 0400 m_downloadAlbumButton->setParent(m_bottomPanel); 0401 } 0402 } 0403 0404 0405 void MagnatuneStore::processRedownload( ) 0406 { 0407 debug() << "Process redownload"; 0408 0409 if ( m_redownloadHandler == nullptr ) 0410 { 0411 m_redownloadHandler = new MagnatuneRedownloadHandler( this ); 0412 } 0413 m_redownloadHandler->showRedownloadDialog(); 0414 } 0415 0416 0417 void MagnatuneStore::downloadCompleted( bool ) 0418 { 0419 delete m_downloadHandler; 0420 m_downloadHandler = nullptr; 0421 0422 m_downloadAlbumButton->setEnabled( true ); 0423 m_downloadInProgress = false; 0424 0425 debug() << "Purchase operation complete"; 0426 0427 //TODO: display some kind of success dialog here? 0428 } 0429 0430 0431 void MagnatuneStore::itemSelected( CollectionTreeItem * selectedItem ) 0432 { 0433 DEBUG_BLOCK 0434 0435 //only care if the user has a download membership 0436 if( !m_isMember || m_membershipType != MagnatuneConfig::DOWNLOAD ) 0437 return; 0438 0439 //we only enable the purchase button if there is only one item selected and it happens to 0440 //be an album or a track 0441 Meta::DataPtr dataPtr = selectedItem->data(); 0442 0443 if ( auto track = AmarokSharedPointer<Meta::MagnatuneTrack>::dynamicCast( dataPtr ) ) 0444 { 0445 debug() << "is right type (track)"; 0446 m_currentAlbum = static_cast<Meta::MagnatuneAlbum *> ( track->album().data() ); 0447 m_downloadAlbumButton->setEnabled( true ); 0448 } 0449 else if ( auto album = AmarokSharedPointer<Meta::MagnatuneAlbum>::dynamicCast( dataPtr ) ) 0450 { 0451 m_currentAlbum = album.data(); 0452 debug() << "is right type (album) named " << m_currentAlbum->name(); 0453 0454 m_downloadAlbumButton->setEnabled( true ); 0455 } 0456 else 0457 { 0458 debug() << "is wrong type"; 0459 m_downloadAlbumButton->setEnabled( false ); 0460 } 0461 } 0462 0463 0464 void MagnatuneStore::addMoodyTracksToPlaylist( const QString &mood, int count ) 0465 { 0466 MagnatuneDatabaseWorker *databaseWorker = new MagnatuneDatabaseWorker(); 0467 databaseWorker->fetchTrackswithMood( mood, count, m_registry ); 0468 connect( databaseWorker, &MagnatuneDatabaseWorker::gotMoodyTracks, this, &MagnatuneStore::moodyTracksReady ); 0469 0470 ThreadWeaver::Queue::instance()->enqueue( QSharedPointer<ThreadWeaver::Job>(databaseWorker) ); 0471 } 0472 0473 0474 void MagnatuneStore::polish() 0475 { 0476 DEBUG_BLOCK; 0477 0478 if (!m_polished) { 0479 m_polished = true; 0480 0481 initTopPanel( ); 0482 initBottomPanel(); 0483 0484 QList<CategoryId::CatMenuId> levels; 0485 levels << CategoryId::Genre << CategoryId::Artist << CategoryId::Album; 0486 0487 m_magnatuneInfoParser = new MagnatuneInfoParser(); 0488 0489 setInfoParser( m_magnatuneInfoParser ); 0490 setModel( new SingleCollectionTreeItemModel( m_collection, levels ) ); 0491 0492 connect( qobject_cast<CollectionTreeView*>(m_contentView), &CollectionTreeView::itemSelected, 0493 this, &MagnatuneStore::itemSelected ); 0494 0495 //add a custom url runner 0496 MagnatuneUrlRunner *runner = new MagnatuneUrlRunner(); 0497 0498 connect( runner, &MagnatuneUrlRunner::showFavorites, this, &MagnatuneStore::showFavoritesPage ); 0499 connect( runner, &MagnatuneUrlRunner::showHome, this, &MagnatuneStore::showHomePage ); 0500 connect( runner, &MagnatuneUrlRunner::showRecommendations, this, &MagnatuneStore::showRecommendationsPage ); 0501 connect( runner, &MagnatuneUrlRunner::buyOrDownload, this, &MagnatuneStore::downloadSku ); 0502 connect( runner, &MagnatuneUrlRunner::removeFromFavorites, this, &MagnatuneStore::removeFromFavorites ); 0503 0504 The::amarokUrlHandler()->registerRunner( runner, runner->command() ); 0505 } 0506 0507 MagnatuneInfoParser * parser = dynamic_cast<MagnatuneInfoParser *> ( infoParser() ); 0508 if ( parser ) 0509 parser->getFrontPage(); 0510 0511 //get a mood map we can show to the cloud view 0512 0513 MagnatuneDatabaseWorker * databaseWorker = new MagnatuneDatabaseWorker(); 0514 databaseWorker->fetchMoodMap(); 0515 connect( databaseWorker, &MagnatuneDatabaseWorker::gotMoodMap, this, &MagnatuneStore::moodMapReady ); 0516 ThreadWeaver::Queue::instance()->enqueue( QSharedPointer<ThreadWeaver::Job>(databaseWorker) ); 0517 0518 if ( MagnatuneConfig().autoUpdateDatabase() ) 0519 checkForUpdates(); 0520 } 0521 0522 0523 0524 void MagnatuneStore::setMembership( int type, const QString & username, const QString & password) 0525 { 0526 m_isMember = true; 0527 m_membershipType = type; 0528 m_username = username; 0529 m_password = password; 0530 } 0531 0532 0533 void MagnatuneStore::moodMapReady(const QMap< QString, int > &map) 0534 { 0535 QVariantMap variantMap; 0536 QList<QVariant> strings; 0537 QList<QVariant> weights; 0538 QVariantMap dbusActions; 0539 0540 foreach( const QString &key, map.keys() ) { 0541 0542 strings << key; 0543 weights << map.value( key ); 0544 0545 QString escapedKey = key; 0546 escapedKey.replace( ' ', "%20" ); 0547 QVariantMap action; 0548 action["component"] = "/ServicePluginManager"; 0549 action["function"] = "sendMessage"; 0550 action["arg1"] = QStringLiteral( "Magnatune.com"); 0551 action["arg2"] = QStringLiteral( "addMoodyTracks %1 10").arg( escapedKey ); 0552 0553 dbusActions[key] = action; 0554 0555 } 0556 0557 variantMap["cloud_name"] = QVariant( "Magnatune Moods" ); 0558 variantMap["cloud_strings"] = QVariant( strings ); 0559 variantMap["cloud_weights"] = QVariant( weights ); 0560 variantMap["cloud_actions"] = QVariant( dbusActions ); 0561 0562 The::infoProxy()->setCloud( variantMap ); 0563 } 0564 0565 0566 void MagnatuneStore::setStreamType( int type ) 0567 { 0568 m_streamType = type; 0569 } 0570 0571 void MagnatuneStore::checkForUpdates() 0572 { 0573 m_updateTimestampDownloadJob = KIO::storedGet( QUrl("http://magnatune.com/info/last_update_timestamp"), KIO::Reload, KIO::HideProgressInfo ); 0574 connect( m_updateTimestampDownloadJob, &KJob::result, this, &MagnatuneStore::timestampDownloadComplete ); 0575 } 0576 0577 0578 void MagnatuneStore::timestampDownloadComplete( KJob * job ) 0579 { 0580 DEBUG_BLOCK 0581 0582 if ( job->error() != 0 ) 0583 { 0584 //TODO: error handling here 0585 return ; 0586 } 0587 if ( job != m_updateTimestampDownloadJob ) 0588 return ; //not the right job, so let's ignore it 0589 0590 0591 QString timestampString = ( ( KIO::StoredTransferJob* ) job )->data(); 0592 debug() << "Magnatune timestamp: " << timestampString; 0593 0594 bool ok; 0595 qulonglong magnatuneTimestamp = timestampString.toULongLong( &ok ); 0596 0597 MagnatuneConfig config; 0598 qulonglong localTimestamp = config.lastUpdateTimestamp(); 0599 0600 debug() << "Last update timestamp: " << QString::number( localTimestamp ); 0601 0602 if ( ok && magnatuneTimestamp > localTimestamp ) { 0603 m_magnatuneTimestamp = magnatuneTimestamp; 0604 updateButtonClicked(); 0605 } 0606 } 0607 0608 0609 void MagnatuneStore::moodyTracksReady( const Meta::TrackList &tracks ) 0610 { 0611 DEBUG_BLOCK 0612 The::playlistController()->insertOptioned( tracks, Playlist::Replace ); 0613 } 0614 0615 0616 QString MagnatuneStore::messages() 0617 { 0618 QString text = i18n( "The Magnatune.com service accepts the following messages: \n\n\taddMoodyTracks mood count: Adds a number of random tracks with the specified mood to the playlist. The mood argument must have spaces escaped with %%20" ); 0619 0620 return text; 0621 } 0622 0623 0624 QString MagnatuneStore::sendMessage( const QString & message ) 0625 { 0626 QStringList args = message.split( ' ', Qt::SkipEmptyParts ); 0627 0628 if ( args.size() < 1 ) { 0629 return i18n( "ERROR: No arguments supplied" ); 0630 } 0631 0632 if ( args[0] == "addMoodyTracks" ) { 0633 if ( args.size() != 3 ) { 0634 return i18n( "ERROR: Wrong number of arguments for addMoodyTracks" ); 0635 } 0636 0637 QString mood = args[1]; 0638 mood = mood.replace( "%20", " " ); 0639 0640 bool ok; 0641 int count = args[2].toInt( &ok ); 0642 0643 if ( !ok ) 0644 return i18n( "ERROR: Parse error for argument 2 ( count )" ); 0645 0646 addMoodyTracksToPlaylist( mood, count ); 0647 0648 return i18n( "ok" ); 0649 } 0650 0651 return i18n( "ERROR: Unknown argument." ); 0652 } 0653 0654 void MagnatuneStore::showFavoritesPage() 0655 { 0656 DEBUG_BLOCK 0657 m_magnatuneInfoParser->getFavoritesPage(); 0658 } 0659 0660 void MagnatuneStore::showHomePage() 0661 { 0662 DEBUG_BLOCK 0663 m_magnatuneInfoParser->getFrontPage(); 0664 } 0665 0666 void MagnatuneStore::showRecommendationsPage() 0667 { 0668 DEBUG_BLOCK 0669 m_magnatuneInfoParser->getRecommendationsPage(); 0670 } 0671 0672 void MagnatuneStore::downloadSku( const QString &sku ) 0673 { 0674 DEBUG_BLOCK 0675 debug() << "sku: " << sku; 0676 MagnatuneDatabaseWorker * databaseWorker = new MagnatuneDatabaseWorker(); 0677 databaseWorker->fetchAlbumBySku( sku, m_registry ); 0678 connect( databaseWorker, &MagnatuneDatabaseWorker::gotAlbumBySku, this, &MagnatuneStore::downloadAlbum ); 0679 0680 ThreadWeaver::Queue::instance()->enqueue( QSharedPointer<ThreadWeaver::Job>(databaseWorker) ); 0681 } 0682 0683 void MagnatuneStore::addToFavorites( const QString &sku ) 0684 { 0685 DEBUG_BLOCK 0686 MagnatuneConfig config; 0687 0688 if( !config.isMember() ) 0689 return; 0690 0691 QString url = "http://%1:%2@%3.magnatune.com/member/favorites?action=add_api&sku=%4"; 0692 url = url.arg( config.username(), config.password(), config.membershipPrefix(), sku ); 0693 0694 debug() << "favorites url: " << url; 0695 0696 m_favoritesJob = KIO::storedGet( QUrl( url ), KIO::Reload, KIO::HideProgressInfo ); 0697 connect( m_favoritesJob, &KJob::result, this, &MagnatuneStore::favoritesResult ); 0698 } 0699 0700 void MagnatuneStore::removeFromFavorites( const QString &sku ) 0701 { 0702 DEBUG_BLOCK 0703 MagnatuneConfig config; 0704 0705 if( !config.isMember() ) 0706 return; 0707 0708 QString url = "http://%1:%2@%3.magnatune.com/member/favorites?action=remove_api&sku=%4"; 0709 url = url.arg( config.username(), config.password(), config.membershipPrefix(), sku ); 0710 0711 debug() << "favorites url: " << url; 0712 0713 m_favoritesJob = KIO::storedGet( QUrl( url ), KIO::Reload, KIO::HideProgressInfo ); 0714 connect( m_favoritesJob, &KJob::result, this, &MagnatuneStore::favoritesResult ); 0715 } 0716 0717 void MagnatuneStore::favoritesResult( KJob* addToFavoritesJob ) 0718 { 0719 if( addToFavoritesJob != m_favoritesJob ) 0720 return; 0721 0722 QString result = m_favoritesJob->data(); 0723 0724 Amarok::Logger::longMessage( result ); 0725 0726 //show the favorites page 0727 showFavoritesPage(); 0728 } 0729 0730 void 0731 MagnatuneStore::showSignupDialog() 0732 { 0733 0734 if ( m_signupInfoWidget== nullptr ) 0735 { 0736 m_signupInfoWidget = new QDialog; 0737 Ui::SignupDialog ui; 0738 ui.setupUi( m_signupInfoWidget ); 0739 } 0740 0741 m_signupInfoWidget->show(); 0742 }