mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-03-23 09:19:41 +01:00
* Fixed HTTP resolving & cleaned up Query / Result API further.
This commit is contained in:
parent
4b9f84f54b
commit
1e26b613f0
@ -16,6 +16,7 @@
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
PlaylistEntry::PlaylistEntry() {}
|
||||
PlaylistEntry::~PlaylistEntry() {}
|
||||
|
||||
@ -34,13 +35,7 @@ PlaylistEntry::setQueryVariant( const QVariant& v )
|
||||
QVariant
|
||||
PlaylistEntry::queryVariant() const
|
||||
{
|
||||
QVariantMap m;
|
||||
|
||||
m[ "artist" ] = m_query->artist();
|
||||
m[ "album" ] = m_query->album();
|
||||
m[ "track" ] = m_query->track();
|
||||
|
||||
return m;
|
||||
return m_query->toVariant();
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,6 +26,7 @@ Query::get( const QString& artist, const QString& track, const QString& album, c
|
||||
|
||||
Query::Query( const QString& artist, const QString& track, const QString& album, const QID& qid )
|
||||
: m_solved( false )
|
||||
, m_qid( qid )
|
||||
, m_artist( artist )
|
||||
, m_album( album )
|
||||
, m_track( track )
|
||||
@ -171,3 +172,24 @@ Query::checkResults()
|
||||
if( becameSolved )
|
||||
emit solvedStateChanged( true );
|
||||
}
|
||||
|
||||
|
||||
QVariant
|
||||
Query::toVariant() const
|
||||
{
|
||||
QVariantMap m;
|
||||
m.insert( "artist", artist() );
|
||||
m.insert( "album", album() );
|
||||
m.insert( "track", track() );
|
||||
m.insert( "duration", duration() );
|
||||
m.insert( "qid", id() );
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
Query::toString() const
|
||||
{
|
||||
return QString( "Query(%1, %2 - %3)" ).arg( id() ).arg( artist() ).arg( track() );
|
||||
}
|
||||
|
@ -52,19 +52,15 @@ public:
|
||||
void setTrack( const QString& track ) { m_track = track; }
|
||||
void setResultHint( const QString& resultHint ) { m_resultHint = resultHint; }
|
||||
void setDuration( int duration ) { m_duration = duration; }
|
||||
// void setQID( const QString& qid ) { m_qid = qid; }
|
||||
|
||||
/// for debug output:
|
||||
QString toString() const
|
||||
{
|
||||
return QString( "Query(%1, %2 - %3)" ).arg( id() ).arg( artist() ).arg( track() );
|
||||
}
|
||||
|
||||
QVariant toVariant() const;
|
||||
QString toString() const;
|
||||
|
||||
QString resultHint() const { return m_resultHint; }
|
||||
QString artist() const { return m_artist; }
|
||||
QString album() const { return m_album; }
|
||||
QString track() const { return m_track; }
|
||||
int duration() const { return m_duration; }
|
||||
QString album() const { return m_album; }
|
||||
QString track() const { return m_track; }
|
||||
int duration() const { return m_duration; }
|
||||
|
||||
signals:
|
||||
void resultsAdded( const QList<Tomahawk::result_ptr>& );
|
||||
@ -95,12 +91,10 @@ private:
|
||||
mutable QID m_qid;
|
||||
unsigned int m_lastpipelineweight;
|
||||
|
||||
int m_duration;
|
||||
|
||||
QString m_artist;
|
||||
QString m_album;
|
||||
QString m_track;
|
||||
|
||||
int m_duration;
|
||||
QString m_resultHint;
|
||||
};
|
||||
|
||||
|
@ -58,14 +58,30 @@ Result::score() const
|
||||
RID
|
||||
Result::id() const
|
||||
{
|
||||
if ( m_rid.isEmpty() )
|
||||
{
|
||||
m_rid = m_v.toMap().value( "sid" ).toString();
|
||||
}
|
||||
Q_ASSERT( !m_rid.isEmpty() );
|
||||
return m_rid;
|
||||
}
|
||||
|
||||
|
||||
QVariant
|
||||
Result::toVariant() const
|
||||
{
|
||||
QVariantMap m;
|
||||
m.insert( "artist", artist()->name() );
|
||||
m.insert( "album", album()->name() );
|
||||
m.insert( "track", track() );
|
||||
m.insert( "source", collection()->source()->friendlyName() );
|
||||
m.insert( "mimetype", mimetype() );
|
||||
m.insert( "size", size() );
|
||||
m.insert( "bitrate", bitrate() );
|
||||
m.insert( "duration", duration() );
|
||||
m.insert( "score", score() );
|
||||
m.insert( "sid", id() );
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
Result::toString() const
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ public:
|
||||
explicit Result();
|
||||
virtual ~Result();
|
||||
|
||||
QVariant toVariant() const { return m_v; }
|
||||
QVariant toVariant() const;
|
||||
QString toString() const;
|
||||
Tomahawk::query_ptr toQuery() const;
|
||||
|
||||
@ -40,9 +40,9 @@ public:
|
||||
collection_ptr collection() const;
|
||||
Tomahawk::artist_ptr artist() const;
|
||||
Tomahawk::album_ptr album() const;
|
||||
QString track() const { return m_track; }
|
||||
QString url() const { return m_url; }
|
||||
QString mimetype() const { return m_mimetype; }
|
||||
QString track() const { return m_track; }
|
||||
QString url() const { return m_url; }
|
||||
QString mimetype() const { return m_mimetype; }
|
||||
|
||||
unsigned int duration() const { return m_duration; }
|
||||
unsigned int bitrate() const { return m_bitrate; }
|
||||
@ -82,7 +82,6 @@ private slots:
|
||||
private:
|
||||
void updateAttributes();
|
||||
|
||||
QVariant m_v;
|
||||
mutable RID m_rid;
|
||||
collection_ptr m_collection;
|
||||
|
||||
|
@ -0,0 +1,315 @@
|
||||
#include "api_v1.h"
|
||||
|
||||
|
||||
void
|
||||
Api_v1::auth_1( QxtWebRequestEvent* event )
|
||||
{
|
||||
qDebug() << "AUTH_1 HTTP" << event->url.toString();
|
||||
|
||||
if ( !event->url.hasQueryItem( "website" ) || !event->url.hasQueryItem( "name" ) )
|
||||
{
|
||||
qDebug() << "Malformed HTTP resolve request";
|
||||
send404( event );
|
||||
}
|
||||
|
||||
QString formToken = uuid();
|
||||
|
||||
if ( event->url.hasQueryItem( "json" ) )
|
||||
{
|
||||
// JSON response
|
||||
QVariantMap m;
|
||||
m[ "formtoken" ] = formToken;
|
||||
sendJSON( m, event );
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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() );
|
||||
|
||||
args[ "formtoken" ] = formToken;
|
||||
args[ "website" ] = QUrl::fromPercentEncoding( event->url.queryItemValue( "website" ).toUtf8() );
|
||||
args[ "name" ] = QUrl::fromPercentEncoding( event->url.queryItemValue( "name" ).toUtf8() );
|
||||
sendWebpageWithArgs( event, authPage, args );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api_v1::auth_2( QxtWebRequestEvent* event )
|
||||
{
|
||||
qDebug() << "AUTH_2 HTTP" << event->url.toString();
|
||||
QUrl url = event->url;
|
||||
url.setEncodedQuery( event->content->readAll() );
|
||||
|
||||
if( !url.hasQueryItem( "website" ) || !url.hasQueryItem( "name" ) || !url.hasQueryItem( "formtoken" ) )
|
||||
{
|
||||
qDebug() << "Malformed HTTP resolve request";
|
||||
qDebug() << url.hasQueryItem( "website" ) << url.hasQueryItem( "name" ) << url.hasQueryItem( "formtoken" );
|
||||
send404( event );
|
||||
return;
|
||||
}
|
||||
|
||||
QString website = QUrl::fromPercentEncoding( url.queryItemValue( "website" ).toUtf8() );
|
||||
QString name = QUrl::fromPercentEncoding( url.queryItemValue( "name" ).toUtf8() );
|
||||
QByteArray authtoken = uuid().toLatin1();
|
||||
qDebug() << "HEADERS:" << event->headers;
|
||||
if( !url.hasQueryItem( "receiverurl" ) && url.queryItemValue( "receiverurl" ).isEmpty() )
|
||||
{
|
||||
//no receiver url, so do it ourselves
|
||||
QString receiverUrl = QUrl::fromPercentEncoding( url.queryItemValue( "receiverurl" ).toUtf8() );
|
||||
if( url.hasQueryItem( "json" ) )
|
||||
{
|
||||
QVariantMap m;
|
||||
m[ "authtoken" ] = authtoken;
|
||||
|
||||
sendJSON( m, event );
|
||||
}
|
||||
else
|
||||
{
|
||||
QString authPage = RESPATH "www/auth.na.html";
|
||||
QHash< QString, QString > args;
|
||||
args[ "authcode" ] = authPage;
|
||||
args[ "website" ] = QUrl::fromPercentEncoding( url.queryItemValue( "website" ).toUtf8() );
|
||||
args[ "name" ] = QUrl::fromPercentEncoding( url.queryItemValue( "name" ).toUtf8() );
|
||||
sendWebpageWithArgs( event, authPage, args );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// do what the client wants
|
||||
QUrl receiverurl = QUrl( url.queryItemValue( "receiverurl" ).toUtf8(), QUrl::TolerantMode );
|
||||
receiverurl.addEncodedQueryItem( "authtoken", "#" + authtoken );
|
||||
qDebug() << "Got receiver url:" << receiverurl.toString();
|
||||
|
||||
QxtWebRedirectEvent* e = new QxtWebRedirectEvent( event->sessionID, event->requestID, receiverurl.toString() );
|
||||
postEvent( e );
|
||||
// TODO validation of receiverurl?
|
||||
}
|
||||
|
||||
DatabaseCommand_AddClientAuth* dbcmd = new DatabaseCommand_AddClientAuth( authtoken, website, name, event->headers.key( "ua" ) );
|
||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(dbcmd) );
|
||||
}
|
||||
|
||||
|
||||
// all v1 api calls go to /api/
|
||||
void
|
||||
Api_v1::api( QxtWebRequestEvent* event )
|
||||
{
|
||||
qDebug() << "HTTP" << event->url.toString();
|
||||
|
||||
const QUrl& url = event->url;
|
||||
if( url.hasQueryItem( "method" ) )
|
||||
{
|
||||
const QString method = url.queryItemValue( "method" );
|
||||
|
||||
if( method == "stat" ) return stat( event );
|
||||
if( method == "resolve" ) return resolve( event );
|
||||
if( method == "get_results" ) return get_results( event );
|
||||
}
|
||||
|
||||
send404( event );
|
||||
}
|
||||
|
||||
|
||||
// request for stream: /sid/<id>
|
||||
void
|
||||
Api_v1::sid( QxtWebRequestEvent* event, QString unused )
|
||||
{
|
||||
using namespace Tomahawk;
|
||||
RID rid = event->url.path().mid( 5 );
|
||||
qDebug() << "Request for sid " << rid;
|
||||
|
||||
result_ptr rp = Pipeline::instance()->result( rid );
|
||||
if( rp.isNull() )
|
||||
{
|
||||
return send404( event );
|
||||
}
|
||||
|
||||
QSharedPointer<QIODevice> iodev = Servent::instance()->getIODeviceForUrl( rp );
|
||||
if( iodev.isNull() )
|
||||
{
|
||||
return send404( event ); // 503?
|
||||
}
|
||||
|
||||
QxtWebPageEvent* e = new QxtWebPageEvent( event->sessionID, event->requestID, iodev );
|
||||
e->streaming = iodev->isSequential();
|
||||
e->contentType = rp->mimetype().toAscii();
|
||||
e->headers.insert( "Content-Length", QString::number( rp->size() ) );
|
||||
postEvent( e );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api_v1::send404( QxtWebRequestEvent* event )
|
||||
{
|
||||
qDebug() << "404" << event->url.toString();
|
||||
QxtWebPageEvent* wpe = new QxtWebPageEvent( event->sessionID, event->requestID, "<h1>Not Found</h1>" );
|
||||
wpe->status = 404;
|
||||
wpe->statusMessage = "not feventound";
|
||||
postEvent( wpe );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api_v1::stat( QxtWebRequestEvent* event )
|
||||
{
|
||||
qDebug() << "Got Stat request:" << event->url.toString();
|
||||
m_storedEvent = event;
|
||||
|
||||
if( !event->content.isNull() )
|
||||
qDebug() << "BODY:" << event->content->readAll();
|
||||
|
||||
if( event->url.hasQueryItem( "auth" ) )
|
||||
{
|
||||
// check for auth status
|
||||
DatabaseCommand_ClientAuthValid* dbcmd = new DatabaseCommand_ClientAuthValid( event->url.queryItemValue( "auth" ), this );
|
||||
connect( dbcmd, SIGNAL( authValid( QString, QString, bool ) ), this, SLOT( statResult( QString, QString, bool ) ) );
|
||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(dbcmd) );
|
||||
}
|
||||
else
|
||||
{
|
||||
statResult( QString(), QString(), false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api_v1::statResult( const QString& clientToken, const QString& name, bool valid )
|
||||
{
|
||||
QVariantMap m;
|
||||
m.insert( "name", "playdar" );
|
||||
m.insert( "version", "0.1.1" ); // TODO (needs to be >=0.1.1 for JS to work)
|
||||
m.insert( "authenticated", valid ); // TODO
|
||||
m.insert( "capabilities", QVariantList() );
|
||||
sendJSON( m, m_storedEvent );
|
||||
|
||||
m_storedEvent = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api_v1::resolve( QxtWebRequestEvent* event )
|
||||
{
|
||||
if( !event->url.hasQueryItem( "artist" ) ||
|
||||
!event->url.hasQueryItem( "track" ) )
|
||||
{
|
||||
qDebug() << "Malformed HTTP resolve request";
|
||||
send404( event );
|
||||
}
|
||||
|
||||
QString qid;
|
||||
if ( event->url.hasQueryItem( "qid" ) )
|
||||
qid = event->url.queryItemValue( "qid" );
|
||||
else
|
||||
qid = uuid();
|
||||
|
||||
Tomahawk::query_ptr qry = Tomahawk::Query::get( event->url.queryItemValue( "artist" ), event->url.queryItemValue( "track" ), event->url.queryItemValue( "album" ), qid );
|
||||
|
||||
QVariantMap r;
|
||||
r.insert( "qid", qid );
|
||||
sendJSON( r, event );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api_v1::staticdata( QxtWebRequestEvent* event )
|
||||
{
|
||||
if( event->url.path().contains( "playdar_auth_logo.gif" ) )
|
||||
{
|
||||
// TODO handle
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api_v1::get_results( QxtWebRequestEvent* event )
|
||||
{
|
||||
if( !event->url.hasQueryItem("qid") )
|
||||
{
|
||||
qDebug() << "Malformed HTTP get_results request";
|
||||
send404(event);
|
||||
}
|
||||
|
||||
using namespace Tomahawk;
|
||||
query_ptr qry = Pipeline::instance()->query( event->url.queryItemValue( "qid" ) );
|
||||
if( qry.isNull() )
|
||||
{
|
||||
send404( event );
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap r;
|
||||
r.insert( "qid", qry->id() );
|
||||
r.insert( "poll_interval", 1000 );
|
||||
r.insert( "refresh_interval", 1000 );
|
||||
r.insert( "poll_limit", 6 );
|
||||
r.insert( "solved", qry->solved() );
|
||||
r.insert( "query", qry->toVariant() );
|
||||
|
||||
QVariantList res;
|
||||
foreach( Tomahawk::result_ptr rp, qry->results() )
|
||||
{
|
||||
res << rp->toVariant();
|
||||
}
|
||||
r.insert( "results", res );
|
||||
|
||||
sendJSON( r, event );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api_v1::sendJSON( const QVariantMap& m, QxtWebRequestEvent* event )
|
||||
{
|
||||
QJson::Serializer ser;
|
||||
QByteArray ctype;
|
||||
QByteArray body = ser.serialize( m );
|
||||
|
||||
if( event->url.hasQueryItem("jsonp") && !event->url.queryItemValue( "jsonp" ).isEmpty() )
|
||||
{
|
||||
ctype = "text/javascript; charset=utf-8";
|
||||
body.prepend( QString("%1( ").arg( event->url.queryItemValue( "jsonp" ) ).toAscii() );
|
||||
body.append( " );" );
|
||||
}
|
||||
else
|
||||
{
|
||||
ctype = "appplication/json; charset=utf-8";
|
||||
}
|
||||
|
||||
QxtWebPageEvent * e = new QxtWebPageEvent( event->sessionID, event->requestID, body );
|
||||
e->contentType = ctype;
|
||||
e->headers.insert( "Content-Length", QString::number( body.length() ) );
|
||||
postEvent( e );
|
||||
qDebug() << "JSON response" << event->url.toString() << body;
|
||||
}
|
||||
|
||||
|
||||
// load an html template from a file, replace args from map
|
||||
// then serve
|
||||
void
|
||||
Api_v1::sendWebpageWithArgs( QxtWebRequestEvent* event, const QString& filenameSource, const QHash< QString, QString >& args )
|
||||
{
|
||||
if( !QFile::exists( filenameSource ) )
|
||||
qWarning() << "Passed invalid file for html source:" << filenameSource;
|
||||
|
||||
QFile f( filenameSource );
|
||||
f.open( QIODevice::ReadOnly );
|
||||
QByteArray html = f.readAll();
|
||||
|
||||
foreach( const QString& param, args.keys() )
|
||||
{
|
||||
html.replace( QString( "<%%1%>" ).arg( param.toUpper() ), args.value( param ).toUtf8() );
|
||||
}
|
||||
|
||||
QxtWebPageEvent* e = new QxtWebPageEvent( event->sessionID, event->requestID, html );
|
||||
postEvent( e );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api_v1::index( QxtWebRequestEvent* event )
|
||||
{
|
||||
send404( event );
|
||||
}
|
296
src/web/api_v1.h
296
src/web/api_v1.h
@ -39,299 +39,29 @@ public:
|
||||
}
|
||||
|
||||
public slots:
|
||||
|
||||
// authenticating uses /auth_1
|
||||
// we redirect to /auth_2 for the callback
|
||||
void auth_1( QxtWebRequestEvent* event )
|
||||
{
|
||||
qDebug() << "AUTH_1 HTTP" << event->url.toString();
|
||||
|
||||
if ( !event->url.hasQueryItem( "website" ) || !event->url.hasQueryItem( "name" ) )
|
||||
{
|
||||
qDebug() << "Malformed HTTP resolve request";
|
||||
send404( event );
|
||||
}
|
||||
|
||||
QString formToken = uuid();
|
||||
|
||||
if ( event->url.hasQueryItem( "json" ) )
|
||||
{
|
||||
// JSON response
|
||||
QVariantMap m;
|
||||
m[ "formtoken" ] = formToken;
|
||||
sendJSON( m, event );
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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() );
|
||||
args[ "formtoken" ] = formToken;
|
||||
args[ "website" ] = QUrl::fromPercentEncoding( event->url.queryItemValue( "website" ).toUtf8() );
|
||||
args[ "name" ] = QUrl::fromPercentEncoding( event->url.queryItemValue( "name" ).toUtf8() );
|
||||
sendWebpageWithArgs( event, authPage, args );
|
||||
}
|
||||
}
|
||||
|
||||
void auth_2( QxtWebRequestEvent* event )
|
||||
{
|
||||
qDebug() << "AUTH_2 HTTP" << event->url.toString();
|
||||
QUrl url = event->url;
|
||||
url.setEncodedQuery( event->content->readAll() );
|
||||
void auth_1( QxtWebRequestEvent* event );
|
||||
void auth_2( QxtWebRequestEvent* event );
|
||||
|
||||
if( !url.hasQueryItem( "website" ) || !url.hasQueryItem( "name" ) || !url.hasQueryItem( "formtoken" ) )
|
||||
{
|
||||
qDebug() << "Malformed HTTP resolve request";
|
||||
qDebug() << url.hasQueryItem( "website" ) << url.hasQueryItem( "name" ) << url.hasQueryItem( "formtoken" );
|
||||
send404( event );
|
||||
return;
|
||||
}
|
||||
|
||||
QString website = QUrl::fromPercentEncoding( url.queryItemValue( "website" ).toUtf8() );
|
||||
QString name = QUrl::fromPercentEncoding( url.queryItemValue( "name" ).toUtf8() );
|
||||
QByteArray authtoken = uuid().toLatin1();
|
||||
qDebug() << "HEADERS:" << event->headers;
|
||||
if( !url.hasQueryItem( "receiverurl" ) && url.queryItemValue( "receiverurl" ).isEmpty() )
|
||||
{
|
||||
//no receiver url, so do it ourselves
|
||||
QString receiverUrl = QUrl::fromPercentEncoding( url.queryItemValue( "receiverurl" ).toUtf8() );
|
||||
if( url.hasQueryItem( "json" ) )
|
||||
{
|
||||
QVariantMap m;
|
||||
m[ "authtoken" ] = authtoken;
|
||||
|
||||
sendJSON( m, event );
|
||||
}
|
||||
else
|
||||
{
|
||||
QString authPage = RESPATH "www/auth.na.html";
|
||||
QHash< QString, QString > args;
|
||||
args[ "authcode" ] = authPage;
|
||||
args[ "website" ] = QUrl::fromPercentEncoding( url.queryItemValue( "website" ).toUtf8() );
|
||||
args[ "name" ] = QUrl::fromPercentEncoding( url.queryItemValue( "name" ).toUtf8() );
|
||||
sendWebpageWithArgs( event, authPage, args );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// do what the client wants
|
||||
QUrl receiverurl = QUrl( url.queryItemValue( "receiverurl" ).toUtf8(), QUrl::TolerantMode );
|
||||
receiverurl.addEncodedQueryItem( "authtoken", "#" + authtoken );
|
||||
qDebug() << "Got receiver url:" << receiverurl.toString();
|
||||
|
||||
QxtWebRedirectEvent* e = new QxtWebRedirectEvent( event->sessionID, event->requestID, receiverurl.toString() );
|
||||
postEvent( e );
|
||||
// TODO validation of receiverurl?
|
||||
}
|
||||
|
||||
DatabaseCommand_AddClientAuth* dbcmd = new DatabaseCommand_AddClientAuth( authtoken, website, name, event->headers.key( "ua" ) );
|
||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(dbcmd) );
|
||||
}
|
||||
|
||||
// all v1 api calls go to /api/
|
||||
void api( QxtWebRequestEvent* event )
|
||||
{
|
||||
qDebug() << "HTTP" << event->url.toString();
|
||||
|
||||
const QUrl& url = event->url;
|
||||
if( url.hasQueryItem( "method" ) )
|
||||
{
|
||||
const QString method = url.queryItemValue( "method" );
|
||||
|
||||
if( method == "stat" ) return stat( event );
|
||||
if( method == "resolve" ) return resolve( event );
|
||||
if( method == "get_results" ) return get_results( event );
|
||||
}
|
||||
|
||||
send404( event );
|
||||
}
|
||||
void api( QxtWebRequestEvent* event );
|
||||
|
||||
// request for stream: /sid/<id>
|
||||
void sid( QxtWebRequestEvent* event, QString unused = "" )
|
||||
{
|
||||
using namespace Tomahawk;
|
||||
RID rid = event->url.path().mid( 5 );
|
||||
qDebug() << "Request for sid " << rid;
|
||||
|
||||
result_ptr rp = Pipeline::instance()->result( rid );
|
||||
if( rp.isNull() )
|
||||
{
|
||||
return send404( event );
|
||||
}
|
||||
|
||||
QSharedPointer<QIODevice> iodev = Servent::instance()->getIODeviceForUrl( rp );
|
||||
if( iodev.isNull() )
|
||||
{
|
||||
return send404( event ); // 503?
|
||||
}
|
||||
|
||||
QxtWebPageEvent* e = new QxtWebPageEvent( event->sessionID, event->requestID, iodev );
|
||||
e->streaming = iodev->isSequential();
|
||||
e->contentType = rp->mimetype().toAscii();
|
||||
e->headers.insert("Content-Length", QString::number( rp->size() ) );
|
||||
postEvent( e );
|
||||
}
|
||||
|
||||
void send404( QxtWebRequestEvent* event )
|
||||
{
|
||||
qDebug() << "404" << event->url.toString();
|
||||
QxtWebPageEvent* wpe = new QxtWebPageEvent( event->sessionID, event->requestID, "<h1>Not Found</h1>" );
|
||||
wpe->status = 404;
|
||||
wpe->statusMessage = "not feventound";
|
||||
postEvent( wpe );
|
||||
}
|
||||
|
||||
void stat( QxtWebRequestEvent* event )
|
||||
{
|
||||
qDebug() << "Got Stat request:" << event->url.toString();
|
||||
m_storedEvent = event;
|
||||
|
||||
if( !event->content.isNull() )
|
||||
qDebug() << "BODY:" << event->content->readAll();
|
||||
|
||||
if( event->url.hasQueryItem( "auth" ) )
|
||||
{
|
||||
// check for auth status
|
||||
DatabaseCommand_ClientAuthValid* dbcmd = new DatabaseCommand_ClientAuthValid( event->url.queryItemValue( "auth" ), this );
|
||||
connect( dbcmd, SIGNAL( authValid( QString, QString, bool ) ), this, SLOT( statResult( QString, QString, bool ) ) );
|
||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(dbcmd) );
|
||||
}
|
||||
else
|
||||
{
|
||||
statResult( QString(), QString(), false );
|
||||
}
|
||||
}
|
||||
|
||||
void statResult( const QString& clientToken, const QString& name, bool valid )
|
||||
{
|
||||
QVariantMap m;
|
||||
m.insert( "name", "playdar" );
|
||||
m.insert( "version", "0.1.1" ); // TODO (needs to be >=0.1.1 for JS to work)
|
||||
m.insert( "authenticated", valid ); // TODO
|
||||
m.insert( "capabilities", QVariantList() );
|
||||
sendJSON( m, m_storedEvent );
|
||||
|
||||
m_storedEvent = 0;
|
||||
}
|
||||
|
||||
void resolve( QxtWebRequestEvent* event )
|
||||
{
|
||||
if( !event->url.hasQueryItem( "artist" ) ||
|
||||
!event->url.hasQueryItem( "track" ) )
|
||||
{
|
||||
qDebug() << "Malformed HTTP resolve request";
|
||||
send404(event);
|
||||
}
|
||||
|
||||
QString qid;
|
||||
if( event->url.hasQueryItem( "qid" ) )
|
||||
qid = event->url.queryItemValue( "qid" );
|
||||
else
|
||||
qid = uuid();
|
||||
|
||||
Tomahawk::query_ptr qry = Tomahawk::Query::get( event->url.queryItemValue( "artist" ), event->url.queryItemValue( "track" ), event->url.queryItemValue( "album" ), qid );
|
||||
|
||||
QVariantMap r;
|
||||
r.insert( "qid", qid );
|
||||
sendJSON( r, event );
|
||||
}
|
||||
|
||||
void staticdata( QxtWebRequestEvent* event )
|
||||
{
|
||||
if( event->url.path().contains( "playdar_auth_logo.gif" ) )
|
||||
{
|
||||
// TODO handle
|
||||
}
|
||||
}
|
||||
|
||||
void get_results( QxtWebRequestEvent* event )
|
||||
{
|
||||
if( !event->url.hasQueryItem("qid") )
|
||||
{
|
||||
qDebug() << "Malformed HTTP get_results request";
|
||||
send404(event);
|
||||
}
|
||||
|
||||
using namespace Tomahawk;
|
||||
query_ptr qry = Pipeline::instance()->query( event->url.queryItemValue("qid") );
|
||||
if( qry.isNull() )
|
||||
{
|
||||
send404( event );
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap r;
|
||||
r.insert( "qid", qry->id() );
|
||||
r.insert( "poll_interval", 1000 );
|
||||
r.insert( "refresh_interval", 1000 );
|
||||
r.insert( "poll_limit", 6 );
|
||||
r.insert( "solved", qry->solved() );
|
||||
|
||||
QVariantMap m;
|
||||
m[ "artist" ] = qry->artist();
|
||||
m[ "album" ] = qry->album();
|
||||
m[ "track" ] = qry->track();
|
||||
r.insert( "query", m );
|
||||
QVariantList res;
|
||||
foreach( Tomahawk::result_ptr rp, qry->results() )
|
||||
{
|
||||
res << rp->toVariant();
|
||||
}
|
||||
r.insert( "results", res );
|
||||
|
||||
sendJSON( r, event );
|
||||
}
|
||||
|
||||
void sendJSON( const QVariantMap& m, QxtWebRequestEvent* event )
|
||||
{
|
||||
QJson::Serializer ser;
|
||||
QByteArray ctype;
|
||||
QByteArray body = ser.serialize( m );
|
||||
|
||||
if( event->url.hasQueryItem("jsonp") && !event->url.queryItemValue( "jsonp" ).isEmpty() )
|
||||
{
|
||||
ctype = "text/javascript; charset=utf-8";
|
||||
body.prepend( QString("%1( ").arg( event->url.queryItemValue( "jsonp" ) ).toAscii() );
|
||||
body.append( " );" );
|
||||
}
|
||||
else
|
||||
{
|
||||
ctype = "appplication/json; charset=utf-8";
|
||||
}
|
||||
|
||||
QxtWebPageEvent * e = new QxtWebPageEvent( event->sessionID, event->requestID, body );
|
||||
e->contentType = ctype;
|
||||
e->headers.insert( "Content-Length", QString::number( body.length() ) );
|
||||
postEvent( e );
|
||||
qDebug() << "JSON response" << event->url.toString() << body;
|
||||
}
|
||||
void sid( QxtWebRequestEvent* event, QString unused = QString() );
|
||||
void send404( QxtWebRequestEvent* event );
|
||||
void stat( QxtWebRequestEvent* event );
|
||||
void statResult( const QString& clientToken, const QString& name, bool valid );
|
||||
void resolve( QxtWebRequestEvent* event );
|
||||
void staticdata( QxtWebRequestEvent* event );
|
||||
void get_results( QxtWebRequestEvent* event );
|
||||
void sendJSON( const QVariantMap& m, QxtWebRequestEvent* event );
|
||||
|
||||
// load an html template from a file, replace args from map
|
||||
// then serve
|
||||
void sendWebpageWithArgs( QxtWebRequestEvent* event, const QString& filenameSource, const QHash< QString, QString >& args )
|
||||
{
|
||||
if( !QFile::exists( filenameSource ) )
|
||||
qWarning() << "Passed invalid file for html source:" << filenameSource;
|
||||
|
||||
QFile f( filenameSource );
|
||||
f.open( QIODevice::ReadOnly );
|
||||
QByteArray html = f.readAll();
|
||||
|
||||
foreach( const QString& param, args.keys() )
|
||||
{
|
||||
html.replace( QString( "<%%1%>" ).arg( param.toUpper() ), args.value( param ).toUtf8() );
|
||||
}
|
||||
|
||||
QxtWebPageEvent* e = new QxtWebPageEvent( event->sessionID, event->requestID, html );
|
||||
postEvent( e );
|
||||
}
|
||||
void sendWebpageWithArgs( QxtWebRequestEvent* event, const QString& filenameSource, const QHash< QString, QString >& args );
|
||||
|
||||
void index( QxtWebRequestEvent* event )
|
||||
{
|
||||
send404( event );
|
||||
}
|
||||
void index( QxtWebRequestEvent* event );
|
||||
|
||||
private:
|
||||
QxtWebRequestEvent* m_storedEvent;
|
||||
|
Loading…
x
Reference in New Issue
Block a user