Logo Search packages:      
Sourcecode: lastfm version File versions  Download package

webserviceconnector.cpp

/***************************************************************************
 *   Copyright (C) 2005 - 2006 by Christian Muehlhaeuser, Last.fm Ltd.     *
 *   chris@last.fm                                                         *
 *                                                                         *
 *   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  02111-1307, USA.          *
 ***************************************************************************/

#include <QDomDocument>
#include <QFile>
#include <QHttp>
#include <QMessageBox>
#include <QTcpSocket>
#include <QTimer>
#include <QUrl>

#include "playback.h"
#include "playlist.h"
#include "settings.h"
#include "song.h"
#include "webserviceconnector.h"


WebserviceConnector *WebserviceConnector::s_instance = 0;

WebserviceConnector::WebserviceConnector()
    : m_connected( false )
    , m_lastSong( new Song() )
    , m_refreshTimer( 0 )
{
    s_instance = this;
}


WebserviceConnector::~WebserviceConnector()
{
    delete m_lastSong;
    delete m_refreshTimer;
}


QString
WebserviceConnector::parameter( QString keyName, QString data )
{
    QStringList list = data.split( "\n" );

    for ( int i = 0; i < list.size(); i++ )
    {
        QStringList values = list[ i ].split( "=" );
        if ( values[0] == keyName )
        {
            values.removeAt( 0 );
            return QString().fromUtf8( values.join( "=" ).toAscii() );
        }
    }

    return QString( "" );
}


QStringList
WebserviceConnector::parameterArray( QString keyName, QString data )
{
    QStringList result;
    QStringList list = data.split( "\n" );

    for ( int i = 0; i < list.size(); i++ )
    {
        QStringList values = list[ i ].split( "=" );
        if ( values[0].startsWith( keyName ) )
        {
            values.removeAt( 0 );
            result.append( QString().fromUtf8( values.join( "=" ).toAscii() ) );
        }
    }

    return result;
}


QStringList
WebserviceConnector::parameterKeys( QString keyName, QString data )
{
    QStringList result;
    QStringList list = data.split( "\n" );

    for ( int i = 0; i < list.size(); i++ )
    {
        QStringList values = list[ i ].split( "=" );
        if ( values[0].startsWith( keyName ) )
        {
            values = values[0].split( "[" );
            values = values[1].split( "]" );
            result.append( values[0] );
        }
    }

    return result;
}


void
WebserviceConnector::stackAppend( QHttp *http )
{
    for ( int i = 0; i < m_httpStack.size(); i++ )
    {
        QHttp *http = stackGet( i );

        if ( http && http->state() == QHttp::Unconnected )
            delete http;
    }

    if ( m_httpStack.size() == 0 )
        emit actionStarted();

    m_httpStack.insert( http->currentId(), http );
}


QHttp*
WebserviceConnector::stackGet( int id )
{
    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        return m_httpStack.value( id - 1 );
    else
        return m_httpStack.value( id );
}


void
WebserviceConnector::stackRemove( int id, bool keepAnimation )
{
    QHttp *http;

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        http = m_httpStack.take( id - 1 );
    else
        http = m_httpStack.take( id );

    if ( http )
        http->close();

    if ( m_httpStack.size() == 0 && !keepAnimation )
        emit actionFinished();
}


void
WebserviceConnector::errorCode( int id, QString errorMessage )
{
    switch ( id )
    {
        case 1:
            QMessageBox::information( 0, "Error", "There is not enough content to play this station.\n" );
            break;
        case 2:
            QMessageBox::information( 0, "Error", "This group does not have enough members for radio.\n" );
            break;
        case 3:
            QMessageBox::information( 0, "Error", "This artist does not have enough fans for radio.\n" );
            break;
        case 4:
            QMessageBox::information( 0, "Error", "This item is not available for streaming.\n" );
            break;
        case 5:
            QMessageBox::information( 0, "Error", "This feature is only available to subscribers.\n" );
            break;
        case 6:
            QMessageBox::information( 0, "Error", "There are not enough neighbours for this radio.\n" );
            break;
        case 7:
            QMessageBox::information( 0, "Error", "This stream has stopped! Please try another station!\n" );
            break;
        default:
            QMessageBox::information( 0, "Error", errorMessage.isEmpty() ? "There was an error!" : errorMessage );
    }
}


