// 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; }
// 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; }