Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Install liblastfm properly

Make Fingerprint suggestions work


git-svn-id: svn+ssh://svn.last.fm/svn/clientside/trunk/desktop@125294 ab8f4a45-97f9-0310-bbd1-854ce3dcee89
  • Loading branch information...
commit f89d8483e07bef9f7f971139d4feba3fa443c24a 1 parent 97d980f
@mxcl mxcl authored
View
4 lib/lastfm/core/libcore.pro
@@ -6,10 +6,10 @@ QT = core xml
include( $$ROOT_DIR/admin/include.qmake )
include( _files.qmake )
-macx:LIBS += -framework Carbon # for mac/AppleScript.*
+macx*:LIBS += -framework Carbon # for mac/AppleScript
win32:LIBS += shell32.lib
headers.files = UrlBuilder.h
-headers.path = $$INSTALL_DIR/include
+headers.path = /include/lastfm
INSTALLS = target headers
View
65 lib/lastfm/fingerprint/FpError.h → lib/lastfm/fingerprint/EXAMPLE.cpp
@@ -17,35 +17,46 @@
* 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
-#ifndef LASTFM_FP_ERROR_H
-#define LASTFM_FP_ERROR_H
+#include <lastfm/Fingerprint>
+#include <lastfm/FingerprintId>
+#include <QtCore>
+#include <QtNetwork>
+using namespace lastfm;
-namespace Fp
+
+static void finish( QNetworkReply* reply )
{
- enum Error
- {
- /** File does not exist or cannot be read */
- ReadError = 0,
-
- /** GetInfo failed to extract samplerate, bitrate, channels, duration etc */
- GetInfoError,
-
- /** Track is shorter than minimum track duration for fingerprinting */
- TrackTooShortError,
-
- /** Could not initialize the fingerprintExtractor (probably ran out of RAM) */
- ExtractorInitError,
-
- /** The fingerprintExtractor has not been initialized before process() is called */
- ExtractorProcessError,
-
- /** The fingerprintExtractor has been starved of data to generate a fingerprint */
- ExtractorNotEnoughDataError,
-
- /** FingerprintExtractor::getFingerprint() has been called prematurely */
- ExtractorNotReadyError
- };
+ QEventLoop loop;
+ loop.connect( reply, SIGNAL(finished()), SLOT(quit()) );
+ loop.exec();
}
-#endif
+
+int main( int argc, char** argv )
+{
+ QCoreApplication app( argc, argv );
+
+ MutableTrack t;
+ t.setArtist( "Air" );
+ t.setTitle( "Redhead Girl" );
+ t.setAlbum( "Pocket Symphony" );
+ t.setUrl( QUrl::fromLocalFile( "/Users/mxcl/Music/iTunes/iTunes Music/Air/Pocket Symphony/1-11 Redhead Girl.mp3") );
+
+ Fingerprint fp( t );
+
+ if(fp.id().isNull()){
+ fp.generate();
+ finish( fp.submit() );
+ fp.decode( reply );
+ }
+
+ if (fp.id().isNull()) {
+ qWarning() << "Still null :(";
+ return 1;
+ }
+
+ finish( fp.id().getSuggestions() );
+
+ qDebug() << FingerprintId::getSuggestions( reply );
+}
View
94 lib/lastfm/fingerprint/Fingerprint.cpp
@@ -22,6 +22,8 @@
#include "Sha256.h"
#include "MP3_Source_Qt.h"
#include "fplib/include/FingerprintExtractor.h"
+#include "../ws/WsRequestBuilder.h"
+#include "../ws/WsAccessManager.h"
#include <QFileInfo>
#include <QNetworkRequest>
#include <QNetworkReply>
@@ -34,11 +36,10 @@ static const uint k_bufferSize = 1024 * 8;
static const int k_minTrackDuration = 30;
-Fingerprint::Fingerprint( const Track& t )
- : m_track( t ),
- m_extractor( 0 ),
- m_id( -1 ),
- m_complete( false )
+lastfm::Fingerprint::Fingerprint( const Track& t )
+ : m_track( t )
+ , m_id( -1 ), m_duration( 0 )
+ , m_complete( false )
{
QString id = Collection::instance().getFingerprintId( t.url().toLocalFile() );
if (id.size()) {
@@ -49,60 +50,61 @@ Fingerprint::Fingerprint( const Track& t )
}
-Fingerprint::~Fingerprint()
-{
- delete m_extractor;
-}
-
-
void
-Fingerprint::generate() throw( Fp::Error )
+lastfm::Fingerprint::generate() throw( Error )
{
- #define CATCH( y ) catch (const std::exception& e) { qWarning() << e.what(); throw( y ); }
-
QString const path = m_track.url().toLocalFile();
if (!QFileInfo( path ).isReadable())
- throw Fp::ReadError;
+ throw ReadError;
- int duration, sampleRate, bitrate, numChannels;
+ int sampleRate, bitrate, numChannels;
MP3_Source ms;
try
{
- MP3_Source::getInfo( path, duration, sampleRate, bitrate, numChannels );
+ MP3_Source::getInfo( path, m_duration, sampleRate, bitrate, numChannels );
ms.init( path );
}
- CATCH( Fp::GetInfoError )
+ catch (std::exception& e)
+ {
+ qWarning() << e.what();
+ throw HeadersError;
+ }
- if (duration < k_minTrackDuration)
- throw Fp::TrackTooShortError;
+
+ if (m_duration < k_minTrackDuration)
+ throw TrackTooShortError;
ms.skipSilence();
bool fpDone = false;
+ fingerprint::FingerprintExtractor* extractor;
try
{
- delete m_extractor;
- m_extractor = new fingerprint::FingerprintExtractor;
+ extractor = new fingerprint::FingerprintExtractor;
if (m_complete)
{
- m_extractor->initForFullSubmit( sampleRate, numChannels );
+ extractor->initForFullSubmit( sampleRate, numChannels );
}
else
{
- m_extractor->initForQuery( sampleRate, numChannels, duration );
+ extractor->initForQuery( sampleRate, numChannels, m_duration );
// Skippety skip for as long as the skipper sez (optimisation)
- ms.skip( m_extractor->getToSkipMs() );
- float secsToSkip = m_extractor->getToSkipMs() / 1000.0f;
- fpDone = m_extractor->process( 0,
+ ms.skip( extractor->getToSkipMs() );
+ float secsToSkip = extractor->getToSkipMs() / 1000.0f;
+ fpDone = extractor->process( 0,
(size_t) sampleRate * numChannels * secsToSkip,
false );
}
}
- CATCH( Fp::ExtractorInitError)
+ catch (std::exception& e)
+ {
+ qWarning() << e.what();
+ throw DecodeError;
+ }
const size_t PCMBufSize = 131072;
short* pPCMBuffer = new short[PCMBufSize];
@@ -115,26 +117,27 @@ Fingerprint::generate() throw( Fp::Error )
try
{
- fpDone = m_extractor->process( pPCMBuffer, readData, ms.eof() );
+ fpDone = extractor->process( pPCMBuffer, readData, ms.eof() );
}
catch ( const std::exception& e )
{
qWarning() << e.what();
delete[] pPCMBuffer;
- throw Fp::ExtractorProcessError;
+ throw InternalError;
}
}
delete[] pPCMBuffer;
if (!fpDone)
- throw Fp::ExtractorNotEnoughDataError;
+ throw InternalError;
// We succeeded
- std::pair<const char*, size_t> fpData = m_extractor->getFingerprint();
+ std::pair<const char*, size_t> fpData = extractor->getFingerprint();
+ delete extractor;
if (fpData.first == NULL || fpData.second == 0)
- throw Fp::ExtractorNotReadyError;
+ throw InternalError;
m_data = QByteArray::fromRawData( fpData.first, fpData.second );
}
@@ -190,9 +193,14 @@ static QString sha256( const QString& path )
}
-QNetworkReply*
-Fingerprint::submit( QNetworkAccessManager* nam ) const
+static QByteArray number( uint n )
{
+ return n ? QByteArray::number( n ) : "";
+}
+
+QNetworkReply*
+lastfm::Fingerprint::submit() const
+{
if (m_data.isEmpty())
return 0;
@@ -210,13 +218,13 @@ Fingerprint::submit( QNetworkAccessManager* nam ) const
url.addEncodedQueryItem( "artist", e(t.artist()) );
url.addEncodedQueryItem( "album", e(t.album()) );
url.addEncodedQueryItem( "track", e(t.title()) );
- url.addEncodedQueryItem( "duration", QByteArray::number(t.duration()) );
+ url.addEncodedQueryItem( "duration", number( m_duration > 0 ? m_duration : t.duration() ) );
url.addEncodedQueryItem( "mbid", e(t.mbid()) );
url.addEncodedQueryItem( "filename", e(fi.completeBaseName()) );
url.addEncodedQueryItem( "fileextension", e(fi.completeSuffix()) );
- url.addEncodedQueryItem( "tracknum", QByteArray::number( t.trackNumber() ) );
+ url.addEncodedQueryItem( "tracknum", number( t.trackNumber() ) );
url.addEncodedQueryItem( "sha256", sha256( path ).toAscii() );
- url.addEncodedQueryItem( "time", QByteArray::number(QDateTime::currentDateTime().toTime_t()) );
+ url.addEncodedQueryItem( "time", number(QDateTime::currentDateTime().toTime_t()) );
url.addEncodedQueryItem( "fpversion", QByteArray::number((int)fingerprint::FingerprintExtractor::getVersion()) );
url.addEncodedQueryItem( "fulldump", m_complete ? "true" : "false" );
url.addEncodedQueryItem( "noupdate", "false" );
@@ -239,12 +247,12 @@ Fingerprint::submit( QNetworkAccessManager* nam ) const
qDebug() << url;
qDebug() << "Fingerprint size:" << bytes.size() << "bytes";
- return nam->post( request, bytes );
+ return WsRequestBuilder::nam()->post( request, bytes );
}
void
-Fingerprint::decode( QNetworkReply* reply, bool* complete_fingerprint_requested )
+lastfm::Fingerprint::decode( QNetworkReply* reply, bool* complete_fingerprint_requested )
{
// The response data will consist of a number and a string.
// The number is the fpid and the string is either FOUND or NEW
@@ -261,6 +269,12 @@ Fingerprint::decode( QNetworkReply* reply, bool* complete_fingerprint_requested
qWarning() << "Null response";
return;
}
+
+ if (response == "No response to client error")
+ throw InternalError;
+
+ if (list.count() != 2)
+ qWarning() << "Response looks bad:" << response;
QString const fpid = list.value( 0 );
QString const status = list.value( 1 );
View
122 lib/lastfm/fingerprint/Fingerprint.h
@@ -20,66 +20,80 @@
#ifndef LASTFM_FINGERPRINT_H
#define LASTFM_FINGERPRINT_H
-#include "lib/lastfm/fingerprint/FpError.h"
#include <lastfm/FingerprintId>
#include <lastfm/Track>
-namespace fingerprint { class FingerprintExtractor; }
-class QNetworkReply;
-class QNetworkAccessManager;
-class LASTFM_FINGERPRINT_DLLEXPORT Fingerprint
+namespace lastfm
{
- lastfm::Track m_track;
- QByteArray m_data;
- fingerprint::FingerprintExtractor* m_extractor;
- int m_id;
-
-protected:
- bool m_complete;
-
-public:
- /** represents a partial fingerprint of 20 seconds of music, this is
- * considered 99.9999...9999% unique and so we use it for most stuff as
- * it is much quicker than a complete fingerprint, still though, you
- * should do the generate step in a thread. */
- Fingerprint( const lastfm::Track& );
- ~Fingerprint();
+ class LASTFM_FINGERPRINT_DLLEXPORT Fingerprint
+ {
+ lastfm::Track m_track;
+ QByteArray m_data;
+ int m_id;
+ int m_duration;
+
+ protected:
+ bool m_complete;
+
+ public:
+ /** represents a partial fingerprint of 20 seconds of music, this is
+ * considered 99.9999...9999% unique and so we use it for most stuff as
+ * it is much quicker than a complete fingerprint, still though, you
+ * should do the generate step in a thread. */
+ Fingerprint( const lastfm::Track& );
- /** if the id isNull(), then you'll need to do generate, submit and decode */
- FingerprintId id() const { return m_id; }
-
- /** The actual data that is the fingerprint, this is about 70kB or so,
- * there isn't anything in it until you call generate.
- * HEY! The QByteArray returned is not valid if Fingerprint object is
- * deleted or falls off the stack. Seriously! Even if you copy it! Although
- * you can of course *deep-copy* the data. */
- QByteArray data() const { return m_data; }
-
- /** This is CPU intensive, do it in a thread in your GUI application */
- void generate() throw( Fp::Error );
-
- /** Submits the fingerprint data to Last.fm in order to get a FingerprintId
- * back. You need to wait for the QNetworkReply to finish before you can
- * pass it to decode clearly. */
- QNetworkReply* submit( QNetworkAccessManager* ) const;
-
- /** Pass a finished reply from submit(), if the response is sound, id()
- * will be valid. Otherwise query QNetworkReply for an error, if there is
- * no error, then the reply was malformed, try submit() again.
- * The return value of id() will be updated by this function, if possible.
- */
- void decode( QNetworkReply*, bool* lastfm_needs_a_complete_fingerprint = 0 );
-};
-
-
-class LASTFM_FINGERPRINT_DLLEXPORT CompleteFingerprint : public Fingerprint
-{
-public:
- CompleteFingerprint( const lastfm::Track& t ) : Fingerprint( t )
+ /** if the id isNull(), then you'll need to do generate, submit and decode */
+ FingerprintId id() const { return m_id; }
+
+ /** The actual data that is the fingerprint, this is about 70kB or so,
+ * there isn't anything in it until you call generate.
+ * HEY! The QByteArray returned is not valid if Fingerprint object is
+ * deleted or falls off the stack. Seriously! Even if you copy it! Although
+ * you can of course *deep-copy* the data. */
+ QByteArray data() const { return m_data; }
+
+ enum Error
+ {
+ ReadError = 0,
+
+ /** failed to extract samplerate, bitrate, channels, duration etc */
+ HeadersError,
+
+ DecodeError,
+
+ /** there is a minimum track duration for fingerprinting */
+ TrackTooShortError,
+
+ /** sorry, liblastfm sucks, report bug with log! */
+ InternalError
+ };
+
+ /** This is CPU intensive, do it in a thread in your GUI application */
+ void generate() throw( Error );
+
+ /** Submits the fingerprint data to Last.fm in order to get a FingerprintId
+ * back. You need to wait for the QNetworkReply to finish before you can
+ * pass it to decode clearly. */
+ QNetworkReply* submit() const;
+
+ /** Pass a finished reply from submit(), if the response is sound, id()
+ * will be valid. Otherwise query QNetworkReply for an error, if there is
+ * no error, then the reply was malformed, try submit() again.
+ * The return value of id() will be updated by this function, if possible.
+ */
+ void decode( QNetworkReply*, bool* lastfm_needs_a_complete_fingerprint = 0 );
+ };
+
+
+ class LASTFM_FINGERPRINT_DLLEXPORT CompleteFingerprint : public Fingerprint
{
- m_complete = true;
- }
-};
+ public:
+ CompleteFingerprint( const lastfm::Track& t ) : Fingerprint( t )
+ {
+ m_complete = true;
+ }
+ };
+}
#endif
View
19 lib/lastfm/fingerprint/libfingerprint.pro
@@ -1,20 +1,18 @@
TARGET = fingerprint
TEMPLATE = lib
QT += xml network sql
-CONFIG += dll types core ws
+CONFIG += dll types mad fftw3f samplerate
include( $$ROOT_DIR/admin/include.qmake )
include( _files.qmake )
+headers.files = Fingerprint.h
+headers.path = /include/lastfm
+INSTALLS = target headers
+
INCLUDEPATH += fplib/include
-mac*:release {
- LIBS += /opt/local/lib/libfftw3f.a
- LIBS += /opt/local/lib/libmad.a
- LIBS += /opt/local/lib/libsamplerate.a
- INCLUDEPATH += /opt/local/include
-}
-else:win32 {
+win32 {
INCLUDEPATH += $$ROOT_DIR/lib/3rdparty
LIBS += -llibsamplerate -llibfftw3f-3 -lmad
@@ -22,7 +20,4 @@ else:win32 {
DEFINES += __NO_THREAD_CHECK _FINGERPRINT_DLLEXPORT
QMAKE_LFLAGS_DEBUG += /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcmt.lib
-} else {
- CONFIG += link_pkgconfig
- PKGCONFIG += samplerate mad fftw3f
-}
+}
View
5 lib/lastfm/global.h
@@ -112,6 +112,8 @@ namespace lastfm
class AuthenticatedUser;
class Xspf;
class Playlist;
+ class Fingerprint;
+ class FingerprintId;
}
@@ -124,11 +126,14 @@ using lastfm::AuthenticatedUser;
using lastfm::Tag;
using lastfm::Xspf;
using lastfm::Playlist;
+using lastfm::Fingerprint;
+using lastfm::FingerprintId;
#endif
//convenience
class WsReply;
+class QNetworkReply;
//convenience for development
View
1  lib/lastfm/install_headers.sh
@@ -7,3 +7,4 @@ fi
for x in `../../admin/findsrc pro`; do ../../admin/penis $x --cp; done
mkdir -p $1/include
cp -R _include/lastfm $1/include
+cp global.h $1/include/lastfm
View
20 lib/lastfm/liblastfm.pro
@@ -1,21 +1,19 @@
TEMPLATE = lib
TARGET = lastfm
-QT = core network xml phonon
+QT = core network xml sql
VERSION = 0.2
+CONFIG += mad fftw3f samplerate
include( $$ROOT_DIR/admin/include.qmake )
include( _files.qmake )
INSTALLS = target
-target.path = $$INSTALL_DIR/lib
+target.path = /lib
+# nobody wants a phonon dependency
+SOURCES -= radio/Radio.cpp radio/LegacyTuner.cpp
+HEADERS -= radio/Radio.h radio/LegacyTuner.h
-# for now because it doesn't work anyway
-SOURCES -= fingerprint/Sha256.cpp \
- fingerprint/MP3_Source_Qt.cpp \
- fingerprint/fplib/src/OptFFT.cpp \
- fingerprint/fplib/src/FingerprintExtractor.cpp \
- fingerprint/fplib/src/Filter.cpp \
- fingerprint/Fingerprint.cpp \
- fingerprint/Collection.cpp
-
+DEFINES += _RADIO_DLLEXPORT _FINGERPRINT_DLLEXPORT _WS_DLLEXPORT _CORE_DLLEXPORT _TYPES_DLLEXPORT _SCROBBLE_DLLEXPORT
+
+macx*:LIBS += -framework Carbon -framework SystemConfiguration
View
2  lib/lastfm/radio/libradio.pro
@@ -7,6 +7,6 @@ DEFINES += _RADIO_DLLEXPORT LASTFM_COLLAPSE_NAMESPACE
include( $$ROOT_DIR/admin/include.qmake )
include( _files.qmake )
-headers.files = Radio.h RadioStation.h Tuner.h
+headers.files = RadioStation.h Tuner.h
headers.path = $$INSTALL_DIR/include/lastfm/radio
INSTALLS = target headers
View
56 lib/lastfm/types/FingerprintId.cpp
@@ -0,0 +1,56 @@
+/***************************************************************************
+ * Copyright 2005-2009 Last.fm Ltd. *
+ * *
+ * This program 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program 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 this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "lib/lastfm/types/FingerprintId.h"
+#include "lib/lastfm/ws/WsAccessManager.h"
+#include "lib/lastfm/ws/WsRequestBuilder.h"
+#include <QtNetwork>
+#include <QtXml>
+
+
+QNetworkReply*
+lastfm::FingerprintId::getSuggestions() const
+{
+ if (isNull()) return 0;
+
+ QUrl const url( "http://ws.audioscrobbler.com/fingerprint/" + QString(*this) + ".xml" );
+ QNetworkRequest const request( url );
+ return WsRequestBuilder::nam()->get( request );
+}
+
+
+QMap<float, lastfm::Track> //static
+lastfm::FingerprintId::getSuggestions( QNetworkReply* reply )
+{
+ QDomDocument xml;
+ xml.setContent( reply->readAll() );
+ QDomNodeList nodes = xml.documentElement().elementsByTagName( "track" );
+
+ QMap<float, Track> tracks;
+ for (int x = 0; x < nodes.count(); ++x)
+ {
+ QDomElement const e = nodes.at(x).toElement();
+
+ MutableTrack t;
+ t.setTitle( e.firstChildElement( "title" ).text() );
+ t.setArtist( e.firstChildElement( "artist" ).text() );
+ tracks.insert( e.attribute( "confidence", "0.0" ).toFloat(), t );
+ }
+ return tracks;
+}
View
42 lib/lastfm/types/FingerprintId.h
@@ -20,32 +20,42 @@
#ifndef LASTFM_FINGERPRINT_ID_H
#define LASTFM_FINGERPRINT_ID_H
-#include <lastfm/global.h>
+#include <lastfm/Track>
#include <QDebug>
+#include <QList>
#include <QString>
+class QNetworkReply;
+
-
-class LASTFM_TYPES_DLLEXPORT FingerprintId
+namespace lastfm
{
- int id;
+ class LASTFM_TYPES_DLLEXPORT FingerprintId
+ {
+ int id;
+
+ public:
+ FingerprintId() : id( -1 )
+ {}
-public:
- FingerprintId() : id( -1 )
- {}
+ FingerprintId( uint i ) : id( i )
+ {}
- FingerprintId( uint i ) : id( i )
- {}
+ bool isNull() const { return id == -1; }
- bool isNull() const { return id == -1; }
+ /** we query Last.fm for suggested metadata, how awesome is that?
+ * @returns null if isNull() */
+ QNetworkReply* getSuggestions() const;
+ static QMap<float,Track> getSuggestions( QNetworkReply* );
- /** -1 if you need to generate it */
- operator int() { return id; }
- /** isEmpty() if you need to generate it */
- operator QString() { return id == -1 ? "" : QString::number( id ); }
-};
+ /** -1 if you need to generate it */
+ operator int() const { return id; }
+ /** isEmpty() if you need to generate it */
+ operator QString() const { return id == -1 ? "" : QString::number( id ); }
+ };
+}
-inline QDebug operator<<( QDebug d, FingerprintId id)
+inline QDebug operator<<( QDebug d, lastfm::FingerprintId id)
{
if (id.isNull())
return d << "(null)";
View
7 lib/lastfm/types/Track.h
@@ -21,7 +21,6 @@
#define LASTFM_TRACK_H
#include <lastfm/Album>
-#include <lastfm/FingerprintId>
#include <lastfm/Mbid>
#include <QDateTime>
#include <QDomElement>
@@ -46,7 +45,7 @@ struct TrackData : QSharedData
short source;
short rating;
QString mbid; /// musicbrainz id
- int fpid;
+ uint fpid;
QUrl url;
QDateTime time; /// the time the track was started at
@@ -122,7 +121,7 @@ class LASTFM_TYPES_DLLEXPORT Track
QUrl url() const { return d->url; }
QDateTime timestamp() const { return d->time; }
Source source() const { return (Source)d->source; }
- FingerprintId fingerprintId() const { return d->fpid; }
+ uint fingerprintId() const { return d->fpid; }
QString durationString() const { return durationString( d->duration ); }
static QString durationString( int seconds );
@@ -205,7 +204,7 @@ class LASTFM_TYPES_DLLEXPORT MutableTrack : public Track
void setSource( Source s ) { d->source = s; }
void setMbid( Mbid id ) { d->mbid = id; }
- void setFingerprintId( int id ) { d->fpid = id; }
+ void setFingerprintId( uint id ) { d->fpid = id; }
/** you also must scrobble this track for the love to become permenant */
WsReply* love();
View
2  lib/lastfm/types/libtypes.pro
@@ -9,5 +9,5 @@ include( _files.qmake )
DEFINES += _TYPES_DLLEXPORT
headers.files = Track.h Mbid.h Artist.h Album.h FingerprintId.h Playlist.h Tag.h User.h Xspf.h
-headers.path = $$INSTALL_DIR/include/lastfm/types
+headers.path = /include/lastfm
INSTALLS = target headers
View
25 lib/lastfm/ws/WsRequestBuilder.cpp
@@ -29,7 +29,7 @@
#include <QThread>
-QThreadStorage<WsAccessManager*> WsRequestBuilder::nam;
+QThreadStorage<WsAccessManager*> WsRequestBuilder::nam_store;
WsRequestBuilder::WsRequestBuilder( const QString& method )
@@ -37,13 +37,6 @@ WsRequestBuilder::WsRequestBuilder( const QString& method )
static QMutex lock;
QMutexLocker locker( &lock );
- if (!nam.hasLocalData())
- {
- // WsAccessManager will be unparented, but it
- // does gets cleaned up when this thread ends
- nam.setLocalData( new WsAccessManager( 0 ) );
- }
-
params["method"] = method;
}
@@ -86,7 +79,7 @@ WsRequestBuilder::start( RequestMethod method )
QByteArray const value = QUrl::toPercentEncoding( pair.second );
url.addEncodedQueryItem( key, value );
}
- return new WsReply( nam.localData()->get( QNetworkRequest( url ) ) );
+ return new WsReply( nam()->get( QNetworkRequest( url ) ) );
}
case Post:
@@ -99,8 +92,20 @@ WsRequestBuilder::start( RequestMethod method )
+ QUrl::toPercentEncoding( param.second )
+ "&";
}
- return new WsReply( nam.localData()->post( QNetworkRequest( url ), query ) );
+ return new WsReply( nam()->post( QNetworkRequest( url ), query ) );
}
}
return 0;
}
+
+
+WsAccessManager* //static private
+WsRequestBuilder::nam()
+{
+ if (!nam_store.hasLocalData())
+ // WsAccessManager will be unparented, but it
+ // does gets cleaned up when this thread ends
+ nam_store.setLocalData( new WsAccessManager );
+
+ return nam_store.localData();
+}
View
7 lib/lastfm/ws/WsRequestBuilder.h
@@ -29,13 +29,18 @@
* We add the session key, api signature and session key to every request */
class LASTFM_WS_DLLEXPORT WsRequestBuilder
{
- static QThreadStorage<class WsAccessManager*> nam; // one per thread
+ static QThreadStorage<class WsAccessManager*> nam_store; // one per thread
QMap<QString, QString> params;
+ static WsAccessManager* nam();
+
enum RequestMethod { Get, Post };
/** starts the request, connect to finished() to get the results */
WsReply* start( RequestMethod );
+ friend class lastfm::FingerprintId;
+ friend class lastfm::Fingerprint;
+
public:
WsRequestBuilder( const QString& methodName );
View
2  lib/lastfm/ws/libws.pro
@@ -16,5 +16,5 @@ win32 {
macx*:LIBS += -framework SystemConfiguration
headers.files = WsAccessManager.h WsError.h WsKeys.h WsRequestBuilder.h WsReply.h WsDomElement.h
-headers.path = $$INSTALL_DIR/include/lastfm/ws
+headers.path = $$INSTALL_DIR/include/lastfm
INSTALLS = target headers
Please sign in to comment.
Something went wrong with that request. Please try again.