mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-03-20 15:59:42 +01:00
Add keep-in-synch support to EchonestCatalogSynchronizer
be extra safe
This commit is contained in:
parent
1e6bbba189
commit
5f9c21120d
@ -99,6 +99,8 @@ set( libSources
|
||||
database/databasecommand_genericselect.cpp
|
||||
database/databasecommand_setcollectionattributes.cpp
|
||||
database/databasecommand_collectionattributes.cpp
|
||||
database/databasecommand_trackattributes.cpp
|
||||
database/databasecommand_settrackattributes.cpp
|
||||
database/database.cpp
|
||||
|
||||
infobar/infobar.cpp
|
||||
@ -322,6 +324,8 @@ set( libHeaders
|
||||
database/databasecommand_genericselect.h
|
||||
database/databasecommand_setcollectionattributes.h
|
||||
database/databasecommand_collectionattributes.h
|
||||
database/databasecommand_trackattributes.h
|
||||
database/databasecommand_settrackattributes.h
|
||||
|
||||
infobar/infobar.h
|
||||
|
||||
|
@ -18,14 +18,18 @@
|
||||
|
||||
#include "EchonestCatalogSynchronizer.h"
|
||||
|
||||
#include "collection.h"
|
||||
#include "database/database.h"
|
||||
#include "database/databasecommand_genericselect.h"
|
||||
#include "database/databasecommand_setcollectionattributes.h"
|
||||
#include "tomahawksettings.h"
|
||||
#include "sourcelist.h"
|
||||
#include "query.h"
|
||||
|
||||
#include <echonest/CatalogUpdateEntry.h>
|
||||
#include <echonest/Config.h>
|
||||
#include "database/databasecommand_settrackattributes.h"
|
||||
#include "database/databasecommand_trackattributes.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@ -39,6 +43,8 @@ EchonestCatalogSynchronizer::EchonestCatalogSynchronizer( QObject *parent )
|
||||
qRegisterMetaType<QList<QStringList> >("QList<QStringList>");
|
||||
|
||||
connect( TomahawkSettings::instance(), SIGNAL( changed() ), this, SLOT( checkSettingsChanged() ) );
|
||||
connect( SourceList::instance()->getLocal()->collection().data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr> ) ), this, SLOT( tracksAdded( QList<Tomahawk::query_ptr> ) ), Qt::QueuedConnection );
|
||||
connect( SourceList::instance()->getLocal()->collection().data(), SIGNAL( tracksRemoved( QList<Tomahawk::query_ptr> ) ), this, SLOT( tracksRemoved( QList<Tomahawk::query_ptr> ) ), Qt::QueuedConnection );
|
||||
|
||||
const QByteArray artist = TomahawkSettings::instance()->value( "collection/artistCatalog" ).toByteArray();
|
||||
const QByteArray song = TomahawkSettings::instance()->value( "collection/songCatalog" ).toByteArray();
|
||||
@ -46,6 +52,21 @@ EchonestCatalogSynchronizer::EchonestCatalogSynchronizer( QObject *parent )
|
||||
m_artistCatalog.setId( artist );
|
||||
if ( !song.isEmpty() )
|
||||
m_songCatalog.setId( song );
|
||||
|
||||
// Sanity check
|
||||
if ( !m_songCatalog.id().isEmpty() && !m_syncing )
|
||||
{
|
||||
// Not syncing but have a catalog id... lets fix this
|
||||
QNetworkReply* r = m_songCatalog.deleteCatalog();
|
||||
connect( r, SIGNAL( finished() ), this, SLOT( catalogDeleted() ) );
|
||||
r->setProperty( "type", "song" );
|
||||
}
|
||||
if ( !m_artistCatalog.id().isEmpty() && !m_syncing )
|
||||
{
|
||||
QNetworkReply* r = m_artistCatalog.deleteCatalog();
|
||||
connect( r, SIGNAL( finished() ), this, SLOT( catalogDeleted() ) );
|
||||
r->setProperty( "type", "artist" );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -60,12 +81,52 @@ EchonestCatalogSynchronizer::checkSettingsChanged()
|
||||
uploadDb();
|
||||
} else if ( !TomahawkSettings::instance()->enableEchonestCatalogs() && m_syncing )
|
||||
{
|
||||
m_songCatalog.deleteCatalog();
|
||||
m_artistCatalog.deleteCatalog();
|
||||
|
||||
// delete all track nums and catalog ids from our peers
|
||||
{
|
||||
DatabaseCommand_SetTrackAttributes* cmd = new DatabaseCommand_SetTrackAttributes( DatabaseCommand_SetTrackAttributes::EchonestCatalogId );
|
||||
Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
|
||||
}
|
||||
{
|
||||
DatabaseCommand_SetCollectionAttributes* cmd = new DatabaseCommand_SetCollectionAttributes( DatabaseCommand_SetCollectionAttributes::EchonestSongCatalog, true );
|
||||
Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
|
||||
}
|
||||
|
||||
if ( !m_songCatalog.id().isEmpty() )
|
||||
{
|
||||
QNetworkReply* r = m_songCatalog.deleteCatalog();
|
||||
connect( r, SIGNAL( finished() ), this, SLOT( catalogDeleted() ) );
|
||||
r->setProperty( "type", "song" );
|
||||
}
|
||||
if ( !m_artistCatalog.id().isEmpty() )
|
||||
{
|
||||
QNetworkReply* r = m_artistCatalog.deleteCatalog();
|
||||
connect( r, SIGNAL( finished() ), this, SLOT( catalogDeleted() ) );
|
||||
r->setProperty( "type", "artist" );
|
||||
}
|
||||
m_syncing = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::catalogDeleted()
|
||||
{
|
||||
QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() );
|
||||
Q_ASSERT( r );
|
||||
|
||||
QString toDel = QString( "collection/%1Catalog" ).arg( r->property( "type" ).toString() );
|
||||
|
||||
try
|
||||
{
|
||||
// HACK libechonest bug, should be a static method but it's not. Doesn't actually use any instance vars though
|
||||
m_songCatalog.parseDelete( r );
|
||||
// If we didn't throw, no errors, so clear our config
|
||||
TomahawkSettings::instance()->setValue( toDel, QString() );
|
||||
} catch ( const Echonest::ParseError& e )
|
||||
{}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::uploadDb()
|
||||
{
|
||||
@ -73,8 +134,8 @@ EchonestCatalogSynchronizer::uploadDb()
|
||||
QNetworkReply* r = Echonest::Catalog::create( QString( "%1_song" ).arg( Database::instance()->dbid() ), Echonest::CatalogTypes::Song );
|
||||
connect( r, SIGNAL( finished() ), this, SLOT( songCreateFinished() ) );
|
||||
|
||||
r = Echonest::Catalog::create( QString( "%1_artist" ).arg( Database::instance()->dbid() ), Echonest::CatalogTypes::Artist );
|
||||
connect( r, SIGNAL( finished() ), this, SLOT( artistCreateFinished() ) );
|
||||
// r = Echonest::Catalog::create( QString( "%1_artist" ).arg( Database::instance()->dbid() ), Echonest::CatalogTypes::Artist );
|
||||
// connect( r, SIGNAL( finished() ), this, SLOT( artistCreateFinished() ) );
|
||||
}
|
||||
|
||||
void
|
||||
@ -88,9 +149,8 @@ EchonestCatalogSynchronizer::songCreateFinished()
|
||||
{
|
||||
m_songCatalog = Echonest::Catalog::parseCreate( r );
|
||||
TomahawkSettings::instance()->setValue( "collection/songCatalog", m_songCatalog.id() );
|
||||
QSharedPointer< DatabaseCommand > cmd( new DatabaseCommand_SetCollectionAttributes( SourceList::instance()->getLocal(),
|
||||
DatabaseCommand_SetCollectionAttributes::EchonestSongCatalog,
|
||||
m_songCatalog.id() ) );
|
||||
QSharedPointer< DatabaseCommand > cmd( new DatabaseCommand_SetCollectionAttributes( DatabaseCommand_SetCollectionAttributes::EchonestSongCatalog,
|
||||
m_songCatalog.id() ) );
|
||||
Database::instance()->enqueue( cmd );
|
||||
} catch ( const Echonest::ParseError& e )
|
||||
{
|
||||
@ -98,7 +158,7 @@ EchonestCatalogSynchronizer::songCreateFinished()
|
||||
return;
|
||||
}
|
||||
|
||||
QString sql( "SELECT track.name, artist.name, album.name "
|
||||
QString sql( "SELECT track.id, track.name, artist.name, album.name "
|
||||
"FROM file, artist, track, file_join "
|
||||
"LEFT OUTER JOIN album "
|
||||
"ON file_join.album = album.id "
|
||||
@ -107,7 +167,7 @@ EchonestCatalogSynchronizer::songCreateFinished()
|
||||
"AND file_join.track = track.id "
|
||||
"AND file.source IS NULL");
|
||||
DatabaseCommand_GenericSelect* cmd = new DatabaseCommand_GenericSelect( sql, DatabaseCommand_GenericSelect::Track, true );
|
||||
connect( cmd, SIGNAL( rawData( QList< QStringList > ) ), this, SLOT( rawTracks( QList< QStringList > ) ) );
|
||||
connect( cmd, SIGNAL( rawData( QList< QStringList > ) ), this, SLOT( rawTracksAdd( QList< QStringList > ) ) );
|
||||
Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
|
||||
}
|
||||
|
||||
@ -138,7 +198,7 @@ EchonestCatalogSynchronizer::artistCreateFinished()
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::rawTracks( const QList< QStringList >& tracks )
|
||||
EchonestCatalogSynchronizer::rawTracksAdd( const QList< QStringList >& tracks )
|
||||
{
|
||||
tDebug() << "Got raw tracks, num:" << tracks.size();
|
||||
|
||||
@ -151,14 +211,18 @@ EchonestCatalogSynchronizer::rawTracks( const QList< QStringList >& tracks )
|
||||
cur = ( cur + 2000 > tracks.size() ) ? tracks.size() : cur + 2000;
|
||||
|
||||
tDebug() << "Enqueueing a batch of tracks to upload to echonest catalog:" << cur - prev;
|
||||
Echonest::CatalogUpdateEntries entries( cur - prev );
|
||||
Echonest::CatalogUpdateEntries entries;
|
||||
QList< QPair< QID, QString > > inserted;
|
||||
for ( int i = prev; i < cur; i++ )
|
||||
{
|
||||
if ( tracks[i][0].isEmpty() || tracks[i][1].isEmpty() )
|
||||
if ( tracks[i][1].isEmpty() || tracks[i][2].isEmpty() )
|
||||
continue;
|
||||
entries.append( entryFromTrack( tracks[i] ) );
|
||||
entries.append( entryFromTrack( tracks[i], Echonest::CatalogTypes::Update ) );
|
||||
inserted << QPair< QID, QString >( tracks[i][0], entries.last().itemId() );
|
||||
}
|
||||
tDebug() << "Done queuing:" << entries.size() << "tracks";
|
||||
m_queuedUpdates.enqueue( entries );
|
||||
m_queuedTrackInfo.enqueue( inserted );
|
||||
}
|
||||
|
||||
doUploadJob();
|
||||
@ -172,6 +236,7 @@ EchonestCatalogSynchronizer::doUploadJob()
|
||||
return;
|
||||
|
||||
Echonest::CatalogUpdateEntries entries = m_queuedUpdates.dequeue();
|
||||
tDebug() << "Updating number of entries:" << entries.count();
|
||||
|
||||
QNetworkReply* updateJob = m_songCatalog.update( entries );
|
||||
connect( updateJob, SIGNAL( finished() ), this, SLOT( songUpdateFinished() ) );
|
||||
@ -179,14 +244,14 @@ EchonestCatalogSynchronizer::doUploadJob()
|
||||
|
||||
|
||||
Echonest::CatalogUpdateEntry
|
||||
EchonestCatalogSynchronizer::entryFromTrack( const QStringList& track ) const
|
||||
EchonestCatalogSynchronizer::entryFromTrack( const QStringList& track, Echonest::CatalogTypes::Action action ) const
|
||||
{
|
||||
//qDebug() << "UPLOADING:" << track[0] << track[1] << track[2];
|
||||
Echonest::CatalogUpdateEntry entry;
|
||||
entry.setAction( Echonest::CatalogTypes::Update );
|
||||
entry.setSongName( escape( track[ 0 ] ) );
|
||||
entry.setArtistName( escape( track[ 1 ] ) );
|
||||
entry.setRelease( escape( track[ 2 ] ) );
|
||||
entry.setAction( action );
|
||||
entry.setSongName( escape( track[ 1 ] ) );
|
||||
entry.setArtistName( escape( track[ 2 ] ) );
|
||||
entry.setRelease( escape( track[ 3 ] ) );
|
||||
entry.setItemId( uuid().toUtf8() );
|
||||
|
||||
return entry;
|
||||
@ -199,7 +264,13 @@ EchonestCatalogSynchronizer::songUpdateFinished()
|
||||
QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() );
|
||||
Q_ASSERT( r );
|
||||
|
||||
doUploadJob();
|
||||
QList< QPair< QID, QString > > ids = m_queuedTrackInfo.dequeue();
|
||||
if ( r->error() == QNetworkReply::NoError )
|
||||
{
|
||||
// Save the ids of each track in the echonest catalog to our db, so we can keep track of them
|
||||
DatabaseCommand_SetTrackAttributes* cmd = new DatabaseCommand_SetTrackAttributes( DatabaseCommand_SetTrackAttributes::EchonestCatalogId, ids );
|
||||
Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@ -209,8 +280,9 @@ EchonestCatalogSynchronizer::songUpdateFinished()
|
||||
} catch ( const Echonest::ParseError& e )
|
||||
{
|
||||
tLog() << "Echonest threw an exception parsing catalog update finished:" << e.what();
|
||||
return;
|
||||
}
|
||||
|
||||
doUploadJob();
|
||||
}
|
||||
|
||||
void
|
||||
@ -231,6 +303,69 @@ EchonestCatalogSynchronizer::checkTicket()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::tracksAdded( const QList< query_ptr >& tracks )
|
||||
{
|
||||
if ( !m_syncing || m_songCatalog.id().isEmpty() || tracks.isEmpty() )
|
||||
return;
|
||||
|
||||
QList< QStringList > rawTracks;
|
||||
foreach( const query_ptr& track, tracks )
|
||||
{
|
||||
// DatabaseCommand_AddFiles sets the track id on the result
|
||||
int id = -1;
|
||||
if ( track->results().size() == 1 )
|
||||
id = track->results().first()->dbid();
|
||||
else
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "No dbid for track we got in tracksAdded()!";
|
||||
continue;
|
||||
}
|
||||
rawTracks << ( QStringList() << QString::number( id ) << track->track() << track->artist() << track->album() );
|
||||
}
|
||||
rawTracksAdd( rawTracks );
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::tracksRemoved( const QList< query_ptr >& tracks )
|
||||
{
|
||||
|
||||
if ( !m_syncing || m_songCatalog.id().isEmpty() || tracks.isEmpty() )
|
||||
return;
|
||||
|
||||
// get the catalog ids, if they exist, otherwise we can't do anything with them.
|
||||
QList< QID > qids;
|
||||
foreach ( const query_ptr& q, tracks )
|
||||
{
|
||||
qids << q->id();
|
||||
}
|
||||
|
||||
DatabaseCommand_TrackAttributes* cmd = new DatabaseCommand_TrackAttributes( DatabaseCommand_SetTrackAttributes::EchonestCatalogId, qids );
|
||||
connect( cmd, SIGNAL( trackAttributes( PairList ) ), this, SLOT( trackAttributes( PairList ) ) );
|
||||
Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::trackAttributes( PairList attributes )
|
||||
{
|
||||
// QString actionStr = cmd->property( "action" ).toString();
|
||||
Echonest::CatalogTypes::Action action;
|
||||
// if ( actionStr == "delete" )
|
||||
action = Echonest::CatalogTypes::Delete;
|
||||
|
||||
Echonest::CatalogUpdateEntries entries( attributes.size() );
|
||||
QPair< QID, QString > track;
|
||||
foreach ( track, attributes )
|
||||
{
|
||||
Echonest::CatalogUpdateEntry e( action );
|
||||
e.setItemId( track.second.toUtf8() );
|
||||
entries.append( e );
|
||||
}
|
||||
|
||||
m_songCatalog.update( entries );
|
||||
}
|
||||
|
||||
|
||||
QByteArray
|
||||
EchonestCatalogSynchronizer::escape( const QString &in ) const
|
||||
{
|
||||
|
@ -20,6 +20,8 @@
|
||||
#define ECHONESTCATALOGSYNCHRONIZER_H
|
||||
|
||||
#include "dllmacro.h"
|
||||
#include "query.h"
|
||||
#include "database/databasecommand_trackattributes.h"
|
||||
|
||||
#include <echonest/Catalog.h>
|
||||
|
||||
@ -51,19 +53,25 @@ signals:
|
||||
|
||||
private slots:
|
||||
void checkSettingsChanged();
|
||||
void tracksAdded( const QList<Tomahawk::query_ptr>& );
|
||||
void tracksRemoved( const QList<Tomahawk::query_ptr>& );
|
||||
|
||||
// Echonest slots
|
||||
void songCreateFinished();
|
||||
void artistCreateFinished();
|
||||
void songUpdateFinished();
|
||||
void catalogDeleted();
|
||||
|
||||
void checkTicket();
|
||||
|
||||
void rawTracks( const QList< QStringList >& tracks );
|
||||
void rawTracksAdd( const QList< QStringList >& tracks );
|
||||
|
||||
void trackAttributes( PairList );
|
||||
private:
|
||||
void uploadDb();
|
||||
QByteArray escape( const QString& in ) const;
|
||||
|
||||
Echonest::CatalogUpdateEntry entryFromTrack( const QStringList& ) const;
|
||||
Echonest::CatalogUpdateEntry entryFromTrack( const QStringList&, Echonest::CatalogTypes::Action action ) const;
|
||||
void doUploadJob();
|
||||
|
||||
bool m_syncing;
|
||||
@ -72,6 +80,7 @@ private:
|
||||
Echonest::Catalog m_artistCatalog;
|
||||
|
||||
QQueue< Echonest::CatalogUpdateEntries > m_queuedUpdates;
|
||||
QQueue< QList< QPair< QID, QString > > > m_queuedTrackInfo;
|
||||
|
||||
static EchonestCatalogSynchronizer* s_instance;
|
||||
};
|
||||
|
@ -259,6 +259,7 @@ Collection::delTracks( const QStringList& files )
|
||||
i++;
|
||||
}
|
||||
|
||||
tDebug() << "Emitting tracks removed:" << tracks.size();
|
||||
emit tracksRemoved( tracks );
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
#include "utils/logger.h"
|
||||
#include "databasecommand_setcollectionattributes.h"
|
||||
#include "databasecommand_settrackattributes.h"
|
||||
|
||||
|
||||
DatabaseCommand::DatabaseCommand( QObject* parent )
|
||||
@ -174,6 +175,13 @@ DatabaseCommand::factory( const QVariant& op, const source_ptr& source )
|
||||
QJson::QObjectHelper::qvariant2qobject( op.toMap(), cmd );
|
||||
return cmd;
|
||||
}
|
||||
else if( name == "settrackattributes" )
|
||||
{
|
||||
DatabaseCommand_SetTrackAttributes * cmd = new DatabaseCommand_SetTrackAttributes;
|
||||
cmd->setSource( source );
|
||||
QJson::QObjectHelper::qvariant2qobject( op.toMap(), cmd );
|
||||
return cmd;
|
||||
}
|
||||
|
||||
qDebug() << "ERROR in" << Q_FUNC_INFO << name;
|
||||
// Q_ASSERT( false );
|
||||
|
@ -24,7 +24,6 @@ DatabaseCommand_CollectionAttributes::DatabaseCommand_CollectionAttributes( Data
|
||||
: DatabaseCommand()
|
||||
, m_type( type )
|
||||
{
|
||||
qRegisterMetaType< PairList >("PairList");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -16,16 +16,14 @@
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DATABASECOMMAND_ECHONESTCATALOG_H
|
||||
#define DATABASECOMMAND_ECHONESTCATALOG_H
|
||||
#ifndef DATABASECOMMAND_COLLECTIONATTRIBUTES_H
|
||||
#define DATABASECOMMAND_COLLECTIONATTRIBUTES_H
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "databasecommand.h"
|
||||
#include "databasecommand_setcollectionattributes.h"
|
||||
#include <QByteArray>
|
||||
|
||||
typedef QList< QPair< QString, QString > > PairList;
|
||||
|
||||
class DatabaseCommand_CollectionAttributes : public DatabaseCommand
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -35,7 +33,7 @@ public:
|
||||
virtual void exec( DatabaseImpl* lib );
|
||||
virtual bool doesMutates() const { return false; }
|
||||
|
||||
virtual QString commandname() const { return "setcollectionattributes"; }
|
||||
virtual QString commandname() const { return "collectionattributes"; }
|
||||
|
||||
signals:
|
||||
void collectionAttributes( PairList );
|
||||
@ -44,5 +42,4 @@ private:
|
||||
DatabaseCommand_SetCollectionAttributes::AttributeType m_type;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(PairList)
|
||||
#endif
|
||||
|
@ -47,6 +47,7 @@ DatabaseCommand_DeleteFiles::postCommitHook()
|
||||
connect( this, SIGNAL( notify( QStringList ) ),
|
||||
coll, SLOT( delTracks( QStringList ) ), Qt::QueuedConnection );
|
||||
|
||||
tDebug() << "Notifying of deleted tracks:" << m_files.size();
|
||||
emit notify( m_files );
|
||||
|
||||
if( source()->isLocal() )
|
||||
|
@ -20,20 +20,33 @@
|
||||
#include "databaseimpl.h"
|
||||
#include "source.h"
|
||||
#include "network/servent.h"
|
||||
#include "sourcelist.h"
|
||||
|
||||
DatabaseCommand_SetCollectionAttributes::DatabaseCommand_SetCollectionAttributes( const Tomahawk::source_ptr& source, AttributeType type, const QByteArray& id )
|
||||
: DatabaseCommandLoggable( source )
|
||||
DatabaseCommand_SetCollectionAttributes::DatabaseCommand_SetCollectionAttributes( AttributeType type, const QByteArray& id )
|
||||
: DatabaseCommandLoggable( )
|
||||
, m_delete( false )
|
||||
, m_type( type )
|
||||
, m_id( id )
|
||||
{
|
||||
}
|
||||
|
||||
DatabaseCommand_SetCollectionAttributes::DatabaseCommand_SetCollectionAttributes( DatabaseCommand_SetCollectionAttributes::AttributeType type, bool toDelete )
|
||||
: DatabaseCommandLoggable()
|
||||
, m_delete( toDelete )
|
||||
, m_type( type )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DatabaseCommand_SetCollectionAttributes::exec( DatabaseImpl *lib )
|
||||
{
|
||||
TomahawkSqlQuery query = lib->newquery();
|
||||
|
||||
QString sourceStr;
|
||||
if ( source().isNull() )
|
||||
setSource( SourceList::instance()->getLocal() );
|
||||
|
||||
if ( source().isNull() || source()->isLocal() )
|
||||
sourceStr = "NULL";
|
||||
else
|
||||
@ -48,6 +61,9 @@ DatabaseCommand_SetCollectionAttributes::exec( DatabaseImpl *lib )
|
||||
TomahawkSqlQuery delQuery = lib->newquery();
|
||||
delQuery.exec( QString( "DELETE FROM collection_attributes WHERE id %1" ).arg( source()->isLocal() ? QString("IS NULL") : QString( "= %1" ).arg( source()->id() )));
|
||||
|
||||
if ( m_delete )
|
||||
return;
|
||||
|
||||
QString queryStr = QString( "INSERT INTO collection_attributes ( id, k, v ) VALUES( %1, \"%2\", \"%3\" )" ).arg( sourceStr ).arg( typeStr ).arg( QString::fromUtf8( m_id ) );
|
||||
qDebug() << "Doing query:" << queryStr;
|
||||
query.exec( queryStr );
|
||||
|
@ -16,8 +16,8 @@
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DATABASECOMMAND_SAVEECHONESTCATALOG_H
|
||||
#define DATABASECOMMAND_SAVEECHONESTCATALOG_H
|
||||
#ifndef DATABASECOMMAND_SETCOLLECTIONATTRIBUTES
|
||||
#define DATABASECOMMAND_SETCOLLECTIONATTRIBUTES
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "databasecommandloggable.h"
|
||||
@ -35,7 +35,10 @@ public:
|
||||
EchonestArtistCatalog = 1
|
||||
};
|
||||
|
||||
DatabaseCommand_SetCollectionAttributes( const Tomahawk::source_ptr& source, AttributeType type, const QByteArray& id );
|
||||
DatabaseCommand_SetCollectionAttributes( AttributeType type, const QByteArray& id );
|
||||
// Delete all attributes for the source+type
|
||||
DatabaseCommand_SetCollectionAttributes( AttributeType type, bool toDelete );
|
||||
|
||||
DatabaseCommand_SetCollectionAttributes() {} // JSON
|
||||
virtual void exec( DatabaseImpl* lib );
|
||||
virtual bool doesMutates() const { return true; }
|
||||
@ -50,8 +53,9 @@ public:
|
||||
int type() const { return (int)m_type; }
|
||||
|
||||
private:
|
||||
bool m_delete;
|
||||
AttributeType m_type;
|
||||
QByteArray m_id;
|
||||
};
|
||||
|
||||
#endif // DATABASECOMMAND_SAVEECHONESTCATALOG_H
|
||||
#endif // DATABASECOMMAND_SETCOLLECTIONATTRIBUTES
|
||||
|
@ -0,0 +1,97 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "databasecommand_settrackattributes.h"
|
||||
#include "tomahawksqlquery.h"
|
||||
#include "databaseimpl.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
DatabaseCommand_SetTrackAttributes::DatabaseCommand_SetTrackAttributes( DatabaseCommand_SetTrackAttributes::AttributeType type, QList< QPair< QID, QString > > ids, bool toDelete )
|
||||
: DatabaseCommandLoggable()
|
||||
, m_loggable( false )
|
||||
, m_delete( toDelete )
|
||||
, m_type( type )
|
||||
, m_tracks( ids )
|
||||
{
|
||||
}
|
||||
|
||||
DatabaseCommand_SetTrackAttributes::DatabaseCommand_SetTrackAttributes( DatabaseCommand_SetTrackAttributes::AttributeType type )
|
||||
: DatabaseCommandLoggable()
|
||||
, m_loggable( false )
|
||||
, m_delete( true )
|
||||
, m_type( type )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DatabaseCommand_SetTrackAttributes::exec( DatabaseImpl* dbi )
|
||||
{
|
||||
TomahawkSqlQuery checkquery = dbi->newquery();
|
||||
TomahawkSqlQuery delquery = dbi->newquery();
|
||||
TomahawkSqlQuery insertquery = dbi->newquery();
|
||||
|
||||
QString k;
|
||||
switch ( m_type )
|
||||
{
|
||||
case EchonestCatalogId:
|
||||
k = "echonestcatalogid";
|
||||
break;
|
||||
}
|
||||
|
||||
if ( m_delete && m_tracks.isEmpty() )
|
||||
{
|
||||
//delete all
|
||||
TomahawkSqlQuery delAll = dbi->newquery();
|
||||
delAll.prepare( "DELETE FROM track_attributes WHERE k = ?" );
|
||||
delAll.bindValue( 0, k );
|
||||
delAll.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
checkquery.prepare( "SELECT id, sortname FROM track WHERE id = ?" );
|
||||
delquery.prepare( "DELETE FROM track_attributes WHERE id = ? AND k = ?" );
|
||||
insertquery.prepare( "INSERT INTO track_attributes ( id, k, v ) VALUES( ?, ?, ? )" );
|
||||
|
||||
QPair< QID, QString > track;
|
||||
foreach ( track, m_tracks )
|
||||
{
|
||||
checkquery.bindValue( 0, track.first );
|
||||
if ( !checkquery.exec() )
|
||||
{
|
||||
tLog() << "No track in track table for set track attribute command...aborting:" << track.first;
|
||||
continue;
|
||||
}
|
||||
|
||||
delquery.bindValue( 0, track.first );
|
||||
delquery.bindValue( 1, k );
|
||||
delquery.exec();
|
||||
|
||||
if ( m_delete )
|
||||
continue; // stop at deleting, don't insert
|
||||
|
||||
insertquery.bindValue( 0, track.first );
|
||||
insertquery.bindValue( 1, k );
|
||||
insertquery.bindValue( 2, track.second );
|
||||
if ( !insertquery.exec() )
|
||||
tLog() << "Failed to insert track attribute:" << k << track.first << track.second;
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DATABASECOMMAND_SETTRACKATTRIBUTES
|
||||
#define DATABASECOMMAND_SETTRACKATTRIBUTES
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "databasecommandloggable.h"
|
||||
|
||||
#include <QByteArray>
|
||||
|
||||
class DatabaseCommand_SetTrackAttributes : public DatabaseCommandLoggable
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum AttributeType {
|
||||
EchonestCatalogId = 0,
|
||||
};
|
||||
|
||||
// Takes a list of <track_id, value> pairs. key is always type
|
||||
DatabaseCommand_SetTrackAttributes( AttributeType type, QList< QPair< Tomahawk::QID, QString > > ids, bool toDelete = false );
|
||||
// Deletes *all tracks with attribute*
|
||||
DatabaseCommand_SetTrackAttributes( AttributeType type );
|
||||
DatabaseCommand_SetTrackAttributes() {} // JSON
|
||||
|
||||
virtual void exec( DatabaseImpl* lib );
|
||||
virtual bool doesMutates() const { return true; }
|
||||
virtual bool loggable() const { return m_loggable; }
|
||||
|
||||
virtual QString commandname() const { return "settrackattributes"; }
|
||||
|
||||
void setType( int type ) { m_type = (AttributeType)type; }
|
||||
int type() const { return (int)m_type; }
|
||||
|
||||
private:
|
||||
bool m_loggable, m_delete;
|
||||
|
||||
AttributeType m_type;
|
||||
QList< QPair< Tomahawk::QID, QString > > m_tracks;
|
||||
};
|
||||
|
||||
#endif // DATABASECOMMAND_SETTRACKATTRIBUTES
|
71
src/libtomahawk/database/databasecommand_trackattributes.cpp
Normal file
71
src/libtomahawk/database/databasecommand_trackattributes.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "databasecommand_trackattributes.h"
|
||||
#include "databaseimpl.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
DatabaseCommand_TrackAttributes::DatabaseCommand_TrackAttributes( DatabaseCommand_SetTrackAttributes::AttributeType type, const QList< Tomahawk::QID > ids )
|
||||
: DatabaseCommand()
|
||||
, m_type( type )
|
||||
, m_ids( ids )
|
||||
{
|
||||
}
|
||||
|
||||
DatabaseCommand_TrackAttributes::DatabaseCommand_TrackAttributes( DatabaseCommand_SetTrackAttributes::AttributeType type )
|
||||
: DatabaseCommand()
|
||||
, m_type( type )
|
||||
{
|
||||
}
|
||||
|
||||
void DatabaseCommand_TrackAttributes::exec( DatabaseImpl* lib )
|
||||
{
|
||||
TomahawkSqlQuery query = lib->newquery();
|
||||
|
||||
QString k;
|
||||
switch ( m_type )
|
||||
{
|
||||
case DatabaseCommand_SetTrackAttributes::EchonestCatalogId:
|
||||
k = "echonestcatalogid";
|
||||
break;
|
||||
}
|
||||
|
||||
PairList results;
|
||||
if ( !m_ids.isEmpty() )
|
||||
{
|
||||
|
||||
foreach ( const QID id, m_ids )
|
||||
{
|
||||
query.prepare( "SELECT v FROM track_attributes WHERE id = ? AND k = ?" );
|
||||
query.bindValue( 0, id );
|
||||
query.bindValue( 1, k );
|
||||
if ( query.exec() )
|
||||
results.append( QPair< QID, QString >( id, query.value( 0 ).toString() ) );
|
||||
}
|
||||
} else {
|
||||
query.prepare( "SELECT id, v FROM track_attributes WHERE k = ?" );
|
||||
query.bindValue( 0, k );
|
||||
query.exec();
|
||||
while ( !query.next() )
|
||||
{
|
||||
results.append( QPair< QID, QString >( query.value( 0 ).toString(), query.value( 1 ).toString() ) );
|
||||
}
|
||||
}
|
||||
|
||||
emit trackAttributes( results );
|
||||
}
|
51
src/libtomahawk/database/databasecommand_trackattributes.h
Normal file
51
src/libtomahawk/database/databasecommand_trackattributes.h
Normal file
@ -0,0 +1,51 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DATABASECOMMAND_TRACKATTRIBUTES_H
|
||||
#define DATABASECOMMAND_TRACKATTRIBUTES_H
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "databasecommand.h"
|
||||
#include "databasecommand_collectionattributes.h"
|
||||
#include "databasecommand_settrackattributes.h"
|
||||
#include <QByteArray>
|
||||
|
||||
class DatabaseCommand_TrackAttributes : public DatabaseCommand
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
// Get all tracks with this attribute
|
||||
DatabaseCommand_TrackAttributes( DatabaseCommand_SetTrackAttributes::AttributeType type );
|
||||
// Get the specific tracks with this attribute
|
||||
DatabaseCommand_TrackAttributes( DatabaseCommand_SetTrackAttributes::AttributeType type, const QList< Tomahawk::QID > ids );
|
||||
|
||||
virtual void exec( DatabaseImpl* lib );
|
||||
virtual bool doesMutates() const { return false; }
|
||||
|
||||
virtual QString commandname() const { return "trackattributes"; }
|
||||
|
||||
signals:
|
||||
void trackAttributes( PairList );
|
||||
|
||||
private:
|
||||
DatabaseCommand_SetTrackAttributes::AttributeType m_type;
|
||||
QList< Tomahawk::QID > m_ids;
|
||||
};
|
||||
|
||||
#endif
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <QSharedPointer>
|
||||
#include <QUuid>
|
||||
#include <QPair>
|
||||
|
||||
//template <typename T> class QSharedPointer;
|
||||
|
||||
@ -66,6 +67,7 @@ namespace Tomahawk
|
||||
|
||||
typedef int AudioErrorCode;
|
||||
typedef int AudioState;
|
||||
typedef QList< QPair< QString, QString > > PairList;
|
||||
|
||||
// creates 36char ascii guid without {} around it
|
||||
inline static QString uuid()
|
||||
|
@ -367,6 +367,7 @@ TomahawkApp::registerMetaTypes()
|
||||
qRegisterMetaType< QMap< QString, plentry_ptr > >("QMap< QString, plentry_ptr >");
|
||||
qRegisterMetaType< QHash< QString, QMap<quint32, quint16> > >("QHash< QString, QMap<quint32, quint16> >");
|
||||
qRegisterMetaType< QMap< QString, QMap< unsigned int, unsigned int > > >("QMap< QString, QMap< unsigned int, unsigned int > >");
|
||||
qRegisterMetaType< PairList >("PairList");
|
||||
|
||||
qRegisterMetaType< GeneratorMode>("GeneratorMode");
|
||||
qRegisterMetaType<Tomahawk::GeneratorMode>("Tomahawk::GeneratorMode");
|
||||
|
@ -135,7 +135,8 @@ private:
|
||||
QxtHttpSessionManager m_session;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE( QPersistentModelIndex );
|
||||
Q_DECLARE_METATYPE( QPersistentModelIndex )
|
||||
Q_DECLARE_METATYPE(PairList)
|
||||
|
||||
#endif // TOMAHAWKAPP_H
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user