summaryrefslogtreecommitdiffstats
path: root/amarok/src/lastfm.h
blob: 5046da64e307d8627736d5c9f6f64378661c05de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
/***************************************************************************
 * 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 QObject
{
    Q_OBJECT

    public:
    AmarokHttp ( const TQString & hostname, Q_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;
    Q_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 QObject
    {
        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::null );   // 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 QObject
    {
        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< QPair<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::null );

            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 QServerSocket
    {
        public:
            MyServerSocket() : TQServerSocket( Q_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*/