void
WebserviceConnector::handshake( QString username, QString password )
{
    QString platform;
    #ifdef WIN32
    platform = "win32";
    #endif
    #ifdef Q_WS_X11
    platform = "linux";
    #endif
    #ifdef Q_WS_MAC
    platform = "mac";
    #endif

    QHttp *http = new QHttp( Settings::instance()->debug() ? "wsdev.audioscrobbler.com" : "ws.audioscrobbler.com", 80, this );

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
         http->setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );

    connect( http, SIGNAL( responseHeaderReceived( QHttpResponseHeader ) ), this, SLOT( handshakeHeaderReceived( QHttpResponseHeader ) ) );
    connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( handshakeFinished( int, bool ) ) );

    http->get( QString( "/radio/handshake.php?version=%1&platform=%2&username=%3&passwordmd5=%4&debug=%5" )
                  .arg( Settings::instance()->version() )
                  .arg( platform )
                  .arg( QString( QUrl( username ).toEncoded() ) )
                  .arg( password )
                  .arg( Settings::instance()->debug() ? "1" : "0" ) );

    stackAppend( http );
}


void
WebserviceConnector::handshakeHeaderReceived( const QHttpResponseHeader &resp )
{
    if ( resp.statusCode() == 503 )
    {
        QMessageBox::information( 0, "Attention", resp.reasonPhrase() );
        QCoreApplication::quit();
    }
}


void
WebserviceConnector::handshakeFinished( int id, bool error )
{
    QHttp *http = stackGet( id );
    if ( !http )
        return;

    if ( error )
    {
      qDebug() << http->error();
      qDebug() << http->errorString();
    }

    QString result( http->readAll() );
    if ( Settings::instance()->debug() )
        qDebug() << "Handshake:" << result;

    if ( error )
    {
        emit handshakeResult( false, false, QUrl() );
        return;
    }

    m_session = parameter( "session", result );
    if ( m_session.toLower() == "failed" )
        m_session = "";

    QString streamUrl = parameter( "stream_url", result );
    QString updateUrl = parameter( "update_url", result );
    m_baseHost = parameter( "base_url", result );
    m_basePath = parameter( "base_path", result );

    m_subscriber = parameter( "subscriber", result ) == "1";
    bool banned = parameter( "banned", result ) == "1";

    if ( !updateUrl.isEmpty() && banned )
    {
        QMessageBox::critical( 0, "Update available",
                                    "This outdated version of the Last.fm Radio is not compatible with our service anymore!\nGo to www.last.fm and download the latest version!",
                                    "O&K", QString(), QString(), 0, 1 );
        Settings::instance()->startBrowser( updateUrl );
//         QApplication::quit();
    }
    else
    if ( !updateUrl.isEmpty() )
    {
        QMessageBox::information( 0, "Update available",
                                       "There is a new version of Last.fm Radio available!\nGo to www.last.fm to download the latest version!",
                                       "O&K", QString(), QString(), 0, 1 );
        Settings::instance()->startBrowser( updateUrl );
    }

    stackRemove( id );
    m_connected = ( m_session.length() == 32 );

    if ( m_session.length() > 0 )
        emit handshakeResult( true, m_connected, QUrl( streamUrl ) );
}


void
WebserviceConnector::searchArtist( QString artist )
{
    QHttp *http = new QHttp( m_baseHost, 80, this );
    connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( searchArtistFinished( int, bool ) ) );

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        http->setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );

    http->get( QString( "/1.0/get.php?resource=artist&document=similar&format=xml&artist=%1&debug=%2" )
//     http->get( QString( "/1.0/artist/%1/similar.xml?debug=%2" )
                  .arg( QString( QUrl( artist ).toEncoded() ) )
                  .arg( Settings::instance()->debug() ? "1" : "0" ) );

    stackAppend( http );
}


void
WebserviceConnector::searchTag( QString tag )
{
    QHttp *http = new QHttp( m_baseHost, 80, this );
    connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( searchTagFinished( int, bool ) ) );

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        http->setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );

    http->get( QString( "/1.0/tag/%1/search.xml?showtop10=1" )
                  .arg( QString( QUrl( tag ).toEncoded() ) ) );
//                   .arg( Settings::instance()->debug() ? "1" : "0" ) );

    stackAppend( http );
}


