Example #1
0
// This method is executed in a separate thread
// via QtConcurrent::run
TreeItem* ITunesFeature::importLibrary() {
    //Give thread a low priority
    QThread* thisThread = QThread::currentThread();
    thisThread->setPriority(QThread::LowestPriority);

    //Delete all table entries of iTunes feature
    ScopedTransaction transaction(m_database);
    clearTable("itunes_playlist_tracks");
    clearTable("itunes_library");
    clearTable("itunes_playlists");
    transaction.commit();

    qDebug() << "ITunesFeature::importLibrary() ";

    transaction.transaction();

    // By default set m_mixxxItunesRoot and m_dbItunesRoot to strip out
    // file://localhost/ from the URL. When we load the user's iTunes XML
    // configuration we may replace this with something based on the detected
    // location of the user's iTunes path but the defaults are necessary in case
    // their iTunes XML does not include the "Music Folder" key.
    m_mixxxItunesRoot = "";
    m_dbItunesRoot = localhost_token();

    //Parse iTunes XML file using SAX (for performance)
    QFile itunes_file(m_dbfile);
    if (!itunes_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "Cannot open iTunes music collection";
        return NULL;
    }
    QXmlStreamReader xml(&itunes_file);
    TreeItem* playlist_root = NULL;
    while (!xml.atEnd() && !m_cancelImport) {
        xml.readNext();
        if (xml.isStartElement()) {
            if (xml.name() == "key") {
                QString key = xml.readElementText();
                if (key == "Music Folder") {
                    if (readNextStartElement(xml)) {
                        guessMusicLibraryMountpoint(xml);
                    }
                } else if (key == "Tracks") {
                    parseTracks(xml);
                    playlist_root = parsePlaylists(xml);
                }
            }
        }
    }

    itunes_file.close();

    // Even if an error occured, commit the transaction. The file may have been
    // half-parsed.
    transaction.commit();

    if (xml.hasError()) {
        // do error handling
        qDebug() << "Cannot process iTunes music collection";
        qDebug() << "XML ERROR: " << xml.errorString();
        if (playlist_root)
            delete playlist_root;
        playlist_root = NULL;
    }
    return playlist_root;
}
Example #2
0
// This method is executed in a separate thread
// via QtConcurrent::run
TreeItem* ITunesFeature::importLibrary() {
    bool isTracksParsed=false;
    bool isMusicFolderLocatedAfterTracks=false;
  
    //Give thread a low priority
    QThread* thisThread = QThread::currentThread();
    thisThread->setPriority(QThread::LowPriority);

    //Delete all table entries of iTunes feature
    ScopedTransaction transaction(m_database);
    clearTable("itunes_playlist_tracks");
    clearTable("itunes_library");
    clearTable("itunes_playlists");
    transaction.commit();

    qDebug() << "ITunesFeature::importLibrary() ";

    transaction.transaction();

    // By default set m_mixxxItunesRoot and m_dbItunesRoot to strip out
    // file://localhost/ from the URL. When we load the user's iTunes XML
    // configuration we may replace this with something based on the detected
    // location of the user's iTunes path but the defaults are necessary in case
    // their iTunes XML does not include the "Music Folder" key.
    m_mixxxItunesRoot = "";
    m_dbItunesRoot = localhost_token();

    //Parse iTunes XML file using SAX (for performance)
    QFile itunes_file(m_dbfile);
    if (!itunes_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "Cannot open iTunes music collection";
        return NULL;
    }

    QXmlStreamReader xml(&itunes_file);
    TreeItem* playlist_root = NULL;
    while (!xml.atEnd() && !m_cancelImport) {
        xml.readNext();
        if (xml.isStartElement()) {
            if (xml.name() == "key") {
                QString key = xml.readElementText();
                if (key == "Music Folder") {
                    if (isTracksParsed) isMusicFolderLocatedAfterTracks = true;
                    if (readNextStartElement(xml)) {
                        guessMusicLibraryMountpoint(xml);
                    }
                } else if (key == "Tracks") {
                    parseTracks(xml);
                    if (playlist_root != NULL)
                        delete playlist_root;
                    playlist_root = parsePlaylists(xml);
                    isTracksParsed = true;
                }
            }
        }
    }

    itunes_file.close();
    
    if (isMusicFolderLocatedAfterTracks) {
        qDebug() << "Updating iTunes real path from " << m_dbItunesRoot << " to " << m_mixxxItunesRoot;
        // In some iTunes files "Music Folder" XML node is located at the end of file. So, we need to 
        QSqlQuery query(m_database);
        query.prepare("UPDATE itunes_library SET location = replace( location, :itunes_path, :mixxx_path )");
        query.bindValue(":itunes_path", m_dbItunesRoot.replace(localhost_token(), ""));
        query.bindValue(":mixxx_path", m_mixxxItunesRoot);
        bool success = query.exec();

        if (!success) {
            LOG_FAILED_QUERY(query);
        }
    }

    // Even if an error occurred, commit the transaction. The file may have been
    // half-parsed.
    transaction.commit();

    if (xml.hasError()) {
        // do error handling
        qDebug() << "Cannot process iTunes music collection";
        qDebug() << "XML ERROR: " << xml.errorString();
        if (playlist_root)
            delete playlist_root;
        playlist_root = NULL;
    }
    return playlist_root;
}