bool Dynamic::LastFmBias::trackMatches( int position, const Meta::TrackList& playlist, int contextCount ) const { Q_UNUSED( contextCount ); if( position <= 0 || position >= playlist.count()) return false; // determine the last track and artist Meta::TrackPtr lastTrack = playlist[position-1]; Meta::ArtistPtr lastArtist = lastTrack->artist(); QString lastTrackName = lastTrack->name(); QString lastArtistName = lastArtist ? lastArtist->name() : QString(); Meta::TrackPtr currentTrack = playlist[position]; Meta::ArtistPtr currentArtist = currentTrack->artist(); QString currentTrackName = currentTrack->name(); QString currentArtistName = currentArtist ? currentArtist->name() : QString(); { QMutexLocker locker( &m_mutex ); if( m_match == SimilarArtist ) { if( lastArtistName.isEmpty() ) return true; if( currentArtistName.isEmpty() ) return false; if( lastArtistName == currentArtistName ) return true; if( m_similarArtistMap.contains( lastArtistName ) ) return m_similarArtistMap.value( lastArtistName ).contains( currentArtistName ); } else if( m_match == SimilarTrack ) { if( lastTrackName.isEmpty() ) return true; if( currentTrackName.isEmpty() ) return false; if( lastTrackName == currentTrackName ) return true; TitleArtistPair lastKey( lastTrackName, lastArtistName ); TitleArtistPair currentKey( currentTrackName, currentArtistName ); if( m_similarTrackMap.contains( lastKey ) ) return m_similarTrackMap.value( lastKey ).contains( currentKey ); } } debug() << "didn't have a cached suggestions for track:" << lastTrackName; return false; }
void IpodCopyTracksJob::slotStartDuplicateTrackSearch( const Meta::TrackPtr &track ) { Collections::QueryMaker *qm = m_coll.data()->queryMaker(); qm->setQueryType( Collections::QueryMaker::Track ); // we cannot qm->addMatch( track ) - it matches by uidUrl() qm->addFilter( Meta::valTitle, track->name(), true, true ); qm->addMatch( track->album() ); qm->setArtistQueryMode( Collections::QueryMaker::TrackArtists ); qm->addMatch( track->artist() ); qm->addMatch( track->composer() ); qm->addMatch( track->genre() ); qm->addMatch( track->year() ); qm->addNumberFilter( Meta::valTrackNr, track->trackNumber(), Collections::QueryMaker::Equals ); qm->addNumberFilter( Meta::valDiscNr, track->discNumber(), Collections::QueryMaker::Equals ); // we don't want to match by filesize, track length, filetype etc - these change during // transcoding. We don't match album artist because handling of it is inconsistent connect( qm, SIGNAL(newResultReady(Meta::TrackList)), SLOT(slotDuplicateTrackSearchNewResult(Meta::TrackList)) ); connect( qm, SIGNAL(queryDone()), SLOT(slotDuplicateTrackSearchQueryDone()) ); qm->setAutoDelete( true ); m_duplicateTrack = Meta::TrackPtr(); // reset duplicate track from previous query qm->run(); }
void LyricsEngine::onTrackMetadataChanged( Meta::TrackPtr track ) { DEBUG_BLOCK // Only update if the lyrics have changed. QString artist = track->artist() ? track->artist()->name() : QString(); if( m_prevLyrics.artist != artist || m_prevLyrics.title != track->name() || m_prevLyrics.text != track->cachedLyrics() ) update(); }
void LastfmInfoParser::getInfo(Meta::TrackPtr track) { DEBUG_BLOCK QMap<QString, QString> query; query[ "method" ] = "track.getInfo"; query[ "track" ] = track->name(); query[ "album" ] = track->album() ? track->album()->name() : QString(); query[ "artist" ] = track->artist() ? track->artist()->name() : QString(); query[ "apikey" ] = Amarok::lastfmApiKey(); m_jobs[ "getTrackInfo" ] = lastfm::ws::post( query ); connect( m_jobs[ "getTrackInfo" ], SIGNAL( finished() ), SLOT( onGetTrackInfo() ) ); }
/** * called whenever metadata of the current track has changed */ void TabsEngine::update() { DEBUG_BLOCK // get the current track Meta::TrackPtr track = The::engineController()->currentTrack(); if( !track ) { debug() << "no track"; m_titleName.clear(); m_artistName.clear(); removeAllData( "tabs" ); setData( "tabs", "state", "Stopped" ); return; } m_currentTrack = track; Meta::ArtistPtr artistPtr = track->artist(); QString newArtist; if( artistPtr ) { if( ( track->playableUrl().protocol() == "lastfm" ) || ( track->playableUrl().protocol() == "daap" ) || !The::engineController()->isStream() ) newArtist = artistPtr->name(); else newArtist = artistPtr->prettyName(); } QString newTitle = track->name(); if( newTitle.isEmpty() ) newTitle = track->prettyName(); // check if something changed if( newTitle == m_titleName && newArtist == m_artistName ) { debug() << "nothing changed"; return; } // stop fetching for unknown artists or titles if( newTitle.isEmpty() || newArtist.isEmpty() ) { setData("tabs", "state", "noTabs" ); return; } requestTab( newArtist, newTitle ); }
Dynamic::TrackSet Dynamic::LastFmBias::matchingTracks( const Meta::TrackList& playlist, int contextCount, int finalCount, Dynamic::TrackCollectionPtr universe ) const { Q_UNUSED( contextCount ); Q_UNUSED( finalCount ); if( playlist.isEmpty() ) return Dynamic::TrackSet( universe, true ); // determine the last track and artist Meta::TrackPtr lastTrack = playlist.last(); Meta::ArtistPtr lastArtist = lastTrack->artist(); m_currentTrack = lastTrack->name(); m_currentArtist = lastArtist ? lastArtist->name() : QString(); { QMutexLocker locker( &m_mutex ); if( m_match == SimilarArtist ) { if( m_currentArtist.isEmpty() ) return Dynamic::TrackSet( universe, true ); if( m_tracksMap.contains( m_currentArtist ) ) return m_tracksMap.value( m_currentArtist ); } else if( m_match == SimilarTrack ) { if( m_currentTrack.isEmpty() ) return Dynamic::TrackSet( universe, true ); QString key = m_currentTrack + '|' + m_currentArtist; if( m_tracksMap.contains( key ) ) return m_tracksMap.value( key ); } } m_tracks = Dynamic::TrackSet( universe, false ); QTimer::singleShot(0, const_cast<LastFmBias*>(this), SLOT(newQuery())); // create the new query from my parent thread return Dynamic::TrackSet(); }
void CurrentEngine::update( Meta::TrackPtr track ) { if( !m_requested.value( QLatin1String("current") ) || track == m_currentTrack ) return; DEBUG_BLOCK m_currentTrack = track; removeAllData( QLatin1String("current") ); if( !track ) return; Plasma::DataEngine::Data data; QVariantMap trackInfo = Meta::Field::mapFromTrack( track ); data["current"] = trackInfo; Meta::AlbumPtr album = track->album(); data["albumart"] = QVariant( album ? The::coverCache()->getCover( album, m_coverWidth) : QPixmap() ); Capabilities::SourceInfoCapability *sic = track->create<Capabilities::SourceInfoCapability>(); if( sic ) { //is the source defined const QString source = sic->sourceName(); debug() <<" We have source " <<source; if( !source.isEmpty() ) data["source_emblem"] = sic->scalableEmblem(); delete sic; } else data["source_emblem"] = QVariant( QPixmap() ); debug() << "updating track" << track->name(); setData( "current", data ); }
void ScrobblerAdapter::copyTrackMetadata( lastfm::MutableTrack &to, const Meta::TrackPtr &track ) { to.setTitle( track->name() ); QString artistOrComposer; Meta::ComposerPtr composer = track->composer(); if( m_config->scrobbleComposer() && composer ) artistOrComposer = composer->name(); Meta::ArtistPtr artist = track->artist(); if( artistOrComposer.isEmpty() && artist ) artistOrComposer = artist->name(); to.setArtist( artistOrComposer ); Meta::AlbumPtr album = track->album(); Meta::ArtistPtr albumArtist; if( album ) { to.setAlbum( album->name() ); albumArtist = album->hasAlbumArtist() ? album->albumArtist() : Meta::ArtistPtr(); } if( albumArtist ) to.setAlbumArtist( albumArtist->name() ); to.setDuration( track->length() / 1000 ); if( track->trackNumber() >= 0 ) to.setTrackNumber( track->trackNumber() ); lastfm::Track::Source source = lastfm::Track::Player; if( track->type() == "stream/lastfm" ) source = lastfm::Track::LastFmRadio; else if( track->type().startsWith( "stream" ) ) source = lastfm::Track::NonPersonalisedBroadcast; else if( track->collection() && track->collection()->collectionId() != "localCollection" ) source = lastfm::Track::MediaDevice; to.setSource( source ); }
QString TrackOrganizer::buildDestination(const QString& format, const Meta::TrackPtr& track) const { // get hold of the shared pointers Meta::AlbumPtr album = track->album(); Meta::ArtistPtr artist = track->artist(); Meta::ComposerPtr composer = track->composer(); Meta::ArtistPtr albumArtist = album ? album->albumArtist() : Meta::ArtistPtr(); Meta::GenrePtr genre = track->genre(); Meta::YearPtr year = track->year(); bool isCompilation = album && album->isCompilation(); QMap<QString, QString> args; QString strArtist = artist ? artist->name() : QString(); QString strAlbumArtist = isCompilation ? i18n( "Various Artists" ) : ( albumArtist ? albumArtist->name() : strArtist ); args["theartist"] = strArtist; args["thealbumartist"] = strAlbumArtist; if( m_postfixThe ) { Amarok::manipulateThe( strArtist, true ); Amarok::manipulateThe( strAlbumArtist, true ); } if ( track->trackNumber() ) { QString trackNum = QString("%1").arg( track->trackNumber(), 2, 10, QChar('0') ); args["track"] = trackNum; } args["title"] = track->name(); args["artist"] = strArtist; args["composer"] = composer ? composer->name() : QString(); // if year == 0 then we don't want include it QString strYear = year ? year->name() : QString(); args["year"] = strYear.localeAwareCompare( "0" ) == 0 ? QString() : strYear; args["album"] = track->album() ? track->album()->name() : QString(); args["albumartist"] = strAlbumArtist; args["comment"] = track->comment(); args["genre"] = genre ? genre->name() : QString(); if( m_targetFileExtension.isEmpty() ) args["filetype"] = track->type(); else args["filetype"] = m_targetFileExtension; QString strFolder = QFileInfo( track->playableUrl().toLocalFile() ).path(); strFolder = strFolder.mid( commonPrefixLength( m_folderPrefix, strFolder ) ); args["folder"] = strFolder; args["initial"] = strAlbumArtist.mid( 0, 1 ).toUpper(); //artists starting with The are already handled above if( track->discNumber() ) args["discnumber"] = QString::number( track->discNumber() ); args["collectionroot"] = m_folderPrefix; // some additional properties not supported by organize dialog. args["rating"] = track->statistics()->rating(); args["filesize"] = track->filesize(); args["length"] = track->length() / 1000; // Fill up default empty values for StringX formater // TODO make this values changeable by user args["default_album"] = i18n( "Unknown album" ); args["default_albumartist"] = i18n( "Unknown artist" ); args["default_artist"] = args["albumartist"]; args["default_thealbumartist"] = args["albumartist"]; args["default_theartist"] = args["albumartist"]; args["default_comment"] = i18n( "No comments" ); args["default_composer"] = i18n( "Unknown composer" ); args["default_discnumber"] = i18n( "Unknown disc number" ); args["default_genre"] = i18n( "Unknown genre" ); args["default_title"] = i18n( "Unknown title" ); args["default_year"] = i18n( "Unknown year" ); foreach( const QString &key, args.keys() ) if( key != "collectionroot" && key != "folder" ) args[key] = args[key].replace( '/', '-' ); Amarok::QStringx formatx( format ); QString result = formatx.namedOptArgs( args ); return cleanPath( result ); }
void LyricsEngine::update() { if( m_isUpdateInProgress ) return; m_isUpdateInProgress = true; // -- get current title and artist Meta::TrackPtr currentTrack = The::engineController()->currentTrack(); if( !currentTrack ) { debug() << "no current track"; m_prevLyrics.clear(); removeAllData( "lyrics" ); setData( "lyrics", "stopped", "stopped" ); m_isUpdateInProgress = false; return; } QString title = currentTrack->name(); QString artist = currentTrack->artist() ? currentTrack->artist()->name() : QString(); // -- clean up title const QString magnatunePreviewString = QLatin1String( "PREVIEW: buy it at www.magnatune.com" ); if( title.contains(magnatunePreviewString, Qt::CaseSensitive) ) title = title.remove( " (" + magnatunePreviewString + ")" ); if( artist.contains(magnatunePreviewString, Qt::CaseSensitive) ) artist = artist.remove( " (" + magnatunePreviewString + ")" ); if( title.isEmpty() && currentTrack ) { /* If title is empty, try to use pretty title. The fact that it often (but not always) has "artist name" together, can be bad, but at least the user will hopefully get nice suggestions. */ QString prettyTitle = currentTrack->prettyName(); int h = prettyTitle.indexOf( QLatin1Char('-') ); if ( h != -1 ) { title = prettyTitle.mid( h + 1 ).trimmed(); if( title.contains(magnatunePreviewString, Qt::CaseSensitive) ) title = title.remove( " (" + magnatunePreviewString + ")" ); if( artist.isEmpty() ) { artist = prettyTitle.mid( 0, h ).trimmed(); if( artist.contains(magnatunePreviewString, Qt::CaseSensitive) ) artist = artist.remove( " (" + magnatunePreviewString + ")" ); } } } LyricsData lyrics = { currentTrack->cachedLyrics(), title, artist, KUrl() }; // Check if the title, the artist and the lyrics are still the same. if( !lyrics.text.isEmpty() && (lyrics.text == m_prevLyrics.text) ) { debug() << "nothing changed:" << lyrics.title; newLyrics( lyrics ); m_isUpdateInProgress = false; return; } // don't rely on caching for streams const bool cached = !LyricsManager::self()->isEmpty( lyrics.text ) && !The::engineController()->isStream(); if( cached ) { newLyrics( lyrics ); } else { // no lyrics, and no lyrics script! if( !ScriptManager::instance()->lyricsScriptRunning() ) { debug() << "no lyrics script running"; removeAllData( "lyrics" ); setData( "lyrics", "noscriptrunning", "noscriptrunning" ); disconnect( ScriptManager::instance(), SIGNAL(lyricsScriptStarted()), this, 0 ); connect( ScriptManager::instance(), SIGNAL(lyricsScriptStarted()), SLOT(update()) ); m_isUpdateInProgress = false; return; } // fetch by lyrics script removeAllData( "lyrics" ); setData( "lyrics", "fetching", "fetching" ); ScriptManager::instance()->notifyFetchLyrics( lyrics.artist, lyrics.title ); } m_isUpdateInProgress = false; }
QVariant Meta::valueForField( qint64 field, Meta::TrackPtr track ) { if( !track ) return QVariant(); switch( field ) { case 0: { // that is the simple search for MetaQueryWidget QSet<QString> allInfos; allInfos += track->playableUrl().path() += track->name() += track->comment(); if( track->artist() ) allInfos += track->artist()->name(); if( track->album() ) allInfos += track->album()->name(); if( track->genre() ) allInfos += track->genre()->name(); return QVariant( allInfos.toList() ); } case Meta::valUrl: return track->playableUrl().path(); case Meta::valTitle: return track->name(); case Meta::valArtist: return track->artist() ? QVariant(track->artist()->name()) : QVariant(); case Meta::valAlbum: return track->album() ? QVariant(track->album()->name()) : QVariant(); case Meta::valGenre: return track->genre() ? QVariant(track->genre()->name()) : QVariant(); case Meta::valComposer: return track->composer() ? QVariant(track->composer()->name()) : QVariant(); case Meta::valYear: return track->year() ? QVariant(track->year()->name().toInt()) : QVariant(); case Meta::valComment: return track->comment(); case Meta::valTrackNr: return track->trackNumber(); case Meta::valDiscNr: return track->discNumber(); case Meta::valBpm: return track->bpm(); case Meta::valLength: return track->length(); case Meta::valBitrate: return track->bitrate(); case Meta::valSamplerate: return track->sampleRate(); case Meta::valFilesize: return track->filesize(); case Meta::valFormat: return int(Amarok::FileTypeSupport::fileType(track->type())); case Meta::valCreateDate: return track->createDate(); case Meta::valScore: return track->statistics()->score(); case Meta::valRating: return track->statistics()->rating(); case Meta::valFirstPlayed: return track->statistics()->firstPlayed(); case Meta::valLastPlayed: return track->statistics()->lastPlayed(); case Meta::valPlaycount: return track->statistics()->playCount(); case Meta::valUniqueId: return track->uidUrl(); // todo case Meta::valTrackGain: return "track gain"; case Meta::valTrackGainPeak: return "track gain peak"; case Meta::valAlbumGain: return "album gain"; case Meta::valAlbumGainPeak: return "album gain peak"; case Meta::valAlbumArtist: return (track->album() && track->album()->albumArtist()) ? QVariant(track->album()->albumArtist()->name()) : QVariant(); case Meta::valLabel: { Meta::LabelList labels = track->labels(); QStringList strLabels; foreach( Meta::LabelPtr label, labels ) strLabels.append( label->name() ); return QVariant( strLabels ); } case Meta::valModified: return track->modifyDate(); default: return QVariant(); } }