void
WebserviceConnector::tagsForArtist( QString artist )
{
    QHttp *http = new QHttp( m_baseHost, 80, this );
    connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( tagsForArtistFinished( int, bool ) ) );

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        http->setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );

    http->get( QString( "/1.0/artist/%1/toptags.xml?debug=%2" )
                  .arg( QString( QUrl( artist ).toEncoded() ) )
                  .arg( Settings::instance()->debug() ? "1" : "0" ) );

    stackAppend( http );
}


void
WebserviceConnector::tagsForUser( QString user )
{
    QHttp *http = new QHttp( m_baseHost, 80, this );
    connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( tagsForUserFinished( int, bool ) ) );

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        http->setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );
    http->get( QString( "/1.0/user/%1/tags.xml?debug=%2" )
                  .arg( QString( QUrl( user ).toEncoded() ) )
                  .arg( Settings::instance()->debug() ? "1" : "0" ) );

    stackAppend( http );
}


void
WebserviceConnector::tagsForUserArtist( QString user, QString artist )
{
    QHttp *http = new QHttp( m_baseHost, 80, this );
    connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( tagsForUserArtistFinished( int, bool ) ) );

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        http->setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );
    http->get( QString( "/1.0/user/%1/artisttags.xml?artist=%2&debug=%3" )
                  .arg( QString( QUrl( user ).toEncoded() ) )
                  .arg( QString( QUrl( artist ).toEncoded() ) )
                  .arg( Settings::instance()->debug() ? "1" : "0" ) );

    stackAppend( http );
}


void
WebserviceConnector::tagsForUserTrack( QString user, QString artist, QString track )
{
    QHttp *http = new QHttp( m_baseHost, 80, this );
    connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( tagsForUserTrackFinished( int, bool ) ) );

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        http->setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );
    http->get( QString( "/1.0/user/%1/tracktags.xml?artist=%2&track=%3&debug=%4" )
                  .arg( QString( QUrl( user ).toEncoded() ) )
                  .arg( QString( QUrl( artist ).toEncoded() ) )
                  .arg( QString( QUrl( track ).toEncoded() ) )
                  .arg( Settings::instance()->debug() ? "1" : "0" ) );

    stackAppend( http );
}


void
WebserviceConnector::tagsForUserAlbum( QString user, QString artist, QString album )
{
    QHttp *http = new QHttp( m_baseHost, 80, this );
    connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( tagsForUserAlbumFinished( int, bool ) ) );

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        http->setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );
    http->get( QString( "/1.0/user/%1/albumtags.xml?artist=%2&album=%3&debug=%4" )
                  .arg( QString( QUrl( user ).toEncoded() ) )
                  .arg( QString( QUrl( artist ).toEncoded() ) )
                  .arg( QString( QUrl( album ).toEncoded() ) )
                  .arg( Settings::instance()->debug() ? "1" : "0" ) );

    stackAppend( http );
}


void
WebserviceConnector::setTag( Song *song, int mode, QString tag )
{
    qDebug() << "Adding tags";
    QString modeToken = "";
    switch ( mode )
    {
        case 0:
            modeToken = QString( "artist=%1" ).arg( QString( QUrl( song->artist() ).toEncoded() ) );
            break;

        case 1:
            modeToken = QString( "album=%1&artist=%2" )
                           .arg( QString( QUrl( song->album() ).toEncoded() ) )
                           .arg( QString( QUrl( song->artist() ).toEncoded() ) );
            break;

        case 2:
            modeToken = QString( "track=%1&artist=%2" )
                           .arg( QString( QUrl( song->track() ).toEncoded() ) )
                           .arg( QString( QUrl( song->artist() ).toEncoded() ) );
            break;
    }

    QHttp *http = new QHttp( m_baseHost, 80, this );
    connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( setTagFinished( int, bool ) ) );

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        http->setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );

/*    http->get( QString( "/player/tag.php?s=%1&tag=%2&%3" )
                  .arg( m_session )
                  .arg( QString( QUrl( tag ).toEncoded() ) )
                  .arg( modeToken ) );*/

    QString token = QString( "s=%1&tag=%2&" + modeToken )
                       .arg( m_session )
                       .arg( QString( QUrl( tag ).toEncoded() ) );

    QHttpRequestHeader header( "POST", "/player/tag.php" );
    header.setValue( "Host", m_baseHost );
    header.setContentType( "application/x-www-form-urlencoded" );
    http->request( header, token.toUtf8() );

    stackAppend( http );
}


