1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-06 14:16:32 +02:00

Create playlists from spotify on flip

This commit is contained in:
Leo Franchi
2012-03-18 18:23:39 -04:00
parent 3aa7f5c9de
commit ac274a50d3
9 changed files with 131 additions and 33 deletions

View File

@@ -23,6 +23,7 @@
#include "playlist/PlaylistUpdaterInterface.h" #include "playlist/PlaylistUpdaterInterface.h"
#include "sourcelist.h" #include "sourcelist.h"
#include "SpotifyAccountConfig.h" #include "SpotifyAccountConfig.h"
#include "SpotifyPlaylistUpdater.h"
#include "resolvers/scriptresolver.h" #include "resolvers/scriptresolver.h"
#include <QPixmap> #include <QPixmap>
@@ -80,7 +81,7 @@ SpotifyAccount::SpotifyAccount( const QString& accountId, const QString& path )
void void
SpotifyAccount::init() SpotifyAccount::init()
{ {
qRegisterMetaType< Tomahawk::Accounts::SpotifyPlaylist* >( "Tomahawk::Accounts::SpotifyPlaylist*" ); qRegisterMetaType< Tomahawk::Accounts::SpotifyPlaylistInfo* >( "Tomahawk::Accounts::SpotifyPlaylist*" );
m_spotifyResolver = dynamic_cast< ScriptResolver* >( m_resolver.data() ); m_spotifyResolver = dynamic_cast< ScriptResolver* >( m_resolver.data() );
@@ -151,7 +152,7 @@ SpotifyAccount::resolverMessage( const QString &msgType, const QVariantMap &msg
qDebug() << "Did not get name and plid and revid for spotify playlist:" << name << plid << revid << plMap; qDebug() << "Did not get name and plid and revid for spotify playlist:" << name << plid << revid << plMap;
continue; continue;
} }
m_allSpotifyPlaylists << new SpotifyPlaylist( name, plid, revid, sync ); m_allSpotifyPlaylists << new SpotifyPlaylistInfo( name, plid, revid, sync );
} }
if ( !m_configWidget.isNull() ) if ( !m_configWidget.isNull() )
@@ -231,13 +232,21 @@ SpotifyAccount::saveConfig()
} }
m_configWidget.data()->saveSettings(); m_configWidget.data()->saveSettings();
foreach ( SpotifyPlaylist* pl, m_allSpotifyPlaylists ) foreach ( SpotifyPlaylistInfo* pl, m_allSpotifyPlaylists )
{ {
if ( pl->changed ) if ( pl->changed )
{ {
pl->changed = false; pl->changed = false;
if ( pl->sync ) if ( pl->sync )
startPlaylistSync( pl ); {
// Fetch full playlist contents, then begin the sync
QVariantMap msg;
msg[ "_msgtype" ] = "getPlaylist";
msg[ "playlistid" ] = pl->plid;
msg[ "sync" ] = pl->sync;
sendMessage( msg, "startPlaylistSyncWithPlaylist" );
}
else else
stopPlaylistSync( pl ); stopPlaylistSync( pl );
} }
@@ -245,6 +254,39 @@ SpotifyAccount::saveConfig()
} }
void
SpotifyAccount::startPlaylistSyncWithPlaylist( const QString& msgType, const QVariantMap& msg )
{
qDebug() << Q_FUNC_INFO << "Got full spotify playlist body, creating a tomahawk playlist and enabling sync!!";
const QString id = msg.value( "id" ).toString();
const QString name = msg.value( "name" ).toString();
qDebug() << "Starting sync with pl:" << id << name;
QVariantList tracks = msg.value( "tracks" ).toList();
// create a list of query/plentries directly
QList< query_ptr > queries;
foreach ( const QVariant& trackV, tracks )
{
const QVariantMap trackMap = trackV.toMap();
qDebug() << "Adding spotify track to new tomahawk playlist:" << trackMap.value( "track" ).toString() << trackMap.value( "artist" ).toString() << trackMap.value( "album" ).toString();
query_ptr q = Query::get( trackMap.value( "artist" ).toString(), trackMap.value( "track" ).toString(), trackMap.value( "album" ).toString(), uuid(), false );
q->setProperty( "spotifytrackid", trackMap.value( "id" ) );
queries << q;
}
playlist_ptr plPtr = Tomahawk::Playlist::create( SourceList::instance()->getLocal(),
uuid(),
name,
QString(),
QString(),
false,
queries );
SpotifyPlaylistUpdater* updater = new SpotifyPlaylistUpdater( this, plPtr );
}
void void
SpotifyAccount::addPlaylist( const QString &qid, const QString& title, QList< Tomahawk::query_ptr > tracks ) SpotifyAccount::addPlaylist( const QString &qid, const QString& title, QList< Tomahawk::query_ptr > tracks )
{ {
@@ -312,14 +354,35 @@ SpotifyAccount::sendMessage( const QVariantMap &m, const QString& slot )
void void
SpotifyAccount::startPlaylistSync( SpotifyPlaylist* playlist ) SpotifyAccount::fetchFullPlaylist( SpotifyPlaylistInfo* playlist )
{ {
} }
void void
SpotifyAccount::stopPlaylistSync( SpotifyPlaylist* playlist ) SpotifyAccount::startPlaylistSync( SpotifyPlaylistInfo* playlist )
{
/**
* Begin syncing a playlist. Two options:
* 1) This is a playlist that has never been synced to tomahawk. Create a new one
* and attach a new SpotifyPlaylistUpdater to it
* 2) This was previously synced, and has since been unsynced. THe playlist is still around
* with an inactive SpotifyPlaylistUpdater, so just enable it and bring it up to date.
*/
if ( m_updaters.contains( playlist->plid ) )
{
// update and re-sync
}
else
{
}
}
void
SpotifyAccount::stopPlaylistSync( SpotifyPlaylistInfo* playlist )
{ {
} }
@@ -334,12 +397,3 @@ SpotifyAccount::loadPlaylists()
msg[ "_msgtype" ] = "getAllPlaylists"; msg[ "_msgtype" ] = "getAllPlaylists";
sendMessage( msg, "allPlaylistsLoaded" ); sendMessage( msg, "allPlaylistsLoaded" );
} }
// bool
// operator==( Accounts::SpotifyAccount::Sync one, Accounts::SpotifyAccount::Sync two )
// {
// if( one.id_ == two.id_ )
// return true;
// return false;
// }

