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 + -
显示快捷键?