예제 #1
0
Meta::TrackPtr
SqlRegistry::getTrack( int urlId )
{
    QString query = "SELECT %1 FROM urls %2 "
        "WHERE urls.id = %3";
    query = query.arg( Meta::SqlTrack::getTrackReturnValues(),
                       Meta::SqlTrack::getTrackJoinConditions(),
                       QString::number( urlId ) );
    QStringList rowData = m_collection->sqlStorage()->query( query );
    if( rowData.isEmpty() )
        return Meta::TrackPtr();

    TrackPath id( rowData[Meta::SqlTrack::returnIndex_urlDeviceId].toInt(),
                rowData[Meta::SqlTrack::returnIndex_urlRPath] );
    QString uid = rowData[Meta::SqlTrack::returnIndex_urlUid];

    QMutexLocker locker( &m_trackMutex );
    if( m_trackMap.contains( id ) )
    {
        Meta::SqlTrackPtr track = Meta::SqlTrackPtr::staticCast( m_trackMap[ id ] );
        // yes, it may happen that we get a different track in corner cases, see bug 323156
        if( track->urlId() == urlId )
            return Meta::TrackPtr::staticCast( track );
        warning() << Q_FUNC_INFO << "track with (deviceId, rpath)" << id << "found in"
                  << "m_trackMap, but it had different urlId (" << track->urlId() << ")"
                  << "than requested (" << urlId << "). This may happen in corner-cases.";
    }
    if( m_uidMap.contains( uid ) )
    {
        Meta::SqlTrackPtr track = Meta::SqlTrackPtr::staticCast( m_uidMap[ uid ] );
        // yes, it may happen that we get a different track in corner cases, see bug 323156
        if( track->urlId() == urlId )
            return Meta::TrackPtr::staticCast( track );
        warning() << Q_FUNC_INFO << "track with uid" << uid << "found in m_uidMap, but it"
                  << "had different urlId (" << track->urlId() << ") than requested ("
                  << urlId << "). This may happen in corner-cases.";
    }

    Meta::SqlTrack *sqlTrack = new Meta::SqlTrack( m_collection, rowData );
    Meta::TrackPtr trackPtr( sqlTrack );

    m_trackMap.insert( id, trackPtr );
    m_uidMap.insert( sqlTrack->uidUrl(), trackPtr );
    return trackPtr;
}
예제 #2
0
void
SqlScanResultProcessor::commitTrack( CollectionScanner::Track *track,
                                     CollectionScanner::Album *srcAlbum )
{
    // debug() << "commitTrack on"<<track->title()<< "album"<<srcAlbum->name() << "dir:" << track->directory()->path()<<track->directory();

    Q_ASSERT( track );
    Q_ASSERT( srcAlbum );

    Q_ASSERT( m_directoryIds.contains( track->directory() ) );
    int directoryId = m_directoryIds.value( track->directory() );
    Q_ASSERT( m_albumIds.contains( srcAlbum ) );
    int albumId = m_albumIds.value( srcAlbum );

    QString uid = track->uniqueid();
    if( uid.isEmpty() )
    {
        warning() << "commitTrack(): got track with empty unique id from the scanner,"
                  << "not adding it";
        m_messages.append( QString( "Not adding track %1 because it has no unique id." ).
                           arg(track->path()) );
        return;
    }
    uid = m_collection->generateUidUrl( uid );

    int deviceId = m_collection->mountPointManager()->getIdForUrl( track->path() );
    QString rpath = m_collection->mountPointManager()->getRelativePath( deviceId, track->path() );

    if( m_foundTracks.contains( uid ) )
    {
        const UrlEntry old = m_urlsCache.value( m_uidCache.value( uid ) );
        const char *pattern = I18N_NOOP( "Duplicates found, the second file will be ignored:\n%1\n%2" );

        // we want translated version for GUI and non-translated for debug log
        warning() << "commitTrack():" << QString( pattern ).arg( old.path, track->path() );
        m_messages.append( i18n( pattern, old.path, track->path() ) );
        return;
    }

    Meta::SqlTrackPtr metaTrack;
    UrlEntry entry;
    // find an existing track by uid
    if( m_uidCache.contains( uid ) )
    {
        // uid is sadly not unique. Try to find the best url id.
        int urlId = findBestUrlId( uid, track->path() );
        Q_ASSERT( urlId > 0 );
        Q_ASSERT( m_urlsCache.contains( urlId ) );
        entry = m_urlsCache.value( urlId );
        entry.path = track->path();
        entry.directoryId = directoryId;

        metaTrack = Meta::SqlTrackPtr::staticCast( m_collection->registry()->getTrack( urlId ) );
        Q_ASSERT( metaTrack->urlId() == entry.id );
    }
    // find an existing track by path
    else if( m_pathCache.contains( track->path() ) )
    {
        int urlId = m_pathCache.value( track->path() );
        Q_ASSERT( m_urlsCache.contains( urlId ) );
        entry = m_urlsCache.value( urlId );
        entry.uid = uid;
        entry.directoryId = directoryId;

        metaTrack = Meta::SqlTrackPtr::staticCast( m_collection->registry()->getTrack( urlId ) );
        Q_ASSERT( metaTrack->urlId() == entry.id );
    }
    // create a new one
    else
    {
        static int autoDecrementId = -1;
        entry.id = autoDecrementId--;
        entry.path = track->path();
        entry.uid = uid;
        entry.directoryId = directoryId;

        metaTrack = Meta::SqlTrackPtr::staticCast( m_collection->getTrack( deviceId, rpath, directoryId, uid ) );
    }

    if( !metaTrack )
    {
        QString text = QString( "Something went wrong when importing track %1, metaTrack "
                                "is null while it shouldn't be." ).arg( track->path() );
        warning() << "commitTrack():" << text.toLocal8Bit().data();
        m_messages.append( text );
        return;
    }
    urlsCacheInsert( entry ); // removes the previous entry (by id) first if necessary
    m_foundTracks.insert( uid, entry.id );

    // TODO: we need to check the modified date of the file agains the last updated of the file
    // to figure out if the track information was updated from outside Amarok.
    // In such a case we would fully reread all the information as if in a FullScan

    // -- set the values
    metaTrack->setWriteFile( false ); // no need to write the tags back
    metaTrack->beginUpdate();

    metaTrack->setUidUrl( uid );
    metaTrack->setUrl( deviceId, rpath, directoryId );

    if( m_type == GenericScanManager::FullScan ||
            !track->title().isEmpty() )
        metaTrack->setTitle( track->title() );

    if( m_type == GenericScanManager::FullScan ||
            albumId != -1 )
        metaTrack->setAlbum( albumId );

    if( m_type == GenericScanManager::FullScan ||
            !track->artist().isEmpty() )
        metaTrack->setArtist( track->artist() );

    if( m_type == GenericScanManager::FullScan ||
            !track->composer().isEmpty() )
        metaTrack->setComposer( track->composer() );

    if( m_type == GenericScanManager::FullScan ||
            track->year() >= 0 )
        metaTrack->setYear( (track->year() >= 0) ? track->year() : 0 );

    if( m_type == GenericScanManager::FullScan ||
            !track->genre().isEmpty() )
        metaTrack->setGenre( track->genre() );

    metaTrack->setType( track->filetype() );

    if( m_type == GenericScanManager::FullScan ||
            track->bpm() >= 0 )
        metaTrack->setBpm( track->bpm() );

    if( m_type == GenericScanManager::FullScan ||
            !track->comment().isEmpty() )
        metaTrack->setComment( track->comment() );

    if( (m_type == GenericScanManager::FullScan || metaTrack->score() == 0) &&
            track->score() >= 0 )
        metaTrack->setScore( track->score() );

    if( (m_type == GenericScanManager::FullScan || metaTrack->rating() == 0.0) &&
            track->rating() >= 0 )
        metaTrack->setRating( track->rating() );

    if( (m_type == GenericScanManager::FullScan || metaTrack->length() == 0) &&
            track->length() >= 0 )
        metaTrack->setLength( track->length() );

    // the filesize is updated every time after the
    // file is changed. Doesn't make sense to set it.

    if( (m_type == GenericScanManager::FullScan || !metaTrack->modifyDate().isValid()) &&
            track->modified().isValid() )
        metaTrack->setModifyDate( track->modified() );

    if( (m_type == GenericScanManager::FullScan || metaTrack->sampleRate() == 0) &&
            track->samplerate() >= 0 )
        metaTrack->setSampleRate( track->samplerate() );

    if( (m_type == GenericScanManager::FullScan || metaTrack->bitrate() == 0) &&
            track->bitrate() >= 0 )
        metaTrack->setBitrate( track->bitrate() );

    if( (m_type == GenericScanManager::FullScan || metaTrack->trackNumber() == 0) &&
            track->track() >= 0 )
        metaTrack->setTrackNumber( track->track() );

    if( (m_type == GenericScanManager::FullScan || metaTrack->discNumber() == 0) &&
            track->disc() >= 0 )
        metaTrack->setDiscNumber( track->disc() );

    if( m_type == GenericScanManager::FullScan && track->playcount() >= metaTrack->playCount() )
        metaTrack->setPlayCount( track->playcount() );


    Meta::ReplayGainTag modes[] = { Meta::ReplayGain_Track_Gain,
                                    Meta::ReplayGain_Track_Peak,
                                    Meta::ReplayGain_Album_Gain,
                                    Meta::ReplayGain_Album_Peak
                                  };

    for( int i=0; i<4; i++ )
    {
        if( track->replayGain( modes[i] ) != 0.0 )
            metaTrack->setReplayGain( modes[i], track->replayGain( modes[i] ) );
    }

    metaTrack->endUpdate();
    metaTrack->setWriteFile( true );
}