1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-29 16:50:11 +02:00

Add liblastfm2 and make tomahawk build against it

This commit is contained in:
Jeff Mitchell
2011-03-24 19:18:42 -04:00
parent 1780781e12
commit b7a1cb8d99
114 changed files with 14711 additions and 3 deletions

95
thirdparty/liblastfm2/demos/demo1.cpp vendored Normal file
View File

@@ -0,0 +1,95 @@
/*
This software is in the public domain, furnished "as is", without technical
support, and with no warranty, express or implied, as to its usefulness for
any purpose.
*/
#include <lastfm.h> // this includes everything in liblastfm, you may prefer
#include <QtCore> // to just include what you need with your project. Still
#include <QtGui> // we've given you the option.
#include <QPointer>
#include <QNetworkReply>
class ArtistList : public QListWidget
{
Q_OBJECT
QPointer<QNetworkReply> reply;
QString artist;
public:
ArtistList()
{
connect( this,
SIGNAL(itemActivated( QListWidgetItem* )),
SLOT(onItemActivated( QListWidgetItem* )) );
}
void getSimilar( const QString& artist )
{
this->artist = artist;
setWindowTitle( "Loading " + artist + "..." );
// deleting a reply cancels the request and disconnects all signals
delete reply;
reply = lastfm::Artist( artist ).getSimilar();
connect( reply, SIGNAL(finished()), SLOT(onGotSimilar()) );
}
private slots:
void onGotSimilar()
{
QNetworkReply* r = static_cast<QNetworkReply*>(sender());
// always enclose retrieval functions in a try block, as they will
// throw if they can't parse the data
try
{
// you decode the response using the equivalent static function
QMap<int, QString> artists = lastfm::Artist::getSimilar( r );
clear();
// we iterate backwards because best match is last because the map
// sorts itself by key
QStringListIterator i( artists.values() );
i.toBack();
while (i.hasPrevious())
addItem( i.previous() );
setWindowTitle( artist );
}
catch (std::runtime_error& e)
{
// if getSimilar() failed to parse the QNetworkReply, then e will
// be of type lastfm::ws::ParseError, which derives
// std::runtime_error
qWarning() << e.what();
}
}
void onItemActivated( QListWidgetItem* item )
{
getSimilar( item->text() );
}
};
int main( int argc, char** argv )
{
QApplication app( argc, argv );
app.setApplicationName( "liblastfm" ); // used to generate UserAgent
// all you need for non-authenticated webservices is your API key
// this one is a public one, it can only do artist.getSimilar calls, so
// I suggest you don't use it :P
lastfm::ws::ApiKey = "b25b959554ed76058ac220b7b2e0a026";
ArtistList artists;
artists.getSimilar( "nirvana" );
artists.resize( 300, 400 ); // Qt picks truly asanine default sizes for its widgets
artists.show();
return app.exec();
}
#include "demo1.moc"

114
thirdparty/liblastfm2/demos/demo2.cpp vendored Normal file
View File

