coverfetcher.cpp

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

CPP
679
字号
// (C) 2004 Mark Kretschmann <markey@web.de>// (C) 2004 Stefan Bogner <bochi@online.ms>// (C) 2004 Max Howell// See COPYING file for licensing information.#include "amarok.h"#include "amarokconfig.h"#include "collectiondb.h"#include "config.h"        //for AMAZON_SUPPORT#include "covermanager.h"#include "coverfetcher.h"#include "debug.h"#include "statusbar.h"#include <qdom.h>#include <qhbox.h>#include <qlabel.h>#include <qlayout.h>#include <qregexp.h>#include <kapplication.h>#include <kcombobox.h>#include <kcursor.h> //waiting cursor#include <kdialog.h>#include <kiconloader.h>#include <kfiledialog.h>#include <kio/job.h>#include <kio/jobclasses.h>#include <klineedit.h>#include <klocale.h>#include <kmessagebox.h>#include <kpopupmenu.h>#include <kpushbutton.h>#include <kwin.h>voidAmarok::coverContextMenu( QWidget *parent, QPoint point, const QString &artist, const QString &album, bool showCoverManager ){        KPopupMenu menu;        enum { SHOW, FETCH, CUSTOM, DELETE, MANAGER };        menu.insertTitle( i18n( "Cover Image" ) );        menu.insertItem( SmallIconSet( Amarok::icon( "zoom" ) ), i18n( "&Show Fullsize" ), SHOW );        menu.insertItem( SmallIconSet( Amarok::icon( "download" ) ), i18n( "&Fetch From amazon.%1" ).arg( CoverManager::amazonTld() ), FETCH );        menu.insertItem( SmallIconSet( Amarok::icon( "files" ) ), i18n( "Set &Custom Cover" ), CUSTOM );        bool disable = !album.isEmpty(); // disable setting covers for unknown albums        menu.setItemEnabled( FETCH, disable );        menu.setItemEnabled( CUSTOM, disable );        menu.insertSeparator();        menu.insertItem( SmallIconSet( Amarok::icon( "remove" ) ), i18n( "&Unset Cover" ), DELETE );        if ( showCoverManager ) {            menu.insertSeparator();            menu.insertItem( SmallIconSet( Amarok::icon( "covermanager" ) ), i18n( "Cover &Manager" ), MANAGER );        }        #ifndef AMAZON_SUPPORT        menu.setItemEnabled( FETCH, false );        #endif        disable = !CollectionDB::instance()->albumImage( artist, album, 0 ).contains( "nocover" );        menu.setItemEnabled( SHOW, disable );        menu.setItemEnabled( DELETE, disable );        switch( menu.exec( point ) )        {        case SHOW:            CoverManager::viewCover( artist, album, parent );            break;        case DELETE:        {            const int button = KMessageBox::warningContinueCancel( parent,                i18n( "Are you sure you want to remove this cover from the Collection?" ),                QString::null,                KStdGuiItem::del() );            if ( button == KMessageBox::Continue )                CollectionDB::instance()->removeAlbumImage( artist, album );            break;        }        case FETCH:        #ifdef AMAZON_SUPPORT            CollectionDB::instance()->fetchCover( parent, artist, album, false );            break;        #endif        case CUSTOM:        {            QString artist_id; artist_id.setNum( CollectionDB::instance()->artistID( artist ) );            QString album_id; album_id.setNum( CollectionDB::instance()->albumID( album ) );            QStringList values = CollectionDB::instance()->albumTracks( artist_id, album_id );            QString startPath = ":homedir";            if ( !values.isEmpty() ) {                KURL url;                url.setPath( values.first() );                startPath = url.directory();            }            KURL file = KFileDialog::getImageOpenURL( startPath, parent, i18n("Select Cover Image File") );            if ( !file.isEmpty() )                CollectionDB::instance()->setAlbumImage( artist, album, file );            break;        }        case MANAGER:            CoverManager::showOnce( album );            break;        }}CoverLabel::CoverLabel ( QWidget * parent, const char * name, WFlags f )        : QLabel( parent, name, f){}void CoverLabel::mouseReleaseEvent(QMouseEvent *pEvent) {    if (pEvent->button() == LeftButton || pEvent->button() == RightButton)    {        Amarok::coverContextMenu( this, pEvent->globalPos(), m_artist, m_album, false );    }}CoverFetcher::CoverFetcher( QWidget *parent, const QString &artist, QString album )        : QObject( parent, "CoverFetcher" )        , m_artist( artist )        , m_album( album )        , m_size( 2 )        , m_success( true ){    DEBUG_FUNC_INFO    QStringList extensions;    extensions << i18n("disc") << i18n("disk") << i18n("remaster") << i18n("cd") << i18n("single") << i18n("soundtrack") << i18n("part")               << "disc" << "disk" << "remaster" << "cd" << "single" << "soundtrack" << "part" << "cds" /*cd single*/;    //we do several queries, one raw ie, without the following modifications    //the others have the above strings removed with the following regex, as this can increase hit-rate    const QString template1 = " ?-? ?[(^{]* ?%1 ?\\d*[)^}\\]]* *$"; //eg album - [disk 1] -> album    foreach( extensions ) {        QRegExp regexp( template1.arg( *it ) );        regexp.setCaseSensitive( false );        album.remove( regexp );    }    //TODO try queries that remove anything in album after a " - " eg Les Mis. - Excerpts    /**     * We search for artist - album, and just album, using the exact album text and the     * manipulated album text.     */    //search on our modified term, then the original    if ( !m_artist.isEmpty() )        m_userQuery = m_artist + " - ";    m_userQuery += m_album;    m_queries += m_artist + " - " + album;    m_queries += m_userQuery;    m_queries += album;    m_queries += m_album;    //don't do the same searches twice in a row    if( m_album == album )  {        m_queries.pop_front();        m_queries.pop_back();    }    /**     * Finally we do a search for just the artist, just in case as this often     * turns up a cover, and it might just be the right one! Also it would be     * the only valid search if m_album.isEmpty()     */    m_queries += m_artist;    QApplication::setOverrideCursor( KCursor::workingCursor() );}CoverFetcher::~CoverFetcher(){    DEBUG_FUNC_INFO    QApplication::restoreOverrideCursor();}voidCoverFetcher::startFetch(){    DEBUG_FUNC_INFO    // Static license Key. Thanks hydrogen ;-)    const QString LICENSE( "11ZKJS8X1ETSTJ6MT802" );    // reset all values    m_coverAmazonUrls.clear();    m_coverAsins.clear();    m_coverUrls.clear();    m_coverNames.clear();    m_xml = QString::null;    m_size = 2;    if ( m_queries.isEmpty() ) {        debug() << "m_queries is empty" << endl;        finishWithError( i18n("No cover found") );        return;    }    QString query = m_queries.front();    m_queries.pop_front();    // '&' breaks searching    query.remove('&');        QString locale = AmarokConfig::amazonLocale();    QString tld;    if( locale == "us" )        tld = "com";    else if( locale =="uk" )        tld = "co.uk";    else        tld = locale;    int mibenum = 106; // utf-8    QString url;    url = "http://ecs.amazonaws." + tld        + "/onca/xml?Service=AWSECommerceService&Version=2007-10-29&Operation=ItemSearch&AssociateTag=webservices-20&AWSAccessKeyId=" + LICENSE        + "&Keywords=" + KURL::encode_string_no_slash( query, mibenum )        + "&SearchIndex=Music&ResponseGroup=Small,Images";    debug() << url << endl;    KIO::TransferJob* job = KIO::storedGet( url, false, false );    connect( job, SIGNAL(result( KIO::Job* )), SLOT(finishedXmlFetch( KIO::Job* )) );    Amarok::StatusBar::instance()->newProgressOperation( job );}//////////////////////////////////////////////////////////////////////////////////////////// PRIVATE SLOTS//////////////////////////////////////////////////////////////////////////////////////////voidCoverFetcher::finishedXmlFetch( KIO::Job *job ) //SLOT{    DEBUG_BLOCK    // NOTE: job can become 0 when this method is called from attemptAnotherFetch()    if( job && job->error() ) {        finishWithError( i18n("There was an error communicating with Amazon."), job );        return;    }    if ( job ) {        KIO::StoredTransferJob* const storedJob = static_cast<KIO::StoredTransferJob*>( job );        m_xml = QString::fromUtf8( storedJob->data().data(), storedJob->data().size() );    }    QDomDocument doc;    if( !doc.setContent( m_xml ) ) {        m_errors += i18n("The XML obtained from Amazon is invalid.");        startFetch();        return;    }    m_coverAsins.clear();    m_coverAmazonUrls.clear();    m_coverUrls.clear();    m_coverNames.clear();    // the url for the Amazon product info page    const QDomNodeList list = doc.documentElement().namedItem( "Items" ).childNodes();    for(int i = 0; i < list.count(); i++ )    {        QDomNode n = list.item( i );        if( n.isElement() && n.nodeName() == "IsValid" )        {            if( n.toElement().text() == "False" )            {                warning() << "The XML Is Invalid!";                return;            }        }        else if( list.item( i ).nodeName() == "Item" )        {            const QDomNode node = list.item( i );            parseItemNode( node );        }    }    attemptAnotherFetch();}void CoverFetcher::parseItemNode( const QDomNode &node ){    QDomNode it = node.firstChild();    QString size;    switch( m_size )    {        case 0:  size = "Small";  break;        case 1:  size = "Medium"; break;        default: size = "Large";  break;    }    size += "Image";    while ( !it.isNull() ) {        if ( it.isElement() ) {            QDomElement e = it.toElement();            if(e.tagName()=="ASIN")            {                m_asin = e.text();                m_coverAsins += m_asin;            }            else if(e.tagName() == "DetailPageURL" )            {                m_amazonURL = e.text();                m_coverAmazonUrls += m_amazonURL;            }            else if( e.tagName() == size )            {                QDomNode subIt = e.firstChild();                while( !subIt.isNull() )                {                    if( subIt.isElement() )                    {                        QDomElement subE = subIt.toElement();                        if( subE.tagName() == "URL" )                        {                            const QString coverUrl = subE.text();                            m_coverUrls += coverUrl;                            break;                        }                    }                    subIt = subIt.nextSibling();

⌨️ 快捷键说明

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