1 /****************************************************************************************
2 * Copyright (c) 2006,2007 Nikolaj Hald Nielsen <nhn@kde.org> *
3 * *
4 * This program is free software; you can redistribute it and/or modify it under *
5 * the terms of the GNU General Public License as published by the Free Software *
6 * Foundation; either version 2 of the License, or (at your option) any later *
7 * version. *
8 * *
9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY *
10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
11 * PARTICULAR PURPOSE. See the GNU General Public License for more details. *
12 * *
13 * You should have received a copy of the GNU General Public License along with *
14 * this program. If not, see <http://www.gnu.org/licenses/>. *
15 ****************************************************************************************/
16
17 #include "MagnatuneStore.h"
18
19 #include "core/support/Amarok.h"
20 #include "core/support/Components.h"
21 #include "core/logger/Logger.h"
22 #include "amarokurls/AmarokUrlHandler.h"
23 #include "browsers/CollectionTreeItem.h"
24 #include "browsers/CollectionTreeView.h"
25 #include "browsers/SingleCollectionTreeItemModel.h"
26 #include "EngineController.h"
27 #include "MagnatuneConfig.h"
28 #include "MagnatuneDatabaseWorker.h"
29 #include "MagnatuneInfoParser.h"
30 #include "MagnatuneNeedUpdateWidget.h"
31 #include "browsers/InfoProxy.h"
32 #include "MagnatuneUrlRunner.h"
33
34 #include "ui_MagnatuneSignupDialogBase.h"
35
36 #include "../ServiceSqlRegistry.h"
37 #include "core-impl/collections/support/CollectionManager.h"
38 #include "core/support/Debug.h"
39 #include "playlist/PlaylistModelStack.h"
40 #include "widgets/SearchWidget.h"
41
42 #include <QAction>
43 #include <QDateTime>
44 #include <QMenu>
45 #include <QStandardPaths>
46 #include <QTemporaryFile>
47 #include <QToolBar>
48 #include <QToolButton>
49 #include <QUrl>
50
51 #include <KSharedConfig>
52 #include <ThreadWeaver/ThreadWeaver>
53 #include <ThreadWeaver/Queue>
54
55
56 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
57 // class MagnatuneServiceFactory
58 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
59
MagnatuneServiceFactory()60 MagnatuneServiceFactory::MagnatuneServiceFactory()
61 : ServiceFactory()
62 {
63 }
64
init()65 void MagnatuneServiceFactory::init()
66 {
67 DEBUG_BLOCK
68 MagnatuneStore* service = new MagnatuneStore( this, "Magnatune.com" );
69 m_initialized = true;
70 Q_EMIT newService( service );
71 }
72
name()73 QString MagnatuneServiceFactory::name()
74 {
75 return "Magnatune.com";
76 }
77
config()78 KConfigGroup MagnatuneServiceFactory::config()
79 {
80 return Amarok::config( "Service_Magnatune" );
81 }
82
83 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
84 // class MagnatuneStore
85 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
86
MagnatuneStore(MagnatuneServiceFactory * parent,const char * name)87 MagnatuneStore::MagnatuneStore( MagnatuneServiceFactory* parent, const char *name )
88 : ServiceBase( name, parent )
89 , m_downloadHandler( 0 )
90 , m_redownloadHandler( 0 )
91 , m_needUpdateWidget( 0 )
92 , m_downloadInProgress( 0 )
93 , m_currentAlbum( 0 )
94 , m_streamType( MagnatuneMetaFactory::OGG )
95 , m_magnatuneTimestamp( 0 )
96 , m_registry( 0 )
97 , m_signupInfoWidget( 0 )
98 {
99 DEBUG_BLOCK
100 setObjectName(name);
101 //initTopPanel( );
102
103 setShortDescription( i18n( "\"Fair trade\" online music store" ) );
104 setIcon( QIcon::fromTheme( "view-services-magnatune-amarok" ) );
105
106 // xgettext: no-c-format
107 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." ) );
108 setImagePath( QStandardPaths::locate( QStandardPaths::GenericDataLocation, "amarok/images/hover_info_magnatune.png" ) );
109
110
111 //initBottomPanel();
112 // m_currentlySelectedItem = 0;
113
114 m_polished = false;
115 //polish( ); //FIXME not happening when shown for some reason
116
117
118 //do this stuff now to make us function properly as a track provider on startup. The expensive stuff will
119 //not happen until the model is added to the view anyway.
120 MagnatuneMetaFactory * metaFactory = new MagnatuneMetaFactory( "magnatune", this );
121
122 MagnatuneConfig config;
123 if ( config.isMember() ) {
124 setMembership( config.membershipType(), config.username(), config.password() );
125 metaFactory->setMembershipInfo( config.membershipPrefix(), m_username, m_password );
126 }
127
128 setStreamType( config.streamType() );
129
130 metaFactory->setStreamType( m_streamType );
131 m_registry = new ServiceSqlRegistry( metaFactory );
132 m_collection = new Collections::MagnatuneSqlCollection( "magnatune", "Magnatune.com", metaFactory, m_registry );
133 CollectionManager::instance()->addTrackProvider( m_collection );
134 setServiceReady( true );
135 }
136
~MagnatuneStore()137 MagnatuneStore::~MagnatuneStore()
138 {
139 CollectionManager::instance()->removeTrackProvider( m_collection );
140 delete m_registry;
141 delete m_collection;
142 }
143
144
download()145 void MagnatuneStore::download( )
146 {
147 DEBUG_BLOCK
148 if ( m_downloadInProgress )
149 return;
150
151 if ( !m_polished )
152 polish();
153
154 debug() << "here";
155
156 //check if we need to start a download or show the signup dialog
157 if( !m_isMember || m_membershipType != MagnatuneConfig::DOWNLOAD )
158 {
159 showSignupDialog();
160 return;
161 }
162
163 m_downloadInProgress = true;
164 m_downloadAlbumButton->setEnabled( false );
165
166 if ( !m_downloadHandler )
167 {
168 m_downloadHandler = new MagnatuneDownloadHandler();
169 m_downloadHandler->setParent( this );
170 connect( m_downloadHandler, &MagnatuneDownloadHandler::downloadCompleted,
171 this, &MagnatuneStore::downloadCompleted );
172 }
173
174 if ( m_currentAlbum != 0 )
175 m_downloadHandler->downloadAlbum( m_currentAlbum );
176 }
177
178
downloadTrack(Meta::MagnatuneTrack * track)179 void MagnatuneStore::downloadTrack( Meta::MagnatuneTrack * track )
180 {
181 Meta::MagnatuneAlbum * album = dynamic_cast<Meta::MagnatuneAlbum *>( track->album().data() );
182 if ( album )
183 downloadAlbum( album );
184 }
185
downloadAlbum(Meta::MagnatuneAlbum * album)186 void MagnatuneStore::downloadAlbum( Meta::MagnatuneAlbum * album )
187 {
188 DEBUG_BLOCK
189 if ( m_downloadInProgress )
190 return;
191
192 if ( !m_polished )
193 polish();
194
195 m_downloadInProgress = true;
196 m_downloadAlbumButton->setEnabled( false );
197
198 if ( !m_downloadHandler )
199 {
200 m_downloadHandler = new MagnatuneDownloadHandler();
201 m_downloadHandler->setParent( this );
202 connect( m_downloadHandler, &MagnatuneDownloadHandler::downloadCompleted,
203 this, &MagnatuneStore::downloadCompleted );
204 }
205
206 m_downloadHandler->downloadAlbum( album );
207 }
208
209
initTopPanel()210 void MagnatuneStore::initTopPanel( )
211 {
212 QMenu *filterMenu = new QMenu( nullptr );
213
214 QAction *action = filterMenu->addAction( i18n("Artist") );
215 connect( action, &QAction::triggered, this, &MagnatuneStore::sortByArtist );
216
217 action = filterMenu->addAction( i18n( "Artist / Album" ) );
218 connect( action, &QAction::triggered, this, &MagnatuneStore::sortByArtistAlbum );
219
220 action = filterMenu->addAction( i18n( "Album" ) ) ;
221 connect( action, &QAction::triggered, this, &MagnatuneStore::sortByAlbum );
222
223 action = filterMenu->addAction( i18n( "Genre / Artist" ) );
224 connect( action, &QAction::triggered, this, &MagnatuneStore::sortByGenreArtist );
225
226 action = filterMenu->addAction( i18n( "Genre / Artist / Album" ) );
227 connect( action, &QAction::triggered, this, &MagnatuneStore::sortByGenreArtistAlbum );
228
229 QAction *filterMenuAction = new QAction( QIcon::fromTheme( "preferences-other" ), i18n( "Sort Options" ), this );
230 filterMenuAction->setMenu( filterMenu );
231
232 m_searchWidget->toolBar()->addSeparator();
233 m_searchWidget->toolBar()->addAction( filterMenuAction );
234
235 QToolButton *tbutton = qobject_cast<QToolButton*>( m_searchWidget->toolBar()->widgetForAction( filterMenuAction ) );
236 if( tbutton )
237 tbutton->setPopupMode( QToolButton::InstantPopup );
238
239 QMenu * actionsMenu = new QMenu( nullptr );
240
241 action = actionsMenu->addAction( i18n( "Re-download" ) );
242 connect( action, &QAction::triggered, this, &MagnatuneStore::processRedownload );
243
244 m_updateAction = actionsMenu->addAction( i18n( "Update Database" ) );
245 connect( m_updateAction, &QAction::triggered, this, &MagnatuneStore::updateButtonClicked );
246
247 QAction *actionsMenuAction = new QAction( QIcon::fromTheme( "list-add" ), i18n( "Tools" ), this );
248 actionsMenuAction->setMenu( actionsMenu );
249
250 m_searchWidget->toolBar()->addAction( actionsMenuAction );
251
252 tbutton = qobject_cast<QToolButton*>( m_searchWidget->toolBar()->widgetForAction( actionsMenuAction ) );
253 if( tbutton )
254 tbutton->setPopupMode( QToolButton::InstantPopup );
255
256 }
257
initBottomPanel()258 void MagnatuneStore::initBottomPanel()
259 {
260 //m_bottomPanel->setMaximumHeight( 24 );
261
262 m_downloadAlbumButton = new QPushButton;
263 m_downloadAlbumButton->setParent( m_bottomPanel );
264
265 MagnatuneConfig config;
266 if ( config.isMember() && config.membershipType() == MagnatuneConfig::DOWNLOAD )
267 {
268 m_downloadAlbumButton->setText( i18n( "Download Album" ) );
269 m_downloadAlbumButton->setEnabled( false );
270 }
271 else if ( config.isMember() )
272 m_downloadAlbumButton->hide();
273 else
274 {
275 m_downloadAlbumButton->setText( i18n( "Signup" ) );
276 m_downloadAlbumButton->setEnabled( true );
277 }
278
279 m_downloadAlbumButton->setObjectName( "downloadButton" );
280 m_downloadAlbumButton->setIcon( QIcon::fromTheme( "download-amarok" ) );
281
282 connect( m_downloadAlbumButton, &QPushButton::clicked, this, &MagnatuneStore::download );
283
284 if ( !config.lastUpdateTimestamp() )
285 {
286 m_needUpdateWidget = new MagnatuneNeedUpdateWidget(m_bottomPanel);
287
288 connect( m_needUpdateWidget, &MagnatuneNeedUpdateWidget::wantUpdate,
289 this, &MagnatuneStore::updateButtonClicked );
290
291 m_downloadAlbumButton->setParent(0);
292 }
293 }
294
295
updateButtonClicked()296 void MagnatuneStore::updateButtonClicked()
297 {
298 DEBUG_BLOCK
299 m_updateAction->setEnabled( false );
300 if ( m_needUpdateWidget )
301 m_needUpdateWidget->disable();
302
303 updateMagnatuneList();
304 }
305
306
updateMagnatuneList()307 bool MagnatuneStore::updateMagnatuneList()
308 {
309 DEBUG_BLOCK
310 //download new list from magnatune
311
312 debug() << "MagnatuneStore: start downloading xml file";
313
314
315 QTemporaryFile tempFile;
316 // tempFile.setSuffix( ".bz2" );
317 tempFile.setAutoRemove( false ); // file will be removed in MagnatuneXmlParser
318 if( !tempFile.open() )
319 {
320 return false; //error
321 }
322
323 m_tempFileName = tempFile.fileName();
324
325 m_listDownloadJob = KIO::file_copy( QUrl("http://magnatune.com/info/album_info_xml.bz2"), QUrl::fromLocalFile( m_tempFileName ), 0700 , KIO::HideProgressInfo | KIO::Overwrite );
326 Amarok::Logger::newProgressOperation( m_listDownloadJob, i18n( "Downloading Magnatune.com database..." ), this, &MagnatuneStore::listDownloadCancelled );
327
328 connect( m_listDownloadJob, &KJob::result,
329 this, &MagnatuneStore::listDownloadComplete );
330
331 return true;
332 }
333
334
listDownloadComplete(KJob * downLoadJob)335 void MagnatuneStore::listDownloadComplete( KJob * downLoadJob )
336 {
337 DEBUG_BLOCK
338 debug() << "MagnatuneStore: xml file download complete";
339
340 if ( downLoadJob != m_listDownloadJob ) {
341 debug() << "wrong job, ignoring....";
342 return ; //not the right job, so let's ignore it
343 }
344
345 m_updateAction->setEnabled( true );
346
347 if ( downLoadJob->error() != 0 )
348 {
349 debug() << "Got an error, bailing out: " << downLoadJob->errorString();
350 //TODO: error handling here
351 return ;
352 }
353
354
355 Amarok::Logger::shortMessage( i18n( "Updating the local Magnatune database." ) );
356 MagnatuneXmlParser * parser = new MagnatuneXmlParser( m_tempFileName );
357 parser->setDbHandler( new MagnatuneDatabaseHandler() );
358 connect( parser, &MagnatuneXmlParser::doneParsing, this, &MagnatuneStore::doneParsing );
359
360 ThreadWeaver::Queue::instance()->enqueue( QSharedPointer<ThreadWeaver::Job>(parser) );
361 }
362
363
listDownloadCancelled()364 void MagnatuneStore::listDownloadCancelled( )
365 {
366 DEBUG_BLOCK
367
368 m_listDownloadJob->kill();
369 m_listDownloadJob = 0;
370 debug() << "Aborted xml download";
371
372 m_updateAction->setEnabled( true );
373 if ( m_needUpdateWidget )
374 m_needUpdateWidget->enable();
375 }
376
377
378
doneParsing()379 void MagnatuneStore::doneParsing()
380 {
381 debug() << "MagnatuneStore: done parsing";
382 m_collection->emitUpdated();
383
384 //update the last update timestamp
385
386 MagnatuneConfig config;
387 if ( m_magnatuneTimestamp == 0 )
388 config.setLastUpdateTimestamp( QDateTime::currentDateTimeUtc().toSecsSinceEpoch() );
389 else
390 config.setLastUpdateTimestamp( m_magnatuneTimestamp );
391
392 config.save();
393
394 if ( m_needUpdateWidget )
395 {
396 m_needUpdateWidget->setParent(0);
397 m_needUpdateWidget->deleteLater();
398 m_needUpdateWidget = 0;
399
400 m_downloadAlbumButton->setParent(m_bottomPanel);
401 }
402 }
403
404
processRedownload()405 void MagnatuneStore::processRedownload( )
406 {
407 debug() << "Process redownload";
408
409 if ( m_redownloadHandler == 0 )
410 {
411 m_redownloadHandler = new MagnatuneRedownloadHandler( this );
412 }
413 m_redownloadHandler->showRedownloadDialog();
414 }
415
416
downloadCompleted(bool)417 void MagnatuneStore::downloadCompleted( bool )
418 {
419 delete m_downloadHandler;
420 m_downloadHandler = 0;
421
422 m_downloadAlbumButton->setEnabled( true );
423 m_downloadInProgress = false;
424
425 debug() << "Purchase operation complete";
426
427 //TODO: display some kind of success dialog here?
428 }
429
430
itemSelected(CollectionTreeItem * selectedItem)431 void MagnatuneStore::itemSelected( CollectionTreeItem * selectedItem )
432 {
433 DEBUG_BLOCK
434
435 //only care if the user has a download membership
436 if( !m_isMember || m_membershipType != MagnatuneConfig::DOWNLOAD )
437 return;
438
439 //we only enable the purchase button if there is only one item selected and it happens to
440 //be an album or a track
441 Meta::DataPtr dataPtr = selectedItem->data();
442
443 if ( auto track = AmarokSharedPointer<Meta::MagnatuneTrack>::dynamicCast( dataPtr ) )
444 {
445 debug() << "is right type (track)";
446 m_currentAlbum = static_cast<Meta::MagnatuneAlbum *> ( track->album().data() );
447 m_downloadAlbumButton->setEnabled( true );
448 }
449 else if ( auto album = AmarokSharedPointer<Meta::MagnatuneAlbum>::dynamicCast( dataPtr ) )
450 {
451 m_currentAlbum = album.data();
452 debug() << "is right type (album) named " << m_currentAlbum->name();
453
454 m_downloadAlbumButton->setEnabled( true );
455 }
456 else
457 {
458 debug() << "is wrong type";
459 m_downloadAlbumButton->setEnabled( false );
460 }
461 }
462
463
addMoodyTracksToPlaylist(const QString & mood,int count)464 void MagnatuneStore::addMoodyTracksToPlaylist( const QString &mood, int count )
465 {
466 MagnatuneDatabaseWorker *databaseWorker = new MagnatuneDatabaseWorker();
467 databaseWorker->fetchTrackswithMood( mood, count, m_registry );
468 connect( databaseWorker, &MagnatuneDatabaseWorker::gotMoodyTracks, this, &MagnatuneStore::moodyTracksReady );
469
470 ThreadWeaver::Queue::instance()->enqueue( QSharedPointer<ThreadWeaver::Job>(databaseWorker) );
471 }
472
473
polish()474 void MagnatuneStore::polish()
475 {
476 DEBUG_BLOCK;
477
478 if (!m_polished) {
479 m_polished = true;
480
481 initTopPanel( );
482 initBottomPanel();
483
484 QList<CategoryId::CatMenuId> levels;
485 levels << CategoryId::Genre << CategoryId::Artist << CategoryId::Album;
486
487 m_magnatuneInfoParser = new MagnatuneInfoParser();
488
489 setInfoParser( m_magnatuneInfoParser );
490 setModel( new SingleCollectionTreeItemModel( m_collection, levels ) );
491
492 connect( qobject_cast<CollectionTreeView*>(m_contentView), &CollectionTreeView::itemSelected,
493 this, &MagnatuneStore::itemSelected );
494
495 //add a custom url runner
496 MagnatuneUrlRunner *runner = new MagnatuneUrlRunner();
497
498 connect( runner, &MagnatuneUrlRunner::showFavorites, this, &MagnatuneStore::showFavoritesPage );
499 connect( runner, &MagnatuneUrlRunner::showHome, this, &MagnatuneStore::showHomePage );
500 connect( runner, &MagnatuneUrlRunner::showRecommendations, this, &MagnatuneStore::showRecommendationsPage );
501 connect( runner, &MagnatuneUrlRunner::buyOrDownload, this, &MagnatuneStore::downloadSku );
502 connect( runner, &MagnatuneUrlRunner::removeFromFavorites, this, &MagnatuneStore::removeFromFavorites );
503
504 The::amarokUrlHandler()->registerRunner( runner, runner->command() );
505 }
506
507 MagnatuneInfoParser * parser = dynamic_cast<MagnatuneInfoParser *> ( infoParser() );
508 if ( parser )
509 parser->getFrontPage();
510
511 //get a mood map we can show to the cloud view
512
513 MagnatuneDatabaseWorker * databaseWorker = new MagnatuneDatabaseWorker();
514 databaseWorker->fetchMoodMap();
515 connect( databaseWorker, &MagnatuneDatabaseWorker::gotMoodMap, this, &MagnatuneStore::moodMapReady );
516 ThreadWeaver::Queue::instance()->enqueue( QSharedPointer<ThreadWeaver::Job>(databaseWorker) );
517
518 if ( MagnatuneConfig().autoUpdateDatabase() )
519 checkForUpdates();
520 }
521
522
523
setMembership(int type,const QString & username,const QString & password)524 void MagnatuneStore::setMembership( int type, const QString & username, const QString & password)
525 {
526 m_isMember = true;
527 m_membershipType = type;
528 m_username = username;
529 m_password = password;
530 }
531
532
moodMapReady(const QMap<QString,int> & map)533 void MagnatuneStore::moodMapReady(const QMap< QString, int > &map)
534 {
535 QVariantMap variantMap;
536 QList<QVariant> strings;
537 QList<QVariant> weights;
538 QVariantMap dbusActions;
539
540 foreach( const QString &key, map.keys() ) {
541
542 strings << key;
543 weights << map.value( key );
544
545 QString escapedKey = key;
546 escapedKey.replace( ' ', "%20" );
547 QVariantMap action;
548 action["component"] = "/ServicePluginManager";
549 action["function"] = "sendMessage";
550 action["arg1"] = QStringLiteral( "Magnatune.com");
551 action["arg2"] = QStringLiteral( "addMoodyTracks %1 10").arg( escapedKey );
552
553 dbusActions[key] = action;
554
555 }
556
557 variantMap["cloud_name"] = QVariant( "Magnatune Moods" );
558 variantMap["cloud_strings"] = QVariant( strings );
559 variantMap["cloud_weights"] = QVariant( weights );
560 variantMap["cloud_actions"] = QVariant( dbusActions );
561
562 The::infoProxy()->setCloud( variantMap );
563 }
564
565
setStreamType(int type)566 void MagnatuneStore::setStreamType( int type )
567 {
568 m_streamType = type;
569 }
570
checkForUpdates()571 void MagnatuneStore::checkForUpdates()
572 {
573 m_updateTimestampDownloadJob = KIO::storedGet( QUrl("http://magnatune.com/info/last_update_timestamp"), KIO::Reload, KIO::HideProgressInfo );
574 connect( m_updateTimestampDownloadJob, &KJob::result, this, &MagnatuneStore::timestampDownloadComplete );
575 }
576
577
timestampDownloadComplete(KJob * job)578 void MagnatuneStore::timestampDownloadComplete( KJob * job )
579 {
580 DEBUG_BLOCK
581
582 if ( job->error() != 0 )
583 {
584 //TODO: error handling here
585 return ;
586 }
587 if ( job != m_updateTimestampDownloadJob )
588 return ; //not the right job, so let's ignore it
589
590
591 QString timestampString = ( ( KIO::StoredTransferJob* ) job )->data();
592 debug() << "Magnatune timestamp: " << timestampString;
593
594 bool ok;
595 qulonglong magnatuneTimestamp = timestampString.toULongLong( &ok );
596
597 MagnatuneConfig config;
598 qulonglong localTimestamp = config.lastUpdateTimestamp();
599
600 debug() << "Last update timestamp: " << QString::number( localTimestamp );
601
602 if ( ok && magnatuneTimestamp > localTimestamp ) {
603 m_magnatuneTimestamp = magnatuneTimestamp;
604 updateButtonClicked();
605 }
606 }
607
608
moodyTracksReady(const Meta::TrackList & tracks)609 void MagnatuneStore::moodyTracksReady( const Meta::TrackList &tracks )
610 {
611 DEBUG_BLOCK
612 The::playlistController()->insertOptioned( tracks, Playlist::Replace );
613 }
614
615
messages()616 QString MagnatuneStore::messages()
617 {
618 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" );
619
620 return text;
621 }
622
623
sendMessage(const QString & message)624 QString MagnatuneStore::sendMessage( const QString & message )
625 {
626 QStringList args = message.split( ' ', QString::SkipEmptyParts );
627
628 if ( args.size() < 1 ) {
629 return i18n( "ERROR: No arguments supplied" );
630 }
631
632 if ( args[0] == "addMoodyTracks" ) {
633 if ( args.size() != 3 ) {
634 return i18n( "ERROR: Wrong number of arguments for addMoodyTracks" );
635 }
636
637 QString mood = args[1];
638 mood = mood.replace( "%20", " " );
639
640 bool ok;
641 int count = args[2].toInt( &ok );
642
643 if ( !ok )
644 return i18n( "ERROR: Parse error for argument 2 ( count )" );
645
646 addMoodyTracksToPlaylist( mood, count );
647
648 return i18n( "ok" );
649 }
650
651 return i18n( "ERROR: Unknown argument." );
652 }
653
showFavoritesPage()654 void MagnatuneStore::showFavoritesPage()
655 {
656 DEBUG_BLOCK
657 m_magnatuneInfoParser->getFavoritesPage();
658 }
659
showHomePage()660 void MagnatuneStore::showHomePage()
661 {
662 DEBUG_BLOCK
663 m_magnatuneInfoParser->getFrontPage();
664 }
665
showRecommendationsPage()666 void MagnatuneStore::showRecommendationsPage()
667 {
668 DEBUG_BLOCK
669 m_magnatuneInfoParser->getRecommendationsPage();
670 }
671
downloadSku(const QString & sku)672 void MagnatuneStore::downloadSku( const QString &sku )
673 {
674 DEBUG_BLOCK
675 debug() << "sku: " << sku;
676 MagnatuneDatabaseWorker * databaseWorker = new MagnatuneDatabaseWorker();
677 databaseWorker->fetchAlbumBySku( sku, m_registry );
678 connect( databaseWorker, &MagnatuneDatabaseWorker::gotAlbumBySku, this, &MagnatuneStore::downloadAlbum );
679
680 ThreadWeaver::Queue::instance()->enqueue( QSharedPointer<ThreadWeaver::Job>(databaseWorker) );
681 }
682
addToFavorites(const QString & sku)683 void MagnatuneStore::addToFavorites( const QString &sku )
684 {
685 DEBUG_BLOCK
686 MagnatuneConfig config;
687
688 if( !config.isMember() )
689 return;
690
691 QString url = "http://%1:%2@%3.magnatune.com/member/favorites?action=add_api&sku=%4";
692 url = url.arg( config.username(), config.password(), config.membershipPrefix(), sku );
693
694 debug() << "favorites url: " << url;
695
696 m_favoritesJob = KIO::storedGet( QUrl( url ), KIO::Reload, KIO::HideProgressInfo );
697 connect( m_favoritesJob, &KJob::result, this, &MagnatuneStore::favoritesResult );
698 }
699
removeFromFavorites(const QString & sku)700 void MagnatuneStore::removeFromFavorites( const QString &sku )
701 {
702 DEBUG_BLOCK
703 MagnatuneConfig config;
704
705 if( !config.isMember() )
706 return;
707
708 QString url = "http://%1:%2@%3.magnatune.com/member/favorites?action=remove_api&sku=%4";
709 url = url.arg( config.username(), config.password(), config.membershipPrefix(), sku );
710
711 debug() << "favorites url: " << url;
712
713 m_favoritesJob = KIO::storedGet( QUrl( url ), KIO::Reload, KIO::HideProgressInfo );
714 connect( m_favoritesJob, &KJob::result, this, &MagnatuneStore::favoritesResult );
715 }
716
favoritesResult(KJob * addToFavoritesJob)717 void MagnatuneStore::favoritesResult( KJob* addToFavoritesJob )
718 {
719 if( addToFavoritesJob != m_favoritesJob )
720 return;
721
722 QString result = m_favoritesJob->data();
723
724 Amarok::Logger::longMessage( result );
725
726 //show the favorites page
727 showFavoritesPage();
728 }
729
730 void
showSignupDialog()731 MagnatuneStore::showSignupDialog()
732 {
733
734 if ( m_signupInfoWidget== 0 )
735 {
736 m_signupInfoWidget = new QDialog;
737 Ui::SignupDialog ui;
738 ui.setupUi( m_signupInfoWidget );
739 }
740
741 m_signupInfoWidget->show();
742 }
743