void
WebserviceConnector::searchArtistFinished( int id, bool error )
{
    QHttp *http = stackGet( id );
    if ( !http || error || http->bytesAvailable() <= 0 )
    {
        stackRemove( id );
        return;
    }

    QDomDocument document;
    document.setContent( http->readAll() );

    QStringList artists;
    QStringList images;
    if ( document.elementsByTagName( "similarartists" ).length() == 0 )
    {
        stackRemove( id );
        emit searchArtistResult( QString( "" ), QString( "" ), false, artists, QStringList() );
        return;
    }

    QString artist  = document.elementsByTagName( "similarartists" ).item( 0 ).attributes().namedItem( "artist" ).nodeValue();
    QString image  = document.elementsByTagName( "similarartists" ).item( 0 ).attributes().namedItem( "picture" ).nodeValue();
    bool streamable = ( document.elementsByTagName( "similarartists" ).item( 0 ).attributes().namedItem( "streamable" ).nodeValue() == "1" );

    QDomNodeList values = document.elementsByTagName( "artist" );
    for ( int i = 0; i < values.count(); i++ )
    {
        QDomNode item = values.item( i ).namedItem( "name" );
        QDomNode image = values.item( i ).namedItem( "image_small" );
        artists << item.toElement().text();
        images << image.toElement().text();
    }

    stackRemove( id );
    emit searchArtistResult( artist, image, streamable, artists, images );
}


void
WebserviceConnector::searchTagFinished( int id, bool error )
{
    QHttp *http = stackGet( id );
    if ( !http || error || http->bytesAvailable() <= 0 )
    {
        stackRemove( id );
        return;
    }

    QDomDocument document;
    document.setContent( http->readAll() );

    QStringList tags;
    QList<QStringList> topArtistList;
    if ( document.elementsByTagName( "tags" ).length() == 0 )
    {
        stackRemove( id );
        emit searchTagResult( tags, QList<QStringList>() );
        return;
    }

    QDomNodeList values = document.elementsByTagName( "tag" );
    for ( int i = 0; i < values.count(); i++ )
    {
        QDomNode item = values.item( i ).namedItem( "name" );
        tags << item.toElement().text();

        QStringList topArtists;
        QDomElement topartistsNode = values.item( i ).firstChildElement( "topartists" );
        if ( !topartistsNode.isNull() )
        {
            QDomNodeList artistsNode = topartistsNode.elementsByTagName( "artist" );
            for ( int x = 0; x < artistsNode.count(); x++ )
            {
                topArtists << artistsNode.item( x ).toElement().text();
            }
        }

        topArtistList.append( topArtists );
    }

    stackRemove( id );
    emit searchTagResult( tags, topArtistList );
}


void
WebserviceConnector::tagsForArtistFinished( int id, bool error )
{
    QHttp *http = stackGet( id );
    if ( !http || error || http->bytesAvailable() <= 0 )
    {
        stackRemove( id );
        return;
    }

    QDomDocument document;
    document.setContent( http->readAll() );

    QStringList tags;
    if ( document.elementsByTagName( "toptags" ).length() == 0 )
    {
        stackRemove( id );
        emit tagsForArtistResult( tags );
        return;
    }

    QDomNodeList values = document.elementsByTagName( "tag" );
    for ( int i = 0; i < values.count(); i++ )
    {
        QDomNode item = values.item( i ).namedItem( "name" );
        tags << item.toElement().text();
    }

    stackRemove( id );
    emit tagsForArtistResult( tags );
}


void
WebserviceConnector::tagsForUserFinished( int id, bool error )
{
    QHttp *http = stackGet( id );
    if ( !http || error || http->bytesAvailable() <= 0 )
    {
        stackRemove( id );
        return;
    }

    QDomDocument document;
    document.setContent( http->readAll() );

    QStringList tags;
    if ( document.elementsByTagName( "toptags" ).length() == 0 )
    {
        stackRemove( id );
        emit tagsForUserResult( tags );
        return;
    }

    QDomNodeList values = document.elementsByTagName( "tag" );
    for ( int i = 0; i < values.count(); i++ )
    {
        QDomNode item = values.item( i ).namedItem( "name" );
        tags << item.toElement().text();
    }

    stackRemove( id );
    emit tagsForUserResult( tags );
}


