diff --git a/src/libtomahawk/AtticaManager.cpp b/src/libtomahawk/AtticaManager.cpp index c53c2377b..bd604b37a 100644 --- a/src/libtomahawk/AtticaManager.cpp +++ b/src/libtomahawk/AtticaManager.cpp @@ -513,14 +513,14 @@ AtticaManager::payloadFetched() // we got a zip file, save it to a temporary file, then unzip it to our destination data dir if ( reply->error() == QNetworkReply::NoError ) { - QTemporaryFile f( QDir::tempPath() + QDir::separator() + "tomahawkattica_XXXXXX.zip" ); - if ( !f.open() ) + QTemporaryFile* f = new QTemporaryFile( QDir::tempPath() + QDir::separator() + "tomahawkattica_XXXXXX.zip" ); + if ( !f->open() ) { - tLog() << "Failed to write zip file to temp file:" << f.fileName(); + tLog() << "Failed to write zip file to temp file:" << f->fileName(); return; } - f.write( reply->readAll() ); - f.close(); + f->write( reply->readAll() ); + f->close(); if ( m_resolverStates[ resolverId ].binary ) { @@ -530,20 +530,20 @@ AtticaManager::payloadFetched() Q_ASSERT( !signature.isEmpty() ); if ( signature.isEmpty() ) return; - if ( !TomahawkUtils::verifyFile( f.fileName(), signature ) ) + if ( !TomahawkUtils::verifyFile( f->fileName(), signature ) ) { - qWarning() << "FILE SIGNATURE FAILED FOR BINARY RESOLVER! WARNING! :" << f.fileName() << signature; + qWarning() << "FILE SIGNATURE FAILED FOR BINARY RESOLVER! WARNING! :" << f->fileName() << signature; } else { - TomahawkUtils::extractBinaryResolver( f.fileName(), new BinaryInstallerHelper( resolverId, reply->property( "createAccount" ).toBool(), this ) ); + TomahawkUtils::extractBinaryResolver( f->fileName(), new BinaryInstallerHelper( f, resolverId, reply->property( "createAccount" ).toBool(), this ) ); // Don't emit success or failed yet, helper will do that. return; } } else { - QDir dir( TomahawkUtils::extractScriptPayload( f.fileName(), resolverId ) ); + QDir dir( TomahawkUtils::extractScriptPayload( f->fileName(), resolverId ) ); QString resolverPath = dir.absoluteFilePath( m_resolverStates[ resolverId ].scriptPath ); if ( !resolverPath.isEmpty() ) @@ -562,6 +562,8 @@ AtticaManager::payloadFetched() installedSuccessfully = true; } } + + delete f; } else { diff --git a/src/libtomahawk/utils/BinaryInstallerHelper.cpp b/src/libtomahawk/utils/BinaryInstallerHelper.cpp index e13cb9321..d061053ca 100644 --- a/src/libtomahawk/utils/BinaryInstallerHelper.cpp +++ b/src/libtomahawk/utils/BinaryInstallerHelper.cpp @@ -20,13 +20,16 @@ #include "accounts/AccountManager.h" #include "TomahawkSettingsGui.h" +#include -BinaryInstallerHelper::BinaryInstallerHelper( const QString& resolverId, bool createAccount, AtticaManager* manager ) +BinaryInstallerHelper::BinaryInstallerHelper( QTemporaryFile* tempFile, const QString& resolverId, bool createAccount, AtticaManager* manager ) : QObject( manager ) + , m_tempFile( tempFile ) , m_resolverId( resolverId ) , m_createAccount( createAccount ) , m_manager( QWeakPointer< AtticaManager >( manager ) ) { + Q_ASSERT( m_tempFile ); Q_ASSERT( !m_resolverId.isEmpty() ); Q_ASSERT( !m_manager.isNull() ); @@ -34,6 +37,13 @@ BinaryInstallerHelper::BinaryInstallerHelper( const QString& resolverId, bool cr } +BinaryInstallerHelper::~BinaryInstallerHelper() +{ + Q_ASSERT( m_tempFile ); + delete m_tempFile; +} + + void BinaryInstallerHelper::installSucceeded( const QString& path ) { diff --git a/src/libtomahawk/utils/BinaryInstallerHelper.h b/src/libtomahawk/utils/BinaryInstallerHelper.h index 511584581..33fbba7ce 100644 --- a/src/libtomahawk/utils/BinaryInstallerHelper.h +++ b/src/libtomahawk/utils/BinaryInstallerHelper.h @@ -22,19 +22,21 @@ #include +class QTemporaryFile; class BinaryInstallerHelper : public QObject { Q_OBJECT public: - explicit BinaryInstallerHelper( const QString& resolverId, bool createAccount, AtticaManager* manager ); + explicit BinaryInstallerHelper( QTemporaryFile* tempFile, const QString& resolverId, bool createAccount, AtticaManager* manager ); - virtual ~BinaryInstallerHelper() {} + virtual ~BinaryInstallerHelper(); public slots: void installSucceeded( const QString& path ); void installFailed(); private: + QTemporaryFile* m_tempFile; QString m_resolverId; bool m_createAccount; QWeakPointer m_manager; diff --git a/src/libtomahawk/utils/TomahawkUtils.cpp b/src/libtomahawk/utils/TomahawkUtils.cpp index 16d8e2a70..6560ebc04 100644 --- a/src/libtomahawk/utils/TomahawkUtils.cpp +++ b/src/libtomahawk/utils/TomahawkUtils.cpp @@ -846,73 +846,107 @@ unzipFileInFolder( const QString &zipFileName, const QDir &folder ) } +class ScopedDeleter +{ +public: + ScopedDeleter( QObject* o ) : m_o( 0 ) {} + ~ScopedDeleter() { m_o->deleteLater(); } + +private: + QObject* m_o; +}; + + +class BinaryExtractWorker : public QThread +{ + Q_OBJECT +public: + BinaryExtractWorker( const QString& zipFilename, QObject* receiver ) : m_zipFileName( zipFilename ), m_receiver( receiver ) {} + virtual ~BinaryExtractWorker() {} + +protected: + virtual void run() + { + ScopedDeleter deleter( this ); + +#ifdef Q_OS_MAC + // Platform-specific handling of resolver payload now. We know it's good + // Unzip the file. + QFileInfo info( m_zipFileName ); + QDir tmpDir = QDir::tempPath(); + if ( !tmpDir.mkdir( info.baseName() ) ) + { + qWarning() << "Failed to create temporary directory to unzip in:" << tmpDir.absolutePath(); + return; + } + tmpDir.cd( info.baseName() ); + TomahawkUtils::unzipFileInFolder( info.absoluteFilePath(), tmpDir ); + + // On OSX it just contains 1 file, the resolver executable itself. For now. We just copy it to + // the Tomahawk.app/Contents/MacOS/ folder alongside the Tomahawk executable. + const QString dest = QCoreApplication::applicationDirPath(); + // Find the filename + const QDir toList( tmpDir.absolutePath() ); + const QStringList files = toList.entryList( QStringList(), QDir::Files ); + Q_ASSERT( files.size() == 1 ); + + const QString src = toList.absoluteFilePath( files.first() ); + qDebug() << "OS X: Copying binary resolver from to:" << src << dest; + + copyWithAuthentication( src, dest, m_receiver ); + + return; +#elif defined(Q_OS_WIN) || defined(Q_OS_LINUX) + // We unzip directly to the target location, just like normal attica resolvers + Q_ASSERT( m_receiver ); + if ( !m_receiver ) + return; + + const QString resolverId = m_receiver->property( "resolverid" ).toString(); + + Q_ASSERT( !resolverId.isEmpty() ); + if ( resolverId.isEmpty() ) + return; + + + const QDir resolverPath( extractScriptPayload( m_zipFileName, resolverId ) ); + +#ifdef Q_OS_WIN + const QStringList files = resolverPath.entryList( QStringList() << "*.exe", QDir::Files ); +#elif defined(Q_OS_LINUX) + const QStringList files = resolverPath.entryList( QStringList() << "*_tomahawkresolver", QDir::Files ); +#endif + + qDebug() << "Found executables in unzipped binary resolver dir:" << files; + Q_ASSERT( files.size() == 1 ); + if ( files.size() < 1 ) + return; + + const QString resolverToUse = resolverPath.absoluteFilePath( files.first() ); + +#ifdef Q_OS_LINUX + QProcess p; + p.start( "chmod", QStringList() << "744" << resolverToUse, QIODevice::ReadOnly ); + p.waitForFinished(); +#endif + + QMetaObject::invokeMethod( m_receiver, "installSucceeded", Qt::QueuedConnection, Q_ARG( QString, resolverToUse ) ); + +#endif + } +private: + QString m_zipFileName; + QObject* m_receiver; +}; + void extractBinaryResolver( const QString& zipFilename, QObject* receiver ) { -#ifdef Q_OS_MAC - // Platform-specific handling of resolver payload now. We know it's good - // Unzip the file. - QFileInfo info( zipFilename ); - QDir tmpDir = QDir::tempPath(); - if ( !tmpDir.mkdir( info.baseName() ) ) - { - qWarning() << "Failed to create temporary directory to unzip in:" << tmpDir.absolutePath(); - return; - } - tmpDir.cd( info.baseName() ); - TomahawkUtils::unzipFileInFolder( info.absoluteFilePath(), tmpDir ); - - // On OSX it just contains 1 file, the resolver executable itself. For now. We just copy it to - // the Tomahawk.app/Contents/MacOS/ folder alongside the Tomahawk executable. - const QString dest = QCoreApplication::applicationDirPath(); - // Find the filename - const QDir toList( tmpDir.absolutePath() ); - const QStringList files = toList.entryList( QStringList(), QDir::Files ); - Q_ASSERT( files.size() == 1 ); - - const QString src = toList.absoluteFilePath( files.first() ); - qDebug() << "OS X: Copying binary resolver from to:" << src << dest; - - copyWithAuthentication( src, dest, receiver ); - - return; -#elif defined(Q_OS_WIN) || defined(Q_OS_LINUX) - // We unzip directly to the target location, just like normal attica resolvers - Q_ASSERT( receiver ); - if ( !receiver ) - return; - - const QString resolverId = receiver->property( "resolverid" ).toString(); - - Q_ASSERT( !resolverId.isEmpty() ); - if ( resolverId.isEmpty() ) - return; - - const QDir resolverPath( extractScriptPayload( zipFilename, resolverId ) ); - -#ifdef Q_OS_WIN - const QStringList files = resolverPath.entryList( QStringList() << "*.exe", QDir::Files ); -#elif defined(Q_OS_LINUX) - const QStringList files = resolverPath.entryList( QStringList() << "*_tomahawkresolver", QDir::Files ); -#endif - - qDebug() << "Found executables in unzipped binary resolver dir:" << files; - Q_ASSERT( files.size() == 1 ); - if ( files.size() < 1 ) - return; - - const QString resolverToUse = resolverPath.absoluteFilePath( files.first() ); - -#ifdef Q_OS_LINUX - QProcess p; - p.start( "chmod", QStringList() << "744" << resolverToUse, QIODevice::ReadOnly ); - p.waitForFinished( 6000 ); -#endif - - QMetaObject::invokeMethod(receiver, "installSucceeded", Qt::DirectConnection, Q_ARG( QString, resolverToUse ) ); - -#endif + BinaryExtractWorker* worker = new BinaryExtractWorker( zipFilename, receiver ); + worker->start( QThread::LowPriority ); } } // ns + +#include "TomahawkUtils.moc"