View File

@@ -25,6 +25,7 @@
#include "sourcelist.h" #include "sourcelist.h"
#include "accounts/ResolverAccount.h" #include "accounts/ResolverAccount.h"
class SpotifyPlaylistUpdater;
class QTimer; class QTimer;
class ScriptResolver; class ScriptResolver;
@@ -34,16 +35,19 @@ namespace Accounts {
class SpotifyAccountConfig; class SpotifyAccountConfig;
struct SpotifyPlaylist { // metadata for a playlist
struct SpotifyPlaylistInfo {
QString name, plid, revid; QString name, plid, revid;
bool sync, changed; bool sync, changed;
SpotifyPlaylist( const QString& nname, const QString& pid, const QString& rrevid, bool ssync )
SpotifyPlaylistInfo( const QString& nname, const QString& pid, const QString& rrevid, bool ssync )
: name( nname ), plid( pid ), revid( rrevid ), sync( ssync ), changed( false ) {} : name( nname ), plid( pid ), revid( rrevid ), sync( ssync ), changed( false ) {}
SpotifyPlaylist() : sync( false ), changed( false ) {} SpotifyPlaylistInfo() : sync( false ), changed( false ) {}
}; };
class SpotifyAccountFactory : public AccountFactory class SpotifyAccountFactory : public AccountFactory
{ {
Q_OBJECT Q_OBJECT
@@ -94,13 +98,17 @@ private slots:
// SpotifyResolver message handlers, all take msgtype, msg as argument // SpotifyResolver message handlers, all take msgtype, msg as argument
// void <here>( const QString& msgType, const QVariantMap& msg ); // void <here>( const QString& msgType, const QVariantMap& msg );
void startPlaylistSyncWithPlaylist( const QString& msgType, const QVariantMap& msg );
private: private:
void init(); void init();
void loadPlaylists(); void loadPlaylists();
void sendMessage( const QVariantMap& msg, const QString& slot ); void sendMessage( const QVariantMap& msg, const QString& slot );
void startPlaylistSync( SpotifyPlaylist* playlist ); void startPlaylistSync( SpotifyPlaylistInfo* playlist );
void stopPlaylistSync( SpotifyPlaylist* playlist ); void stopPlaylistSync( SpotifyPlaylistInfo* playlist );
void fetchFullPlaylist( SpotifyPlaylistInfo* playlist );
// QList<Sync> m_syncPlaylists; // QList<Sync> m_syncPlaylists;
QWeakPointer<SpotifyAccountConfig> m_configWidget; QWeakPointer<SpotifyAccountConfig> m_configWidget;
@@ -108,12 +116,15 @@ private:
QMap<QString, QString> m_qidToSlotMap; QMap<QString, QString> m_qidToSlotMap;
QList< SpotifyPlaylist* > m_allSpotifyPlaylists; // List of synced spotify playlists in config UI
QList< SpotifyPlaylistInfo* > m_allSpotifyPlaylists;
QHash< QString, SpotifyPlaylistUpdater* > m_updaters;
}; };
} }
} }
Q_DECLARE_METATYPE( Tomahawk::Accounts::SpotifyPlaylist* ); Q_DECLARE_METATYPE( Tomahawk::Accounts::SpotifyPlaylistInfo* );
#endif // SpotifyAccount_H #endif // SpotifyAccount_H

View File