void
WebserviceConnector::tagsForUserArtistFinished( int id, bool error )
{
    QHttp *http = stackGet( id );
    if ( !http || error || http->bytesAvailable() <= 0 )
    {
        stackRemove( id );
        return;
    }

    QDomDocument document;
    document.setContent( http->readAll() );

    QStringList tags;
    if ( document.elementsByTagName( "artisttags" ).length() == 0 )
    {
        stackRemove( id );
        emit tagsForUserArtistResult( tags );
        return;
    }

    QDomNodeList values = document.elementsByTagName( "tag" );
    for ( int i = 0; i < values.count(); i++ )
    {
        QDomNode item = values.item( i ).namedItem( "name" );
        tags << item.toElement().text();
    }

    stackRemove( id );
    emit tagsForUserArtistResult( tags );
}


void
WebserviceConnector::tagsForUserTrackFinished( int id, bool error )
{
    QHttp *http = stackGet( id );
    if ( !http || error || http->bytesAvailable() <= 0 )
    {
        stackRemove( id );
        return;
    }

    QDomDocument document;
    document.setContent( http->readAll() );

    QStringList tags;
    if ( document.elementsByTagName( "tracktags" ).length() == 0 )
    {
        stackRemove( id );
        emit tagsForUserTrackResult( tags );
        return;
    }

    QDomNodeList values = document.elementsByTagName( "tag" );
    for ( int i = 0; i < values.count(); i++ )
    {
        QDomNode item = values.item( i ).namedItem( "name" );
        tags << item.toElement().text();
    }

    stackRemove( id );
    emit tagsForUserTrackResult( tags );
}


void
WebserviceConnector::tagsForUserAlbumFinished( int id, bool error )
{
    QHttp *http = stackGet( id );
    if ( !http || error || http->bytesAvailable() <= 0 )
    {
        stackRemove( id );
        return;
    }

    QDomDocument document;
    document.setContent( http->readAll() );

    QStringList tags;
    if ( document.elementsByTagName( "albumtags" ).length() == 0 )
    {
        stackRemove( id );
        emit tagsForUserAlbumResult( tags );
        return;
    }

    QDomNodeList values = document.elementsByTagName( "tag" );
    for ( int i = 0; i < values.count(); i++ )
    {
        QDomNode item = values.item( i ).namedItem( "name" );
        tags << item.toElement().text();
    }

    stackRemove( id );
    emit tagsForUserAlbumResult( tags );
}


void
WebserviceConnector::setTagFinished( int id, bool error )
{
    QHttp *http = stackGet( id );
    if ( !http || error || http->bytesAvailable() <= 0 )
    {
        stackRemove( id );
        return;
    }

    QString result( http->readAll() );
    qDebug() << "Tagging:" << result;

    stackRemove( id );
}


void
WebserviceConnector::metaData( bool force )
{
    if ( m_refreshTimer != 0 )
    {
        m_refreshTimer->stop();
        delete m_refreshTimer;
        m_refreshTimer = 0;
    }

    qDebug( "Retrieving MetaData!" );
    if ( force )
        m_forcedUpdate = true;

    QHttp *http = new QHttp( m_baseHost, 80, this );
    connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( metaDataFinished( int, bool ) ) );

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        http->setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );

    http->get( QString( m_basePath + "/np.php?session=%1&debug=%2" )
                  .arg( m_session )
                  .arg( Settings::instance()->debug() ? "1" : "0" ) );

    stackAppend( http );
}


