![]() |
Mixxx
|
00001 /************************************************************************** 00002 * 1.7.x library upgrade code 00003 * 00004 * Description: 00005 * 00006 * Parse the mixxxtrack.xml file in order to create list of of songs to be 00007 * added to the sqlite database 1.8+ uses 00008 * 00009 * ***********************************************************************/ 00010 00011 #include <QDomDocument> 00012 #include <QDomNodeList> 00013 #include <QDomNode> 00014 #include <QDir> 00015 #include <QFile> 00016 #include <QDebug> 00017 #include "trackinfoobject.h" //needed for importing 1.7.x library 00018 #include "xmlparse.h" //needed for importing 1.7.x library 00019 #include "legacylibraryimporter.h" 00020 00021 struct LegacyPlaylist 00022 { 00023 QString name; 00024 QList<int> indexes; 00025 }; 00026 00027 void doNothing(TrackInfoObject*) { 00028 00029 } 00030 00031 LegacyLibraryImporter::LegacyLibraryImporter(TrackDAO& trackDao, 00032 PlaylistDAO& playlistDao) : QObject(), 00033 m_trackDao(trackDao), 00034 m_playlistDao(playlistDao) 00035 { 00036 } 00037 00039 void LegacyLibraryImporter::import() 00040 { 00041 QString trackXML = QDir::homePath().append("/").append(SETTINGS_PATH).append("mixxxtrack.xml"); 00042 QFile file(trackXML); 00043 00044 QDomDocument doc("TrackList"); 00045 00046 if(!file.open(QIODevice::ReadOnly)) { 00047 //qDebug() << "Could not import legacy 1.7 XML library: " << trackXML; 00048 return; 00049 } 00050 00051 QString* errorMsg = NULL; 00052 int* errorLine = NULL; 00053 int* errorColumn = NULL; 00054 00055 qDebug() << "Starting upgrade from 1.7 library..."; 00056 00057 QHash<int, QString> playlistHashTable; //Maps track indices onto track locations 00058 QList<LegacyPlaylist> legacyPlaylists; // <= 1.7 playlists 00059 00060 if (doc.setContent(&file, false, errorMsg, errorLine, errorColumn)) { 00061 00062 QDomNodeList playlistList = doc.elementsByTagName("Playlist"); 00063 QDomNode playlist; 00064 for (int i = 0; i < playlistList.size(); i++) 00065 { 00066 LegacyPlaylist legPlaylist; 00067 playlist = playlistList.at(i); 00068 00069 QString name = playlist.firstChildElement("Name").text(); 00070 00071 legPlaylist.name = name; 00072 00073 //Store the IDs in the hash table so we can map them to track locations later, 00074 //and also store them in-order in a temporary playlist struct. 00075 QDomElement listNode = playlist.firstChildElement("List").toElement(); 00076 QDomNodeList trackIDs = listNode.elementsByTagName("Id"); 00077 for (int j = 0; j < trackIDs.size(); j++) 00078 { 00079 int id = trackIDs.at(j).toElement().text().toInt(); 00080 if (!playlistHashTable.contains(id)) 00081 playlistHashTable.insert(id, ""); 00082 legPlaylist.indexes.push_back(id); //Save this track id. 00083 } 00084 //Save this playlist in our list. 00085 legacyPlaylists.push_back(legPlaylist); 00086 } 00087 00088 QDomNodeList trackList = doc.elementsByTagName("Track"); 00089 QDomNode track; 00090 00091 for (int i = 0; i < trackList.size(); i++) { 00092 //blah, can't figure out how to use an iterator with QDomNodeList 00093 track = trackList.at(i); 00094 TrackInfoObject trackInfo17(track); 00095 //Only add the track to the DB if the file exists on disk, 00096 //because Mixxx <= 1.7 had no logic to deal with detecting deleted 00097 //files. 00098 00099 if (trackInfo17.exists()) { 00100 //Create a TrackInfoObject by directly parsing 00101 //the actual MP3/OGG/whatever because 1.7 didn't parse 00102 //genre and album tags (so the imported TIO doesn't have 00103 //those fields). 00104 emit(progress("Upgrading Mixxx 1.7 Library: " + trackInfo17.getTitle())); 00105 00106 // Read the metadata we couldn't support in <1.8 from file. 00107 QFileInfo fileInfo(trackInfo17.getLocation()); 00108 //Ensure we have the absolute file path stored 00109 trackInfo17.setLocation(fileInfo.absoluteFilePath()); 00110 TrackInfoObject trackInfoNew(trackInfo17.getLocation()); 00111 trackInfo17.setGenre(trackInfoNew.getGenre()); 00112 trackInfo17.setAlbum(trackInfoNew.getAlbum()); 00113 trackInfo17.setYear(trackInfoNew.getYear()); 00114 trackInfo17.setType(trackInfoNew.getType()); 00115 trackInfo17.setTrackNumber(trackInfoNew.getTrackNumber()); 00116 trackInfo17.setKey(trackInfoNew.getKey()); 00117 trackInfo17.setHeaderParsed(true); 00118 00119 // Import the track's saved cue point if it is non-zero. 00120 float fCuePoint = trackInfo17.getCuePoint(); 00121 if (fCuePoint != 0.0f) { 00122 Cue* pCue = trackInfo17.addCue(); 00123 pCue->setType(Cue::CUE); 00124 pCue->setPosition(fCuePoint); 00125 } 00126 00127 // Provide a no-op deleter b/c this Track is on the stack. 00128 TrackPointer pTrack(&trackInfo17, &doNothing); 00129 m_trackDao.saveTrack(pTrack); 00130 00131 //Check if this track is used in a playlist anywhere. If it is, save the 00132 //track location. (The "id" of a track in 1.8 is a database index, so it's totally 00133 //different. Using the track location is the best way for us to identify the song.) 00134 int id = trackInfo17.getId(); 00135 if (playlistHashTable.contains(id)) 00136 playlistHashTable[id] = trackInfo17.getLocation(); 00137 } 00138 } 00139 00140 00141 //Create the imported playlists 00142 QListIterator<LegacyPlaylist> it(legacyPlaylists); 00143 LegacyPlaylist current; 00144 while (it.hasNext()) 00145 { 00146 current = it.next(); 00147 emit(progress("Upgrading Mixxx 1.7 Playlists: " + current.name)); 00148 00149 //Create the playlist with the imported name. 00150 //qDebug() << "Importing playlist:" << current.name; 00151 m_playlistDao.createPlaylist(current.name, false); 00152 int playlistId = m_playlistDao.getPlaylistIdFromName(current.name); 00153 00154 //For each track ID in the XML... 00155 QList<int> trackIDs = current.indexes; 00156 for (int i = 0; i < trackIDs.size(); i++) 00157 { 00158 QString trackLocation; 00159 int id = trackIDs[i]; 00160 //qDebug() << "track ID:" << id; 00161 00162 //Try to resolve the (XML's) track ID to a track location. 00163 if (playlistHashTable.contains(id)) { 00164 trackLocation = playlistHashTable[id]; 00165 //qDebug() << "Resolved to:" << trackLocation; 00166 } 00167 00168 //Get the database's track ID (NOT the XML's track ID!) 00169 int dbTrackId = m_trackDao.getTrackId(trackLocation); 00170 00171 if (dbTrackId >= 0) { 00172 //Add it to the database's playlist. 00173 m_playlistDao.appendTrackToPlaylist(dbTrackId, playlistId); 00174 } 00175 } 00176 } 00177 00178 QString upgrade_filename = QDir::homePath().append("/").append(SETTINGS_PATH).append("DBUPGRADED"); 00179 //now create stub so that the library is not readded next time program loads 00180 QFile upgradefile(upgrade_filename); 00181 if (!upgradefile.open(QIODevice::WriteOnly | QIODevice::Text)) 00182 qDebug() << "Couldn't open" << upgrade_filename << "for writing"; 00183 else 00184 { 00185 file.write("",0); 00186 file.close(); 00187 } 00188 } else { 00189 qDebug() << errorMsg << " line: " << errorLine << " column: " << errorColumn; 00190 } 00191 00192 file.close(); 00193 } 00194 00195 00196 LegacyLibraryImporter::~LegacyLibraryImporter() 00197 { 00198 }