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
TreeItem* TraktorFeature::importLibrary(QString file) {
    //Give thread a low priority
    QThread* thisThread = QThread::currentThread();
    thisThread->setPriority(QThread::LowestPriority);
    //Invisible root item of Traktor's child model
    TreeItem* root = NULL;
    //Delete all table entries of Traktor feature
    ScopedTransaction transaction(m_database);
    clearTable("traktor_playlist_tracks");
    clearTable("traktor_library");
    clearTable("traktor_playlists");
    transaction.commit();

    transaction.transaction();
    QSqlQuery query(m_database);
    query.prepare("INSERT INTO traktor_library (artist, title, album, year,"
                  "genre,comment,tracknumber,bpm, bitrate,duration, location,"
                  "rating,key) VALUES (:artist, :title, :album, :year,:genre,"
                  ":comment, :tracknumber,:bpm, :bitrate,:duration, :location,"
                  ":rating,:key)");

    //Parse Trakor XML file using SAX (for performance)
    QFile traktor_file(file);
    if (!traktor_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "Cannot open Traktor music collection";
        return NULL;
    }
    QXmlStreamReader xml(&traktor_file);
    bool inCollectionTag = false;
    //TODO(XXX) is this still needed to parse the library correctly?
    bool inEntryTag = false;
    bool inPlaylistsTag = false;
    bool isRootFolderParsed = false;
    int nAudioFiles = 0;

    while (!xml.atEnd() && !m_cancelImport) {
        xml.readNext();
        if (xml.isStartElement()) {
            if (xml.name() == "COLLECTION") {
                inCollectionTag = true;
            }
            // Each "ENTRY" tag in <COLLECTION> represents a track
            if (inCollectionTag && xml.name() == "ENTRY" ) {
                inEntryTag = true;
                //parse track
                parseTrack(xml, query);
                ++nAudioFiles; //increment number of files in the music collection
            }
            if (xml.name() == "PLAYLISTS") {
                inPlaylistsTag = true;
            } if (inPlaylistsTag && !isRootFolderParsed && xml.name() == "NODE") {
                QXmlStreamAttributes attr = xml.attributes();
                QString nodetype = attr.value("TYPE").toString();
                QString name = attr.value("NAME").toString();

                if (nodetype == "FOLDER" && name == "$ROOT") {
                    //process all playlists
                    root = parsePlaylists(xml);
                    isRootFolderParsed = true;
                }
            }
        }
        if (xml.isEndElement()) {
            if (xml.name() == "COLLECTION") {
                inCollectionTag = false;
            }
            if (xml.name() == "ENTRY" && inCollectionTag) {
                inEntryTag = false;
            }
            if (xml.name() == "PLAYLISTS" && inPlaylistsTag) {
                inPlaylistsTag = false;
            }
        }
    }
    if (xml.hasError()) {
         // do error handling
         qDebug() << "Cannot process Traktor music collection";
         if (root)
             delete root;
         return NULL;
    }

    qDebug() << "Found: " << nAudioFiles << " audio files in Traktor";
    //initialize TraktorTableModel
    transaction.commit();

    return root;
}
Example #3
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;
}