void
WebserviceConnector::metaDataFinished( int id, bool error )
{
    QHttp *http = stackGet( id );
    if ( !http || error || http->bytesAvailable() <= 0 )
    {
        stackRemove( id );
        return;
    }

    QString result( http->readAll() );
    if ( Settings::instance()->debug() )
        qDebug() << "Metadata:" << result.left( 8000 );

    Song song;
    song.setProgress( 0 );

    song.setStation( parameter( "station", result ) );
    song.setArtist( parameter( "artist", result ) );
    song.setAlbum( parameter( "album", result ) );
    song.setTrack( parameter( "track", result ) );
    song.setCover( parameter( "albumcover_medium", result ) );
    song.setArtistUrl( parameter( "artist_url", result ) );
    song.setAlbumUrl( parameter( "album_url", result ) );
    song.setTrackUrl( parameter( "track_url", result ) );
    song.setDuration( parameter( "trackduration", result ).toInt() );
    bool discovery = parameter( "discovery", result ) != "-1";

    QStringList ids = parameterKeys( "playlist_track[", result );
    QStringList tracks = parameterArray( "playlist_track[", result );
    QStringList urls = parameterArray( "playlist_track_url[", result );

    Playlist playlist;
    for ( int i = 0; i < tracks.count(); i++ )
        playlist.appendTrack( tracks.at( i ), urls.at( i ), ids.at( i ) );
    emit playlistResult( playlist );

    int errCode = parameter( "error", result ).toInt();
    if ( errCode > 0 )
    {
        errorCode( errCode, parameter( "error_message", result ) );
        stackRemove( id );

        if ( error < 100 )
            return;
    }

    if ( m_refreshTimer != 0 )
    {
        m_refreshTimer->stop();
        delete m_refreshTimer;
        m_refreshTimer = 0;
    }
    if ( song.station().isEmpty() || parameter( "streaming", result ) == "false" || ( m_forcedUpdate && m_lastSong->sameAs( song ) ) )
    {
        qDebug( "Returned same or invalid metadata, will refetch!" );

        m_refreshTimer = new QTimer( this );
        connect( m_refreshTimer, SIGNAL( timeout() ), this, SLOT( metaData() ) );

        m_refreshTimer->setInterval( 2000 );
        m_refreshTimer->start();

        stackRemove( id, true );
        return;
    }

    if ( !m_lastSong->sameAs( song ) )
        emit metaDataResult( song, discovery );

    m_forcedUpdate = false;
    m_lastSong->fetch( song );
    stackRemove( id );
}


void
WebserviceConnector::skip()
{
    qDebug( "Sending SKIP!" );
    QHttp *http = new QHttp( m_baseHost, 80, this );
    connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( skipFinished( int, bool ) ) );

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        http->setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );

    http->get( QString( m_basePath + "/control.php?session=%1&command=skip&debug=%2" )
                  .arg( m_session )
                  .arg( Settings::instance()->debug() ? "1" : "0" ) );

    stackAppend( http );
    emit skipPrepared();
}


void
WebserviceConnector::love()
{
    qDebug( "Sending LOVE!" );
    QHttp *http = new QHttp( m_baseHost, 80, this );
    connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( loveFinished( int, bool ) ) );

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        http->setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );

    http->get( QString( m_basePath + "/control.php?session=%1&command=love&debug=%2" )
                  .arg( m_session )
                  .arg( Settings::instance()->debug() ? "1" : "0" ) );

    stackAppend( http );
    emit lovePrepared();
}


void
WebserviceConnector::ban()
{
    qDebug( "Sending BAN!" );
    QHttp *http = new QHttp( m_baseHost, 80, this );
    connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( banFinished( int, bool ) ) );

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        http->setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );

    http->get( QString( m_basePath + "/control.php?session=%1&command=ban&debug=%2" )
                  .arg( m_session )
                  .arg( Settings::instance()->debug() ? "1" : "0" ) );

    stackAppend( http );
    emit banPrepared();
}


void
WebserviceConnector::skipFinished( int id, bool error )
{
    QHttp *http = stackGet( id );
    if ( !http || error || http->bytesAvailable() <= 0 )
    {
        stackRemove( id );
        return;
    }

    QString result( http->readAll() );
    if ( Settings::instance()->debug() )
        qDebug() << "Skip:" << result;

    stackRemove( id, true );
    emit skipResult();
}


void
WebserviceConnector::loveFinished( int id, bool error )
{
    QHttp *http = stackGet( id );
    if ( !http || error || http->bytesAvailable() <= 0 )
    {
        stackRemove( id );
        return;
    }

    QString result( http->readAll() );
    if ( Settings::instance()->debug() )
        qDebug() << "Love:" << result;

    stackRemove( id );
    emit loveResult();
}


void
WebserviceConnector::banFinished( int id, bool error )
{
    QHttp *http = stackGet( id );
    if ( !http || error || http->bytesAvailable() <= 0 )
    {
        stackRemove( id );
        return;
    }

    QString result( http->readAll() );
    if ( Settings::instance()->debug() )
        qDebug() << "Ban:" << result;

    stackRemove( id, true );
    emit banResult();
}


