From 8285857ac2ac1cb2b6379a53af325bf3c75adddb Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Tue, 26 Mar 2013 18:23:47 +0100 Subject: [PATCH] Add platform and Tomahawk version checks to resolver installation. --- src/SettingsDialog.cpp | 16 +++++- src/libtomahawk/accounts/ResolverAccount.cpp | 60 ++++++++++++++++++++ src/libtomahawk/utils/TomahawkUtils.cpp | 48 ++++++++++++++++ src/libtomahawk/utils/TomahawkUtils.h | 2 + 4 files changed, 125 insertions(+), 1 deletion(-) diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index 70bb2b11f..e525a5235 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -51,6 +51,9 @@ #include "accounts/spotify/SpotifyAccount.h" #include "thirdparty/Qocoa/qtoolbartabdialog.h" #include "thirdparty/Qocoa/qbutton.h" +#include "jobview/JobStatusView.h" +#include "jobview/JobStatusModel.h" +#include "jobview/ErrorStatusMessage.h" #include #include @@ -491,7 +494,18 @@ SettingsDialog::installFromFile() Account* acct = AccountManager::instance()->accountFromPath( resolver ); - Q_ASSERT( acct ); + if ( !acct ) + { + QFileInfo fi( resolver ); + + JobStatusView::instance()->model()->addJob( new ErrorStatusMessage( + tr( "Resolver installation from file %1 failed." ) + .arg( fi.fileName() ) ) ); + + tDebug() << "Resolver was not installed:" << resolver; + return; + } + AccountManager::instance()->addAccount( acct ); TomahawkSettings::instance()->addAccount( acct->accountId() ); AccountManager::instance()->enableAccount( acct ); diff --git a/src/libtomahawk/accounts/ResolverAccount.cpp b/src/libtomahawk/accounts/ResolverAccount.cpp index 049b098a0..32a332141 100644 --- a/src/libtomahawk/accounts/ResolverAccount.cpp +++ b/src/libtomahawk/accounts/ResolverAccount.cpp @@ -28,6 +28,10 @@ #include "Source.h" #include "utils/Logger.h" #include "qjson/parser.h" +#include "jobview/JobStatusView.h" +#include "jobview/JobStatusModel.h" +#include "jobview/ErrorStatusMessage.h" +#include "TomahawkVersion.h" #include #include @@ -93,10 +97,18 @@ ResolverAccountFactory::createFromPath( const QString& path, const QString& fact uniqueName, MANUALRESOLVERS_DIR ) ); if ( !( dir.exists() && dir.isReadable() ) ) //decompression fubar + { + JobStatusView::instance()->model()->addJob( new ErrorStatusMessage( + tr( "Resolver installation error: cannot open bundle." ) ) ); return 0; + } if ( !dir.cd( "content" ) ) //more fubar + { + JobStatusView::instance()->model()->addJob( new ErrorStatusMessage( + tr( "Resolver installation error: incomplete bundle." ) ) ); return 0; + } QString metadataFilePath = dir.absoluteFilePath( "metadata.json" ); configuration = metadataFromJsonFile( metadataFilePath ); @@ -131,7 +143,11 @@ ResolverAccountFactory::createFromPath( const QString& path, const QString& fact realPath = configuration[ "path" ].toString(); if ( realPath.isEmpty() ) + { + JobStatusView::instance()->model()->addJob( new ErrorStatusMessage( + tr( "Resolver installation error: bad metadata in bundle." ) ) ); return 0; + } } else //either legacy resolver or uncompressed bundle, so we look for a metadata file { @@ -146,6 +162,46 @@ ResolverAccountFactory::createFromPath( const QString& path, const QString& fact //else we just have empty metadata (legacy resolver without desktop file) } + //check if the bundle specifies a platform, and if so, reject the resolver if the platform is wrong + if ( !configuration[ "platform" ].isNull() && configuration[ "platform" ].toString() != "any" ) + { + QString platform( configuration[ "platform" ].toString() ); + QString myPlatform( "any" ); + +#if defined( Q_OS_WIN ) + myPlatform = "win"; +#elif defined( Q_OS_MAC ) + myPlatform = "osx"; +#elif defined( Q_OS_LINUX ) + if ( __WORDSIZE == 32 ) + myPlatform = "linux-x86"; + else if ( __WORDSIZE == 64 ) + myPlatform = "linux-x64"; +#endif + + if ( !myPlatform.contains( platform ) ) + { + tDebug() << "Wrong resolver platform."; + JobStatusView::instance()->model()->addJob( new ErrorStatusMessage( + tr( "Resolver installation error: platform mismatch." ) ) ); + return 0; + } + } + + if ( !configuration[ "tomahawkVersion" ].isNull() ) + { + QString thVer = TOMAHAWK_VERSION; + QString requiredVer = configuration[ "tomahawkVersion" ].toString(); + + if ( TomahawkUtils::compareVersionStrings( thVer, requiredVer ) < 0 ) + { + JobStatusView::instance()->model()->addJob( new ErrorStatusMessage( + tr( "Resolver installation error: Tomahawk %1 or newer is required." ) + .arg( requiredVer ) ) ); + return 0; + } + } + //TODO: handle multi-account resolvers return new ResolverAccount( generateId( factory ), realPath, configuration ); @@ -187,6 +243,10 @@ ResolverAccountFactory::metadataFromJsonFile( const QString& path ) result[ "revision" ] = variant[ "revision" ]; if ( !variant[ "timestamp" ].isNull() ) result[ "timestamp" ] = variant[ "timestamp" ]; + if ( !variant[ "tomahawkVersion" ].isNull() ) + result[ "tomahawkVersion" ] = variant[ "tomahawkVersion" ]; + if ( !variant[ "platform" ].isNull() ) + result[ "platform" ] = variant[ "platform" ]; } } return result; diff --git a/src/libtomahawk/utils/TomahawkUtils.cpp b/src/libtomahawk/utils/TomahawkUtils.cpp index bec74cd25..6a7c6f781 100644 --- a/src/libtomahawk/utils/TomahawkUtils.cpp +++ b/src/libtomahawk/utils/TomahawkUtils.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 ) @@ -1013,6 +1014,53 @@ whitelistedHttpResultHint( const QString& url ) } +int +compareVersionStrings( const QString& first, const QString& second ) +{ + QStringList a = first.split( '.', QString::SkipEmptyParts ); + QStringList b = second.split( '.', QString::SkipEmptyParts ); + + const int depth = qMax( a.count(), b.count() ); + + while ( a.count() < depth ) + a.append( "0" ); + + while ( b.count() < depth ) + b.append( "0" ); + + int verdict = 0; + for ( int i = 0; i < depth; ++i ) + { + bool aOk; + int aNumber = a.at( i ).toInt( &aOk ); + bool bOk; + int bNumber = b.at( i ).toInt( &bOk ); + + if ( aOk && bOk ) + { + if ( aNumber < bNumber ) + { + verdict = -1; + break; + } + if ( aNumber > bNumber ) + { + verdict = 1; + break; + } + } + else //fallback: string comparison + { + verdict = a.at( i ).compare( b.at( i ) ); + if ( verdict != 0 ) + break; + } + } + + return verdict; +} + + void urlAddQueryItem( QUrl& url, const QString& key, const QString& value ) { diff --git a/src/libtomahawk/utils/TomahawkUtils.h b/src/libtomahawk/utils/TomahawkUtils.h index 7f56f3040..edd84ec9d 100644 --- a/src/libtomahawk/utils/TomahawkUtils.h +++ b/src/libtomahawk/utils/TomahawkUtils.h @@ -206,6 +206,8 @@ namespace TomahawkUtils DLLEXPORT bool whitelistedHttpResultHint( const QString& url ); + DLLEXPORT int compareVersionStrings( const QString& first, const QString& second ); + /** * This helper is designed to help "update" an existing playlist with a newer revision of itself. * To avoid re-loading the whole playlist and re-resolving tracks that are the same in the old playlist,