|
|
|
/***************************************************************************
|
|
|
|
* copyright : (C) 2006 Chris Muehlhaeuser <chris@chris.de> *
|
|
|
|
* : (C) 2006 Seb Ruiz <me@sebruiz.net> *
|
|
|
|
* : (C) 2006 Ian Monroe <ian@monroe.nu> *
|
|
|
|
* : (C) 2006 Mark Kretschmann <markey@web.de> *
|
|
|
|
**************************************************************************/
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* *
|
|
|
|
* 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. *
|
|
|
|
* *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#ifndef AMAROK_LASTFM_H
|
|
|
|
#define AMAROK_LASTFM_H
|
|
|
|
|
|
|
|
#include "metabundle.h"
|
|
|
|
|
|
|
|
#include <tqhttp.h>
|
|
|
|
#include <tqobject.h>
|
|
|
|
#include <tqserversocket.h>
|
|
|
|
#include <tqurl.h>
|
|
|
|
#include <tqvaluelist.h>
|
|
|
|
|
|
|
|
#include <kconfigdialog.h>
|
|
|
|
|
|
|
|
class KLineEdit;
|
|
|
|
class KAction;
|
|
|
|
class KProcIO;
|
|
|
|
class KURL;
|
|
|
|
class TQSocket;
|
|
|
|
class TQTimer;
|
|
|
|
|
|
|
|
namespace KIO { class Job; }
|
|
|
|
|
|
|
|
/* AmarokHttp is a hack written so that lastfm code could easily use something proxy aware.
|
|
|
|
DO NOT use this class for anything else, use KIO directly instead. */
|
|
|
|
class AmarokHttp : public TQObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
AmarokHttp ( const TQString & hostname, TQ_UINT16 port = 80, TQObject* parent = 0 );
|
|
|
|
int get ( const TQString & path );
|
|
|
|
TQHttp::State state() const;
|
|
|
|
TQByteArray readAll ();
|
|
|
|
TQHttp::Error error();
|
|
|
|
|
|
|
|
signals:
|
|
|
|
void requestFinished ( int id, bool error );
|
|
|
|
|
|
|
|
protected slots:
|
|
|
|
void slotData(KIO::Job*, const TQByteArray& );
|
|
|
|
void slotResult(KIO::Job*);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
TQString m_hostname;
|
|
|
|
TQ_UINT16 m_port;
|
|
|
|
TQString m_path;
|
|
|
|
TQHttp::State m_state;
|
|
|
|
TQHttp::Error m_error;
|
|
|
|
bool m_done;
|
|
|
|
TQByteArray m_result;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
namespace LastFm
|
|
|
|
{
|
|
|
|
class WebService;
|
|
|
|
|
|
|
|
class Controller : public TQObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
static Controller* instance();
|
|
|
|
|
|
|
|
KURL getNewProxy( TQString genreUrl, bool useProxy );
|
|
|
|
int changeStation ( TQString url );
|
|
|
|
|
|
|
|
bool isPlaying() const { return m_service != 0; }
|
|
|
|
WebService* getService() const { return m_service; }
|
|
|
|
TQString getGenreUrl() const { return m_genreUrl; }
|
|
|
|
|
|
|
|
static bool checkCredentials();
|
|
|
|
static TQString createCustomStation();
|
|
|
|
static TQString stationDescription( TQString url = TQString() ); // necessary for translation
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
void playbackStopped();
|
|
|
|
void ban();
|
|
|
|
void love();
|
|
|
|
void skip();
|
|
|
|
|
|
|
|
private:
|
|
|
|
Controller();
|
|
|
|
void setActionsEnabled( bool enable );
|
|
|
|
|
|
|
|
static Controller *s_instance;
|
|
|
|
TQPtrList<KAction> m_actionList;
|
|
|
|
|
|
|
|
TQString m_genreUrl;
|
|
|
|
WebService* m_service;
|
|
|
|
};
|
|
|
|
|
|
|
|
class WebService : public TQObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
enum DataType { Artist, Album, Track };
|
|
|
|
|
|
|
|
WebService( TQObject* parent, bool useProxy );
|
|
|
|
~WebService();
|
|
|
|
|
|
|
|
bool handshake( const TQString& username, const TQString& password );
|
|
|
|
|
|
|
|
bool changeStation( TQString url );
|
|
|
|
TQString currentUsername() const { return m_username; }
|
|
|
|
TQString currentPassword() const { return m_password; }
|
|
|
|
TQString currentStation() const { return m_station; }
|
|
|
|
TQString session() const { return m_session; }
|
|
|
|
TQUrl streamUrl() const { return m_streamUrl; }
|
|
|
|
|
|
|
|
void friends( TQString username );
|
|
|
|
void neighbours( TQString username );
|
|
|
|
|
|
|
|
void recentTracks( TQString username );
|
|
|
|
void userTags( TQString username );
|
|
|
|
|
|
|
|
void recommend( int type, TQString username, TQString artist, TQString token = TQString() );
|
|
|
|
|
|
|
|
void recommendArtist( TQString username, TQString artist )
|
|
|
|
{ recommend( WebService::Artist, username, artist ); }
|
|
|
|
|
|
|
|
void recommendAlbum( TQString username, TQString artist, TQString album )
|
|
|
|
{ recommend( WebService::Album, username, artist, album ); }
|
|
|
|
|
|
|
|
void recommendTrack( TQString username, TQString artist, TQString track )
|
|
|
|
{ recommend( WebService::Track, username, artist, track ); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Verify with server that a supplied user/pass combo is valid. Password
|
|
|
|
should be MD5 hashed.
|
|
|
|
**/
|
|
|
|
void verifyUser( const TQString& user, const TQString& pass );
|
|
|
|
|
|
|
|
bool cancel();
|
|
|
|
bool wasCanceled() const { return m_wasCanceled; }
|
|
|
|
|
|
|
|
TQString proxyUrl() { return m_proxyUrl; }
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
void requestMetaData();
|
|
|
|
void enableScrobbling( bool enabled );
|
|
|
|
|
|
|
|
void love();
|
|
|
|
void skip();
|
|
|
|
void ban();
|
|
|
|
|
|
|
|
signals:
|
|
|
|
void actionStarted();
|
|
|
|
void actionFinished();
|
|
|
|
|
|
|
|
void stationChanged( TQString url, TQString name );
|
|
|
|
void songQueued();
|
|
|
|
|
|
|
|
void metaDataResult( const MetaBundle &bundle );
|
|
|
|
void enableScrobblingDone();
|
|
|
|
|
|
|
|
void loveDone();
|
|
|
|
void skipDone();
|
|
|
|
void banDone();
|
|
|
|
|
|
|
|
void friendsResult( const TQString& username, const TQStringList& friends );
|
|
|
|
void neighboursResult( const TQString& username, const TQStringList& friends );
|
|
|
|
|
|
|
|
void recentTracksResult( const TQString& username, TQValueList< TQPair<TQString, TQString> > songs );
|
|
|
|
void userTagsResult( const TQString& username, const TQStringList& tags );
|
|
|
|
|
|
|
|
private:
|
|
|
|
enum errorCode { E_NOCONTENT = 1, E_NOMEMBERS = 2, E_NOFANS = 3, E_NOAVAIL = 4, E_NOSUBSCRIBER = 5,
|
|
|
|
E_NONEIGHBOURS = 6, E_NOSTOPPED = 7, E_OTHER = 0 };
|
|
|
|
|
|
|
|
void showError( int code, TQString message = TQString() );
|
|
|
|
|
|
|
|
bool m_useProxy;
|
|
|
|
|
|
|
|
TQString parameter( const TQString keyName, const TQString data ) const;
|
|
|
|
TQStringList parameterArray( const TQString keyName, const TQString data ) const;
|
|
|
|
TQStringList parameterKeys( const TQString keyName, const TQString data ) const;
|
|
|
|
|
|
|
|
TQString m_username; // login username
|
|
|
|
TQString m_password; // login password
|
|
|
|
TQString m_station; // the url of the station
|
|
|
|
TQString m_session; // session id that last.fm provides
|
|
|
|
TQString m_baseHost; // who are we connecting to?
|
|
|
|
TQString m_basePath; // where are we connecting to!
|
|
|
|
TQUrl m_streamUrl; // last.fm webserver for direct connection (proxy connects to this)
|
|
|
|
bool m_subscriber; // self explanatory
|
|
|
|
|
|
|
|
KProcIO* m_server;
|
|
|
|
|
|
|
|
TQString m_proxyUrl;
|
|
|
|
MetaBundle m_metaBundle;
|
|
|
|
|
|
|
|
bool m_deletionUnsafe;
|
|
|
|
bool m_wasCanceled;
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void readProxy();
|
|
|
|
void metaDataFinished( int id, bool error );
|
|
|
|
void fetchImageFinished( KIO::Job* );
|
|
|
|
void enableScrobblingFinished( int id, bool error );
|
|
|
|
|
|
|
|
void loveFinished( int id, bool error );
|
|
|
|
void skipFinished( int id, bool error );
|
|
|
|
void banFinished( int id, bool error );
|
|
|
|
|
|
|
|
void friendsFinished( int id, bool error );
|
|
|
|
void neighboursFinished( int id, bool error );
|
|
|
|
|
|
|
|
void recentTracksFinished( int id, bool error );
|
|
|
|
void userTagsFinished( int id, bool error );
|
|
|
|
|
|
|
|
void recommendFinished( int id, bool error );
|
|
|
|
};
|
|
|
|
|
|
|
|
class Bundle
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Bundle() {};
|
|
|
|
Bundle( const Bundle& bundle);
|
|
|
|
TQString imageUrl() const { return m_imageUrl; }
|
|
|
|
void setImageUrl( const TQString& imageUrl ) { m_imageUrl = imageUrl; }
|
|
|
|
|
|
|
|
TQString artistUrl() const { return m_artistUrl; }
|
|
|
|
void setArtistUrl( const TQString& theValue ) { m_artistUrl = theValue; }
|
|
|
|
|
|
|
|
TQString albumUrl() const { return m_albumUrl; }
|
|
|
|
void setAlbumUrl( const TQString& theValue ) { m_albumUrl = theValue; }
|
|
|
|
|
|
|
|
TQString titleUrl() const { return m_titleUrl; }
|
|
|
|
void setTitleUrl( const TQString& theValue ) { m_titleUrl = theValue; }
|
|
|
|
|
|
|
|
void detach(); // for being able to apply TQDeepCopy<>
|
|
|
|
|
|
|
|
private:
|
|
|
|
TQString m_imageUrl;
|
|
|
|
TQString m_albumUrl;
|
|
|
|
TQString m_artistUrl;
|
|
|
|
TQString m_titleUrl;
|
|
|
|
};
|
|
|
|
|
|
|
|
// We must implement this because TQServerSocket has one pure virtual method.
|
|
|
|
// It's just used for finding a free port.
|
|
|
|
class MyServerSocket : public TQServerSocket
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
MyServerSocket() : TQServerSocket( TQ_UINT16( 0 ) ) {}
|
|
|
|
|
|
|
|
private:
|
|
|
|
void newConnection( int ) {}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
class LoginDialog : public KDialogBase
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
LoginDialog( TQWidget *parent );
|
|
|
|
|
|
|
|
protected slots:
|
|
|
|
void slotOk();
|
|
|
|
|
|
|
|
private:
|
|
|
|
KLineEdit *m_userLineEdit;
|
|
|
|
KLineEdit *m_passLineEdit;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
class CustomStationDialog : public KDialogBase
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
CustomStationDialog( TQWidget *parent );
|
|
|
|
|
|
|
|
TQString text() const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
KLineEdit *m_edit;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /*AMAROK_LASTFM_H*/
|