@@ -52,7 +52,7 @@ SpotifyAccountConfig::saveSettings()
for( int i = 0; i < m_ui->playlistList->count(); i++ ) for( int i = 0; i < m_ui->playlistList->count(); i++ )
{ {
const QListWidgetItem* item = m_ui->playlistList->itemAt( i, 0 ); const QListWidgetItem* item = m_ui->playlistList->itemAt( i, 0 );
SpotifyPlaylist* pl = item->data( Qt::UserRole ).value< SpotifyPlaylist* >(); SpotifyPlaylistInfo* pl = item->data( Qt::UserRole ).value< SpotifyPlaylistInfo* >();
const bool toSync = ( item->checkState() == Qt::Checked ); const bool toSync = ( item->checkState() == Qt::Checked );
if ( pl->sync != toSync ) if ( pl->sync != toSync )
{ {
@@ -83,13 +83,13 @@ SpotifyAccountConfig::highQuality() const
void void
SpotifyAccountConfig::setPlaylists( const QList<SpotifyPlaylist *>& playlists ) SpotifyAccountConfig::setPlaylists( const QList<SpotifyPlaylistInfo *>& playlists )
{ {
m_ui->playlistList->clear(); m_ui->playlistList->clear();
foreach ( SpotifyPlaylist* pl, playlists ) foreach ( SpotifyPlaylistInfo* pl, playlists )
{ {
QListWidgetItem* item = new QListWidgetItem( pl->name, m_ui->playlistList ); QListWidgetItem* item = new QListWidgetItem( pl->name, m_ui->playlistList );
item->setData( Qt::UserRole, QVariant::fromValue< SpotifyPlaylist* >( pl ) ); item->setData( Qt::UserRole, QVariant::fromValue< SpotifyPlaylistInfo* >( pl ) );
item->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsSelectable | Qt::ItemIsEnabled ); item->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsSelectable | Qt::ItemIsEnabled );
item->setCheckState( pl->sync ? Qt::Checked : Qt::Unchecked ); item->setCheckState( pl->sync ? Qt::Checked : Qt::Unchecked );
} }

View File

@@ -32,7 +32,7 @@ namespace Accounts
{ {
class SpotifyAccount; class SpotifyAccount;
struct SpotifyPlaylist; struct SpotifyPlaylistInfo;
class SpotifyAccountConfig : public QWidget class SpotifyAccountConfig : public QWidget
{ {
@@ -44,7 +44,7 @@ public:
QString password() const; QString password() const;
bool highQuality() const; bool highQuality() const;
void setPlaylists( const QList< SpotifyPlaylist* >& playlists ); void setPlaylists( const QList< SpotifyPlaylistInfo* >& playlists );
void loadFromConfig(); void loadFromConfig();
void saveSettings(); void saveSettings();

View File

@@ -18,7 +18,35 @@
#include "SpotifyPlaylistUpdater.h" #include "SpotifyPlaylistUpdater.h"
SpotifyPlaylistUpdater::SpotifyPlaylistUpdater(const Tomahawk::playlist_ptr& pl): PlaylistUpdaterInterface(pl) #include "accounts/AccountManager.h"
#include "SpotifyAccount.h"
using namespace Tomahawk;
using namespace Accounts;
Tomahawk::PlaylistUpdaterInterface*
SpotifyUpdaterFactory::create( const Tomahawk::playlist_ptr& pl )
{
if ( !m_account )
{
// Find the spotify account
foreach ( Account* account, AccountManager::instance()->accounts() )
{
if ( SpotifyAccount* spotify = qobject_cast< SpotifyAccount* >( account ) )
{
m_account = spotify;
break;
}
}
}
return new SpotifyPlaylistUpdater( m_account, pl );
}
SpotifyPlaylistUpdater::SpotifyPlaylistUpdater( SpotifyAccount* acct, const playlist_ptr& pl )
: PlaylistUpdaterInterface( pl )
, m_spotify( acct )
{ {
} }

View File

@@ -32,7 +32,7 @@ class SpotifyPlaylistUpdater : public Tomahawk::PlaylistUpdaterInterface
{ {
Q_OBJECT Q_OBJECT
public: public:
SpotifyPlaylistUpdater( const Tomahawk::playlist_ptr& pl ); SpotifyPlaylistUpdater( Tomahawk::Accounts::SpotifyAccount* acct, const Tomahawk::playlist_ptr& pl );
virtual ~SpotifyPlaylistUpdater(); virtual ~SpotifyPlaylistUpdater();
@@ -52,10 +52,13 @@ private:
class SpotifyUpdaterFactory : public Tomahawk::PlaylistUpdaterFactory class SpotifyUpdaterFactory : public Tomahawk::PlaylistUpdaterFactory
{ {
public: public:
SpotifyUpdaterFactory() {} SpotifyUpdaterFactory() : m_account( 0 ) {}
virtual Tomahawk::PlaylistUpdaterInterface* create( const Tomahawk::playlist_ptr& pl ) { return new SpotifyPlaylistUpdater( pl ); } virtual Tomahawk::PlaylistUpdaterInterface* create( const Tomahawk::playlist_ptr& pl );
virtual QString type() const { return "spotify"; } virtual QString type() const { return "spotify"; }
private:
Tomahawk::Accounts::SpotifyAccount* m_account;
}; };
#endif // SPOTIFYPLAYLISTUPDATER_H #endif // SPOTIFYPLAYLISTUPDATER_H

View File

@@ -1,6 +1,7 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,7 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by