From 82753732b9147fa0a489453271d73e2fae6db460 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sat, 5 Jan 2013 21:54:39 +0100 Subject: [PATCH] qt5: port QxtWeb and the web api --- CMakeLists.txt | 5 ++ src/CMakeLists.txt | 17 ++++--- src/CMakeLists.unix.cmake | 2 - src/CMakeLists.win32.cmake | 2 - src/TomahawkApp.h | 4 +- src/libtomahawk/CMakeLists.txt | 13 ++--- src/web/Api_v1.cpp | 49 ++++++++++--------- src/web/Api_v1.h | 10 ++-- .../qxtweb-standalone/qxtweb/qxtmetatype.h | 4 ++ .../qxtweb/qxtwebcgiservice.cpp | 14 +++++- .../qxtweb/qxtwebcontent.cpp | 8 +++ 11 files changed, 77 insertions(+), 51 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f7221bc5e..8084c1f7f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -148,6 +148,11 @@ IF( WIN32 ) macro_log_feature(QTSPARKLE_FOUND "qtsparkle" "Library for creating auto updaters written in Qt" "https://github.com/davidsansome/qtsparkle" FALSE "" "") ENDIF( WIN32 ) +#TODO: support external qxt +set(QXTWEB_FOUND TRUE) +set(QXTWEB_LIBRARIES qxtweb-standalone) +set(QXTWEB_INCLUDE_DIRS ${THIRDPARTY_DIR}/qxt/qxtweb-standalone/qxtweb ${CMAKE_CURRENT_BINARY_DIR}) + #### submodules start # automatically init submodules here, don't delete this code we may add submodules again diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2889ce63c..99b3cbea0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -35,8 +35,6 @@ ENDIF() #ENDFOREACH( moddir ) SET( tomahawkSources ${tomahawkSources} - web/Api_v1.cpp - AclRegistryImpl.cpp ShortcutHandler.cpp UbuntuUnityHack.cpp @@ -110,7 +108,6 @@ INCLUDE_DIRECTORIES( libtomahawk mac - ${THIRDPARTY_DIR}/qxt/qxtweb-standalone/qxtweb ${THIRDPARTY_DIR}/breakpad ${TAGLIB_INCLUDES} @@ -121,6 +118,12 @@ INCLUDE_DIRECTORIES( ${LIBLASTFM_INCLUDE_DIRS} ) +IF(QXTWEB_FOUND) + LIST(APPEND tomahawkSources web/Api_v1.cpp) + LIST(APPEND LINK_LIBRARIES ${QXTWEB_LIBRARIES}) + INCLUDE_DIRECTORIES(${QXTWEB_INCLUDE_DIRS}) +ENDIF() + SET( OS_SPECIFIC_LINK_LIBRARIES "" ) IF( WIN32 ) @@ -188,15 +191,14 @@ SET_TARGET_PROPERTIES(tomahawk PROPERTIES AUTOMOC TRUE) MESSAGE( STATUS "OS_SPECIFIC_LINK_LIBRARIES: ${OS_SPECIFIC_LINK_LIBRARIES}" ) -SET(LINK_LIBRARIES "") IF(LIBLASTFM_FOUND) - SET( LINK_LIBRARIES ${LINK_LIBRARIES} ${LIBLASTFM_LIBRARIES} ) + LIST(APPEND LINK_LIBRARIES ${LINK_LIBRARIES} ${LIBLASTFM_LIBRARIES} ) ENDIF(LIBLASTFM_FOUND) IF(QCA2_FOUND) - SET( LINK_LIBRARIES ${LINK_LIBRARIES} ${QCA2_LIBRARIES} ) + LIST(APPEND LINK_LIBRARIES ${LINK_LIBRARIES} ${QCA2_LIBRARIES} ) ENDIF(QCA2_FOUND) IF(WITH_BREAKPAD) - SET( LINK_LIBRARIES ${LINK_LIBRARIES} tomahawk_breakpad ) + LIST(APPEND LINK_LIBRARIES ${LINK_LIBRARIES} tomahawk_breakpad ) ENDIF() TARGET_LINK_LIBRARIES( tomahawk @@ -207,7 +209,6 @@ TARGET_LINK_LIBRARIES( tomahawk ${QT_LIBRARIES} ${MAC_EXTRA_LIBS} ${ECHONEST_LIBRARIES} - ${QXTWEB_LIBRARIES} ${QJSON_LIBRARIES} ${TAGLIB_LIBRARIES} ) diff --git a/src/CMakeLists.unix.cmake b/src/CMakeLists.unix.cmake index 49caf297b..63a3699e9 100644 --- a/src/CMakeLists.unix.cmake +++ b/src/CMakeLists.unix.cmake @@ -4,8 +4,6 @@ ADD_DEFINITIONS( -g ) ADD_DEFINITIONS( -fno-operator-names ) ADD_DEFINITIONS( -fPIC ) -SET( QXTWEB_LIBRARIES qxtweb-standalone ) - IF( APPLE ) INCLUDE( "CMakeLists.osx.cmake" ) ENDIF( APPLE ) diff --git a/src/CMakeLists.win32.cmake b/src/CMakeLists.win32.cmake index eac4a788c..ce3a71ad7 100644 --- a/src/CMakeLists.win32.cmake +++ b/src/CMakeLists.win32.cmake @@ -5,8 +5,6 @@ ADD_DEFINITIONS( /DWIN32_LEAN_AND_MEAN ) ADD_DEFINITIONS( -static-libgcc ) ADD_DEFINITIONS( -DUNICODE ) -SET( QXTWEB_LIBRARIES qxtweb-standalone ) - # Check for the availability of the Thumbbutton check_cxx_source_compiles( " diff --git a/src/TomahawkApp.h b/src/TomahawkApp.h index 628a74e2d..ed2e3f632 100644 --- a/src/TomahawkApp.h +++ b/src/TomahawkApp.h @@ -31,8 +31,8 @@ #include "HeadlessCheck.h" #include "config.h" -#include "QxtHttpServerConnector" -#include "QxtHttpSessionManager" +#include +#include #include #include diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 4322ea769..60357db5a 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -370,13 +370,14 @@ IF(LIBATTICA_FOUND) SET( libGuiSources ${libGuiSources} AtticaManager.cpp ) SET( libGuiHeaders ${libGuiHeaders} AtticaManager.h ) INCLUDE_DIRECTORIES( ${LIBATTICA_INCLUDE_DIR} ) + LIST(APPEND LINK_LIBRARIES ${LIBATTICA_LIBRARIES} ${QuaZip_LIBRARIES} ) ENDIF(LIBATTICA_FOUND) IF( UNIX AND NOT APPLE ) IF( BUILD_GUI AND X11_FOUND ) INCLUDE_DIRECTORIES( ${THIRDPARTY_DIR}/libqnetwm ) SET( libSources ${libSources} ${THIRDPARTY_DIR}/libqnetwm/libqnetwm/netwm.cpp ) - SET( LINK_LIBRARIES ${LINK_LIBRARIES} ${X11_LIBRARIES} ) + LIST(APPEND LINK_LIBRARIES ${X11_LIBRARIES} ) ENDIF() ENDIF( UNIX AND NOT APPLE ) @@ -429,7 +430,7 @@ ELSE( APPLE ) ENDIF( APPLE ) IF(LIBLASTFM_FOUND) - SET(LINK_LIBRARIES ${LINK_LIBRARIES} ${LIBLASTFM_LIBRARIES} ) + LIST(APPEND LINK_LIBRARIES ${LIBLASTFM_LIBRARIES} ) ENDIF(LIBLASTFM_FOUND) IF(BUILD_GUI) @@ -444,15 +445,11 @@ ADD_LIBRARY( tomahawklib SHARED ${libSources}) set_target_properties(tomahawklib PROPERTIES AUTOMOC TRUE) IF(QCA2_FOUND) - SET(LINK_LIBRARIES ${LINK_LIBRARIES} ${QCA2_LIBRARIES} ) + LIST(APPEND LINK_LIBRARIES ${QCA2_LIBRARIES} ) ENDIF(QCA2_FOUND) -IF(LIBATTICA_FOUND) - SET( LINK_LIBRARIES ${LINK_LIBRARIES} ${LIBATTICA_LIBRARIES} ${QuaZip_LIBRARIES} ) -ENDIF(LIBATTICA_FOUND) - IF( UNIX AND NOT APPLE ) - SET( LINK_LIBRARIES ${LINK_LIBRARIES} ${QT_QTDBUS_LIBRARY} ) + LIST(APPEND LINK_LIBRARIES ${QT_QTDBUS_LIBRARY} ) ENDIF( UNIX AND NOT APPLE ) TARGET_LINK_LIBRARIES( tomahawklib diff --git a/src/web/Api_v1.cpp b/src/web/Api_v1.cpp index 76327e2f8..9ac84660c 100644 --- a/src/web/Api_v1.cpp +++ b/src/web/Api_v1.cpp @@ -32,7 +32,10 @@ #include + + using namespace Tomahawk; +using namespace TomahawkUtils; Api_v1::Api_v1(QxtAbstractWebSessionManager* sm, QObject* parent) : QxtWebSlotService(sm, parent) @@ -45,7 +48,7 @@ Api_v1::auth_1( QxtWebRequestEvent* event, QString arg ) { tDebug( LOGVERBOSE ) << "AUTH_1 HTTP" << event->url.toString() << arg; - if ( !event->url.hasQueryItem( "website" ) || !event->url.hasQueryItem( "name" ) ) + if ( !urlHasQueryItem( event->url, "website" ) || !urlHasQueryItem( event->url, "name" ) ) { tDebug( LOGVERBOSE ) << "Malformed HTTP resolve request"; send404( event ); @@ -54,7 +57,7 @@ Api_v1::auth_1( QxtWebRequestEvent* event, QString arg ) QString formToken = uuid(); - if ( event->url.hasQueryItem( "json" ) ) + if ( urlHasQueryItem( event->url, "json" ) ) { // JSON response QVariantMap m; @@ -66,12 +69,12 @@ Api_v1::auth_1( QxtWebRequestEvent* event, QString arg ) // webpage request QString authPage = RESPATH "www/auth.html"; QHash< QString, QString > args; - if ( event->url.hasQueryItem( "receiverurl" ) ) - args[ "url" ] = QUrl::fromPercentEncoding( event->url.queryItemValue( "receiverurl" ).toUtf8() ); + if ( urlHasQueryItem( event->url, "receiverurl" ) ) + args[ "url" ] = urlQueryItemValue( event->url, "receiverurl" ).toUtf8(); args[ "formtoken" ] = formToken; - args[ "website" ] = QUrl::fromPercentEncoding( event->url.queryItemValue( "website" ).toUtf8() ); - args[ "name" ] = QUrl::fromPercentEncoding( event->url.queryItemValue( "name" ).toUtf8() ); + args[ "website" ] = urlQueryItemValue( event->url, "website" ).toUtf8(); + args[ "name" ] = urlQueryItemValue( event->url, "name" ).toUtf8(); sendWebpageWithArgs( event, authPage, args ); } } @@ -138,7 +141,7 @@ Api_v1::auth_2( QxtWebRequestEvent* event, QString arg ) { // do what the client wants QUrl receiverurl = QUrl( queryItems.value( "receiverurl" ), QUrl::TolerantMode ); - receiverurl.addEncodedQueryItem( "authtoken", "#" + authtoken ); + urlAddQueryItem( receiverurl, "authtoken", "#" + authtoken ); tDebug( LOGVERBOSE ) << "Got receiver url:" << receiverurl.toString(); QxtWebRedirectEvent* e = new QxtWebRedirectEvent( event->sessionID, event->requestID, receiverurl.toString() ); @@ -158,9 +161,9 @@ Api_v1::api( QxtWebRequestEvent* event ) tDebug( LOGVERBOSE ) << "HTTP" << event->url.toString(); const QUrl& url = event->url; - if ( url.hasQueryItem( "method" ) ) + if ( urlHasQueryItem( url, "method" ) ) { - const QString method = url.queryItemValue( "method" ); + const QString method = urlQueryItemValue( url, "method" ); if ( method == "stat" ) return stat( event ); if ( method == "resolve" ) return resolve( event ); @@ -194,7 +197,7 @@ Api_v1::sid( QxtWebRequestEvent* event, QString unused ) QxtWebPageEvent* e = new QxtWebPageEvent( event->sessionID, event->requestID, iodev.data() ); e->streaming = iodev->isSequential(); - e->contentType = rp->mimetype().toAscii(); + e->contentType = rp->mimetype().toLatin1(); if ( rp->size() > 0 ) e->headers.insert( "Content-Length", QString::number( rp->size() ) ); postEvent( e ); @@ -221,10 +224,10 @@ Api_v1::stat( QxtWebRequestEvent* event ) if ( !event->content.isNull() ) tDebug( LOGVERBOSE ) << "BODY:" << event->content->readAll(); - if ( event->url.hasQueryItem( "auth" ) ) + if ( urlHasQueryItem( event->url, "auth" ) ) { // check for auth status - DatabaseCommand_ClientAuthValid* dbcmd = new DatabaseCommand_ClientAuthValid( event->url.queryItemValue( "auth" ) ); + DatabaseCommand_ClientAuthValid* dbcmd = new DatabaseCommand_ClientAuthValid( urlQueryItemValue( event->url, "auth" ) ); connect( dbcmd, SIGNAL( authValid( QString, QString, bool ) ), this, SLOT( statResult( QString, QString, bool ) ) ); Database::instance()->enqueue( QSharedPointer(dbcmd) ); } @@ -259,16 +262,16 @@ Api_v1::statResult( const QString& clientToken, const QString& name, bool valid void Api_v1::resolve( QxtWebRequestEvent* event ) { - if ( !event->url.hasQueryItem( "artist" ) || - !event->url.hasQueryItem( "track" ) ) + if ( !urlHasQueryItem( event->url, "artist" ) || + !urlHasQueryItem( event->url, "track" ) ) { tDebug( LOGVERBOSE ) << "Malformed HTTP resolve request"; return send404( event ); } - const QString artist = QUrl::fromPercentEncoding( event->url.queryItemValue( "artist" ).toUtf8() ); - const QString track = QUrl::fromPercentEncoding( event->url.queryItemValue( "track" ).toUtf8() ); - const QString album = QUrl::fromPercentEncoding( event->url.queryItemValue( "album" ).toUtf8() ); + const QString artist = urlQueryItemValue( event->url, "artist" ); + const QString track = urlQueryItemValue( event->url, "track" ); + const QString album = urlQueryItemValue( event->url, "album" ); if ( artist.trimmed().isEmpty() || track.trimmed().isEmpty() ) @@ -278,8 +281,8 @@ Api_v1::resolve( QxtWebRequestEvent* event ) } QString qid; - if ( event->url.hasQueryItem( "qid" ) ) - qid = event->url.queryItemValue( "qid" ); + if ( urlHasQueryItem( event->url, "qid" ) ) + qid = urlQueryItemValue( event->url, "qid" ); else qid = uuid(); @@ -316,14 +319,14 @@ Api_v1::staticdata( QxtWebRequestEvent* event, const QString& str ) void Api_v1::get_results( QxtWebRequestEvent* event ) { - if ( !event->url.hasQueryItem( "qid" ) ) + if ( !urlHasQueryItem( event->url, "qid" ) ) { tDebug( LOGVERBOSE ) << "Malformed HTTP get_results request"; send404( event ); return; } - query_ptr qry = Pipeline::instance()->query( event->url.queryItemValue( "qid" ) ); + query_ptr qry = Pipeline::instance()->query( urlQueryItemValue( event->url, "qid" ) ); if ( qry.isNull() ) { send404( event ); @@ -357,10 +360,10 @@ Api_v1::sendJSON( const QVariantMap& m, QxtWebRequestEvent* event ) QByteArray ctype; QByteArray body = ser.serialize( m ); - if ( event->url.hasQueryItem("jsonp") && !event->url.queryItemValue( "jsonp" ).isEmpty() ) + if ( urlHasQueryItem( event->url, "jsonp" ) && !urlQueryItemValue( event->url, "jsonp" ).isEmpty() ) { ctype = "text/javascript; charset=utf-8"; - body.prepend( QString("%1( ").arg( event->url.queryItemValue( "jsonp" ) ).toAscii() ); + body.prepend( QString("%1( ").arg( urlQueryItemValue( event->url, "jsonp" ) ).toLatin1() ); body.append( " );" ); } else diff --git a/src/web/Api_v1.h b/src/web/Api_v1.h index 3d1739aab..4ad4c88cf 100644 --- a/src/web/Api_v1.h +++ b/src/web/Api_v1.h @@ -22,11 +22,11 @@ // See: http://doc.libqxt.org/tip/qxtweb.html -#include "QxtHttpServerConnector" -#include "QxtHttpSessionManager" -#include "QxtWebContent" -#include "QxtWebSlotService" -#include "QxtWebPageEvent" +#include +#include +#include +#include +#include #include #include diff --git a/thirdparty/qxt/qxtweb-standalone/qxtweb/qxtmetatype.h b/thirdparty/qxt/qxtweb-standalone/qxtweb/qxtmetatype.h index 34bde7a05..d4b75bc28 100644 --- a/thirdparty/qxt/qxtweb-standalone/qxtweb/qxtmetatype.h +++ b/thirdparty/qxt/qxtweb-standalone/qxtweb/qxtmetatype.h @@ -111,7 +111,11 @@ public: inline void* qxtConstructByName(const char* typeName, const void* copy = 0) { +#if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 ) + return QMetaType::create(QMetaType::type(typeName), copy); +#else return QMetaType::construct(QMetaType::type(typeName), copy); +#endif } inline void qxtDestroyByName(const char* typeName, void* data) diff --git a/thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebcgiservice.cpp b/thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebcgiservice.cpp index 409118c27..b51a9b73b 100644 --- a/thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebcgiservice.cpp +++ b/thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebcgiservice.cpp @@ -215,7 +215,11 @@ void QxtWebCgiService::pageRequestedEvent(QxtWebRequestEvent* event) env["CONTENT_TYPE"] = event->contentType; env["CONTENT_LENGTH"] = QString::number(event->content->unreadBytes()); } +#if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 ) + env["QUERY_STRING"] = event->url.query(); +#else env["QUERY_STRING"] = event->url.encodedQuery(); +#endif // Populate HTTP header environment variables QMultiHash::const_iterator iter = event->headers.constBegin(); @@ -251,10 +255,18 @@ void QxtWebCgiService::pageRequestedEvent(QxtWebRequestEvent* event) process->setEnvironment(p_env); // Launch process +#if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 ) + if (event->url.hasQuery() && event->url.query().contains('=')) +#else if (event->url.hasQuery() && event->url.encodedQuery().contains('=')) +#endif { // CGI/1.1 spec says to pass the query on the command line if there's no embedded = sign - process->start(qxt_d().binary + ' ' + QUrl::fromPercentEncoding(event->url.encodedQuery()), QIODevice::ReadWrite); +#if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 ) + process->start(qxt_d().binary + ' ' + event->url.query(), QIODevice::ReadWrite); +#else + process->start(qxt_d().binary + ' ' + event->url.encodedQuery(), QIODevice::ReadWrite); +#endif } else { diff --git a/thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebcontent.cpp b/thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebcontent.cpp index 6fa17026b..77e3932dd 100644 --- a/thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebcontent.cpp +++ b/thirdparty/qxt/qxtweb-standalone/qxtweb/qxtwebcontent.cpp @@ -52,6 +52,10 @@ QxtWeb uses QxtWebContent as an abstraction for streaming data. #include #include +#if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 ) +#include +#endif + #ifndef QXT_DOXYGEN_RUN class QxtWebContentPrivate : public QxtPrivate { @@ -270,7 +274,11 @@ QHash QxtWebContent::parseUrlEncodedQuery(const QString& data) { QUrl post("/?" + data); QHash rv; +#if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 ) + foreach(const QxtQueryItem& item, QUrlQuery( post ).queryItems()) +#else foreach(const QxtQueryItem& item, post.queryItems()) +#endif { rv.insertMulti(item.first, item.second); }