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