lastfm.cpp

来自「Amarok是一款在LINUX或其他类UNIX操作系统中运行的音频播放器软件。 」· C++ 代码 · 共 1,099 行 · 第 1/3 页

CPP
1,099
字号
/*************************************************************************** * 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.                                   * *                                                                         * ***************************************************************************/#define DEBUG_PREFIX "LastFm"#include "amarok.h"         //APP_VERSION, actioncollection#include "amarokconfig.h"   //last.fm username and passwd#include "collectiondb.h"#include "debug.h"#include "enginecontroller.h"#include "lastfm.h"#include "statusbar.h"      //showError()#include <qdeepcopy.h>#include <qdom.h>#include <qhttp.h>#include <qlabel.h>#include <qregexp.h>#include <kaction.h>#include <klineedit.h>#include <kmdcodec.h>       //md5sum#include <kmessagebox.h>#include <kio/job.h>#include <kio/jobclasses.h>#include <kprotocolmanager.h>#include <kshortcut.h>#include <kurl.h>#include <time.h>#include <unistd.h>using namespace LastFm;///////////////////////////////////////////////////////////////////////////////// CLASS AmarokHttp// 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.////////////////////////////////////////////////////////////////////////////////AmarokHttp::AmarokHttp ( const QString& hostname, Q_UINT16 port,                         QObject* parent )    : QObject( parent ),      m_hostname( hostname ),      m_port( port ){}intAmarokHttp::get ( const QString & path ){    QString uri = QString( "http://%1:%2/%3" )                  .arg( m_hostname )                  .arg( m_port )                  .arg( path );    m_done = false;    m_error = QHttp::NoError;    m_state = QHttp::Connecting;    KIO::TransferJob *job = KIO::get(uri, true, false);    connect(job,  SIGNAL(data(KIO::Job*, const QByteArray&)),            this, SLOT(slotData(KIO::Job*, const QByteArray&)));    connect(job,  SIGNAL(result(KIO::Job*)),            this, SLOT(slotResult(KIO::Job*)));    return 0;}QHttp::StateAmarokHttp::state() const{    return m_state;}QByteArrayAmarokHttp::readAll (){    return m_result;}QHttp::ErrorAmarokHttp::error(){    return m_error;}voidAmarokHttp::slotData(KIO::Job*, const QByteArray& data){    if( data.size() == 0 ) {        return;    }    else if ( m_result.size() == 0 ) {        m_result = data;    }    else if ( m_result.resize( m_result.size() + data.size() ) ) {        memcpy( m_result.end(), data.data(),  data.size() );    }}voidAmarokHttp::slotResult(KIO::Job* job){    bool err = job->error();    if( err || m_error != QHttp::NoError ) {        m_error = QHttp::UnknownError;    }    else {        m_error = QHttp::NoError;    }    m_done = true;    m_state = QHttp::Unconnected;    emit( requestFinished( 0, err ) );}///////////////////////////////////////////////////////////////////////////////// CLASS Controller////////////////////////////////////////////////////////////////////////////////Controller *Controller::s_instance = 0;Controller::Controller()    : QObject( EngineController::instance(), "lastfmController" )    , m_service( 0 ){    KActionCollection* ac = Amarok::actionCollection();    m_actionList.append( new KAction( i18n( "Ban" ), Amarok::icon( "remove" ),                         KKey( Qt::CTRL | Qt::Key_B ), this, SLOT( ban() ), ac, "ban" ) );    m_actionList.append( new KAction( i18n( "Love" ), Amarok::icon( "love" ),                         KKey( Qt::CTRL | Qt::Key_L ), this, SLOT( love() ), ac, "love" ) );    m_actionList.append( new KAction( i18n( "Skip" ), Amarok::icon( "next" ),                         KKey( Qt::CTRL | Qt::Key_K ), this, SLOT( skip() ), ac, "skip" ) );    setActionsEnabled( false );}Controller*Controller::instance(){    if( !s_instance ) s_instance = new Controller();    return s_instance;}KURLController::getNewProxy( QString genreUrl, bool useProxy ){    DEBUG_BLOCK    m_genreUrl = genreUrl;    if ( m_service ) playbackStopped();    m_service = new WebService( this, useProxy );    if( checkCredentials() )    {        QString user = AmarokConfig::scrobblerUsername();        QString pass = AmarokConfig::scrobblerPassword();        if( !user.isEmpty() && !pass.isEmpty() &&            m_service->handshake( user, pass ) )        {            bool ok = m_service->changeStation( m_genreUrl );            if( ok ) // else playbackStopped()            {                if( !AmarokConfig::submitPlayedSongs() )                    m_service->enableScrobbling( false );                setActionsEnabled( true );                return KURL( m_service->proxyUrl() );            }        }    }    // Some kind of failure happened, so crap out    playbackStopped();    return KURL();}voidController::playbackStopped() //SLOT{    setActionsEnabled( false );    delete m_service;    m_service = 0;}boolController::checkCredentials() //static{    if( AmarokConfig::scrobblerUsername().isEmpty() || AmarokConfig::scrobblerPassword().isEmpty() )    {        LoginDialog dialog( 0 );        dialog.setCaption( "last.fm" );        return dialog.exec() == QDialog::Accepted;    }    return true;}QStringController::createCustomStation() //static{    QString token;    CustomStationDialog dialog( 0 );    if( dialog.exec() == QDialog::Accepted )    {        token =  dialog.text();    }    return token;}voidController::ban(){    if( m_service )        m_service->ban();}voidController::love(){    if( m_service )        m_service->love();}voidController::skip(){    if( m_service )        m_service->skip();}voidController::setActionsEnabled( bool enable ){   //pausing last.fm streams doesn't do anything good    Amarok::actionCollection()->action( "play_pause" )->setEnabled( !enable );    Amarok::actionCollection()->action( "pause" )->setEnabled( !enable );    KAction* action;    for( action = m_actionList.first(); action; action = m_actionList.next() )        action->setEnabled( enable );}/// return a translatable description of the station we are connected toQStringController::stationDescription( QString url ){    if( url.isEmpty() && instance() && instance()->isPlaying() )        url = instance()->getService()->currentStation();    if( url.isEmpty() ) return QString();    QStringList elements = QStringList::split( "/", url );    /// TAG RADIOS    // eg: lastfm://globaltag/rock    if ( elements[1] == "globaltags" )        return i18n( "Global Tag Radio: %1" ).arg( elements[2] );    /// ARTIST RADIOS    if ( elements[1] == "artist" )    {        // eg: lastfm://artist/Queen/similarartists        if ( elements[3] == "similarartists" )            return i18n( "Similar Artists to %1" ).arg( elements[2] );        if ( elements[3] == "fans" )            return i18n( "Artist Fan Radio: %1" ).arg( elements[2] );    }    /// CUSTOM STATION    if ( elements[1] == "artistnames" )    {        // eg: lastfm://artistnames/genesis,pink floyd,queen        // turn "genesis,pink floyd,queen" into "Genesis, Pink Floyd, Queen"        QString artists = elements[2];        artists.replace( ",", ", " );        const QStringList words = QStringList::split( " ", QString( artists ).remove( "," ) );        foreach( words ) {            QString capitalized = *it;            capitalized.replace( 0, 1, (*it)[0].upper() );            artists.replace( *it, capitalized );        }        return i18n( "Custom Station: %1" ).arg( artists );    }    /// USER RADIOS    else if ( elements[1] == "user" )    {        // eg: lastfm://user/sebr/neighbours        if ( elements[3] == "neighbours" )            return i18n( "%1's Neighbor Radio" ).arg( elements[2] );        // eg: lastfm://user/sebr/personal        if ( elements[3] == "personal" )            return i18n( "%1's Personal Radio" ).arg( elements[2] );        // eg: lastfm://user/sebr/loved        if ( elements[3] == "loved" )            return i18n( "%1's Loved Radio" ).arg( elements[2] );        // eg: lastfm://user/sebr/recommended/100 : 100 is number for how obscure the music should be        if ( elements[3] == "recommended" )            return i18n( "%1's Recommended Radio" ).arg( elements[2] );    }    /// GROUP RADIOS    //eg: lastfm://group/Amarok%20users    else if ( elements[1] == "group" )        return i18n( "Group Radio: %1" ).arg( elements[2] );    /// TRACK RADIOS    else if ( elements[1] == "play" )    {        if ( elements[2] == "tracks" )            return i18n( "Track Radio" );        else if ( elements[2] == "artists" )            return i18n( "Artist Radio" );    }    //kaput!    return url;}////////////////////////////////////////////////////////////////////////////////// CLASS WebService////////////////////////////////////////////////////////////////////////////////WebService::WebService( QObject* parent, bool useProxy )    : QObject( parent, "lastfmParent" )    , m_useProxy( useProxy ){    debug() << "Initialising Web Service" << endl;}WebService::~WebService(){    DEBUG_BLOCK

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?