void
WebserviceConnector::recordToProfile( bool enabled )
{
    if ( enabled )
        qDebug( "Enabling Record-To-Profile!" );
    else
        qDebug( "Disabling Record-To-Profile!" );

    QHttp *http = new QHttp( m_baseHost, 80, this );
    connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( defaultFinished( int, bool ) ) );

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        http->setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );

    http->get( QString( m_basePath + "/control.php?session=%1&command=%2&debug=%3" )
                  .arg( m_session )
                  .arg( enabled ? QString( "rtp" ) : QString( "nortp" ) )
                  .arg( Settings::instance()->debug() ? "1" : "0" ) );

    stackAppend( http );
}


void
WebserviceConnector::discoveryMode( bool enabled )
{
    if ( enabled )
        qDebug( "Enabling Discovery-Mode!" );
    else
        qDebug( "Disabling Discovery-Mode!" );

    QHttp *http = new QHttp( m_baseHost, 80, this );
    connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( defaultFinished( int, bool ) ) );

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        http->setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );

    http->get( QString( m_basePath + "/adjust.php?session=%1&url=lastfm://settings/discovery/%2&debug=%3" )
                  .arg( m_session )
                  .arg( enabled ? "on" : "off" )
                  .arg( Settings::instance()->debug() ? "1" : "0" ) );

    stackAppend( http );
}


void
WebserviceConnector::changeStation( QString url )
{
    qDebug( "Changing station!" );

    QHttp *http = new QHttp( m_baseHost, 80, this );
    connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( changeStationFinished( int, bool ) ) );

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        http->setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );

    http->get( QString( m_basePath + "/adjust.php?session=%1&url=lastfm://%2&debug=%3" )
                  .arg( m_session )
                  .arg( url.contains( "%" ) ? url : QString( QUrl( url ).toEncoded() ) )
                  .arg( Settings::instance()->debug() ? "1" : "0" ) );

    stackAppend( http );

    Playback::instance()->setDirectSkip();

    if ( !url.startsWith( "play" ) )
        emit changeStationPrepared();
}


void
WebserviceConnector::changeStationFinished( int id, bool error )
{
    QHttp *http = stackGet( id );
    if ( !http || error || http->bytesAvailable() <= 0 )
    {
        stackRemove( id );
        return;
    }

    QString result( http->readAll() );
    if ( Settings::instance()->debug() )
        qDebug() << "Station-change:" << result;

    int errCode = parameter( "error", result ).toInt();
    if ( errCode > 0 )
    {
        errorCode( errCode );
    }

    QString url = parameter( "url", result );
    if ( url.startsWith( "lastfm://" ) )
    {
        url.remove( 0, 9 );
        Settings::instance()->setResumeStation( url );

        QString stationName = parameter( "stationname", result );
        if ( !url.startsWith( "play" ) )
        {
            Settings::instance()->incrementStationCounter( url, stationName );
            emit changeStationPrepared();
        }
        else
            // retrieve new playlist data
            metaData( false );
    }

    stackRemove( id, errCode == 0 );
    emit changeStationResult( errCode != 0 );
}


void
WebserviceConnector::playlistRemove( QString id )
{
    qDebug( QString( "Removing track from playlist: " + id ).toLocal8Bit() );

    QHttp *http = new QHttp( m_baseHost, 80, this );
    connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( defaultFinished( int, bool ) ) );

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        http->setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );

    http->get( QString( m_basePath + "/adjust.php?session=%1&url=lastfm://play/removetrack/%2&debug=%3" )
                  .arg( m_session )
                  .arg( id )
                  .arg( Settings::instance()->debug() ? "1" : "0" ) );

    stackAppend( http );
}


void
WebserviceConnector::playlistClear()
{
    qDebug( "Clearing playlist!" );

    QHttp *http = new QHttp( m_baseHost, 80, this );
    connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( defaultFinished( int, bool ) ) );

    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        http->setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );

    http->get( QString( m_basePath + "/adjust.php?session=%1&url=lastfm://play/clear&debug=%2" )
                  .arg( m_session )
                  .arg( Settings::instance()->debug() ? "1" : "0" ) );

    stackAppend( http );
}


void
WebserviceConnector::defaultFinished( int id, bool error )
{
    QHttp *http = stackGet( id );
    if ( !http || error || http->bytesAvailable() <= 0 )
    {
        stackRemove( id );
        return;
    }

    QString result( http->readAll() );
    if ( Settings::instance()->debug() )
        qDebug() << result;

    stackRemove( id );
}


Generated by  Doxygen 1.6.0   Back to index