@@ -0,0 +1,114 @@
/*
This software is in the public domain, furnished "as is", without technical
support, and with no warranty, express or implied, as to its usefulness for
any purpose.
*/
#include <lastfm.h>
#include <QtCore>
struct MyCoreApp : QCoreApplication
{
Q_OBJECT
public:
MyCoreApp( int& argc, char**& argv ) : QCoreApplication( argc, argv )
{}
private slots:
void onWsError( lastfm::ws::Error e )
{
// QNetworkReply will invoke this slot on application level errors
// mostly this is only stuff like Ws::InvalidSessionKey and
// Ws::InvalidApiKey
qWarning() << e;
}
};
int main( int argc, char** argv )
{
MyCoreApp app( argc, argv );
// this is used to generate the UserAgent for webservice requests
// please set it to something sensible in your application
app.setApplicationName( "liblastfm" );
////// you'll need to fill these in for this demo to work
lastfm::ws::Username =
lastfm::ws::ApiKey =
lastfm::ws::SharedSecret =
QString password =
////// Usually you never have to construct an Last.fm WS API call manually
// eg. Track.getTopTags() just returns a QNetworkReply* but authentication is
// different.
// We're using getMobileSession here as we're a console app, but you
// should use getToken if you can as the user will be presented with a
// route that feels my trustworthy to them than entering their password
// into some random app they just downloaded... ;)
QMap<QString, QString> params;
params["method"] = "auth.getMobileSession";
params["username"] = lastfm::ws::Username;
params["authToken"] = lastfm::md5( (lastfm::ws::Username + lastfm::md5( password.toUtf8() )).toUtf8() );
QNetworkReply* reply = lastfm::ws::post( params );
// never do this when an event loop is running it's a real HACK
QEventLoop loop;
loop.connect( reply, SIGNAL(finished()), SLOT(quit()) );
loop.exec();
try
{
////// Usually there is a convenience function to decode the output from
// ws calls too, but again, authentication is different. We think you
// need to handle it yourselves :P Also conveniently it means you
// can learn more about what our webservices return, eg. this service
// will return an XML document like this:
//
// <lfm status="ok">
// <session>
// <name>mxcl</name>
// <key>d580d57f32848f5dcf574d1ce18d78b2</key>
// <subscriber>1</subscriber>
// </session>
// </lfm>
//
// If status is not "ok" then this function throws
lastfm::XmlQuery const lfm = lastfm::ws::parse( reply );
// replace username; because eg. perhaps the user typed their
// username with the wrong case
lastfm::ws::Username = lfm["session"]["name"].text();
// we now have a session key, you should save this, forever! Really.
// DO NOT AUTHENTICATE EVERY TIME THE APP STARTS! You only have to do
// this once. Or again if the user deletes your key on the site. If
// that happens you'll get notification to your onWsError() function,
// see above.
lastfm::ws::SessionKey = lfm["session"]["key"].text();
qDebug() << "sk:" << lastfm::ws::SessionKey;
////// because the SessionKey is now set, the AuthenticatedUser class will
// work. And we can call authenticated calls
QNetworkReply* reply = lastfm::AuthenticatedUser().getRecommendedArtists();
// again, you shouldn't do this.. ;)
QEventLoop loop;
loop.connect( reply, SIGNAL(finished()), SLOT(quit()) );
loop.exec();
// yay, a list rec'd artists to stderr :)
qDebug() << lastfm::Artist::list( reply );
}
catch (std::runtime_error& e)
{
// lastfm::ws::parse() can throw lastfm::ws::ParseError, this
// exception derives std::runtime_error
qWarning() << e.what();
return 1;
}
}
#include "demo2.moc"

63
thirdparty/liblastfm2/demos/demo3.cpp vendored Normal file
View File

@@ -0,0 +1,63 @@
/*
This software is in the public domain, furnished "as is", without technical
support, and with no warranty, express or implied, as to its usefulness for
any purpose.
*/
#include <lastfm.h>
#include <QtCore>
#include <QtNetwork>
#include "src/_version.h"
struct MyCoreApp : QCoreApplication
{
Q_OBJECT
public:
MyCoreApp( int& argc, char** argv ) : QCoreApplication( argc, argv )
{}
public slots:
void onStatus( int status )
{
qDebug() << lastfm::Audioscrobbler::Status(status);
}
};
int main( int argc, char** argv )
{
// all 6 of these lines are REQUIRED in order to scrobble
// this demo requires you to fill in the blanks as well...
lastfm::ws::Username =
lastfm::ws::ApiKey =
lastfm::ws::SharedSecret =
lastfm::ws::SessionKey = // you need to auth to get this... try demo2
QCoreApplication::setApplicationName( "liblastfm" );
QCoreApplication::setApplicationVersion( VERSION );
MyCoreApp app( argc, argv );
lastfm::MutableTrack t;
t.setArtist( "Max Howell" );
t.setTitle( "I Told You Not To Trust Me With Your Daughter" );
t.setDuration( 30 );
t.stamp(); //sets track start time
lastfm::Audioscrobbler as( "ass" );
as.nowPlaying( t );
// Audioscrobbler will submit whatever is in the cache when you call submit.
// And the cache is persistent between sessions. So you should cache at the
// scrobble point usually, not before
as.cache( t );
//FIXME I don't get it, but the timer never triggers! pls fork and fix!
QTimer::singleShot( 31*1000, &as, SLOT(submit()) );
app.connect( &as, SIGNAL(status(int)), SLOT(onStatus(int)) );
return app.exec();
}
#include "demo3.moc"

3
thirdparty/liblastfm2/demos/demos.pro vendored Normal file
View File

@@ -0,0 +1,3 @@
QT = core gui network xml
LIBS += -llastfm -L$$DESTDIR
SOURCES = demo1.cpp # change to demo2.cpp (etc.) to compile that demo