diff --git a/src/services/magnatune/MagnatuneXmlParser.cpp b/src/services/magnatune/MagnatuneXmlParser.cpp index 1373dfb4a5..b08bab502e 100644 --- a/src/services/magnatune/MagnatuneXmlParser.cpp +++ b/src/services/magnatune/MagnatuneXmlParser.cpp @@ -1,432 +1,430 @@ /**************************************************************************************** * Copyright (c) 2006,2007 Nikolaj Hald Nielsen * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #include "MagnatuneXmlParser.h" #include "core/support/Amarok.h" #include "core/support/Debug.h" #include "core/support/Components.h" #include "core/interfaces/Logger.h" #include #include #include #include using namespace Meta; MagnatuneXmlParser::MagnatuneXmlParser( const QString &filename ) : QObject() , ThreadWeaver::Job() { m_sFileName = filename; connect( this, &MagnatuneXmlParser::done, this, &MagnatuneXmlParser::completeJob ); } MagnatuneXmlParser::~MagnatuneXmlParser() { QFile(m_sFileName).remove(); qDeleteAll(m_currentAlbumTracksList); } void MagnatuneXmlParser::run(ThreadWeaver::JobPointer self, ThreadWeaver::Thread *thread) { Q_UNUSED(self); Q_UNUSED(thread); readConfigFile( m_sFileName ); } void MagnatuneXmlParser::defaultBegin(const ThreadWeaver::JobPointer& self, ThreadWeaver::Thread *thread) { Q_EMIT started(self); ThreadWeaver::Job::defaultBegin(self, thread); } void MagnatuneXmlParser::defaultEnd(const ThreadWeaver::JobPointer& self, ThreadWeaver::Thread *thread) { ThreadWeaver::Job::defaultEnd(self, thread); if (!self->success()) { Q_EMIT failed(self); } Q_EMIT done(self); } void MagnatuneXmlParser::completeJob( ) { Amarok::Components::logger()->longMessage( i18ncp( "First part of: Magnatune.com database update complete. Database contains 3 tracks on 4 albums from 5 artists.", "Magnatune.com database update complete. Database contains 1 track on ", "Magnatune.com database update complete. Database contains %1 tracks on ", m_nNumberOfTracks) + i18ncp( "Middle part of: Magnatune.com database update complete. Database contains 3 tracks on 4 albums from 5 artists.", "1 album from ", "%1 albums from ", m_nNumberOfAlbums) + i18ncp( "Last part of: Magnatune.com database update complete. Database contains 3 tracks on 4 albums from 5 artists.", "1 artist.", "%1 artists.", m_nNumberOfArtists ) , Amarok::Logger::Information ); emit doneParsing(); deleteLater(); } void MagnatuneXmlParser::readConfigFile( const QString &filename ) { DEBUG_BLOCK m_nNumberOfTracks = 0; m_nNumberOfAlbums = 0; m_nNumberOfArtists = 0; QDomDocument doc( "config" ); if ( !QFile::exists( filename ) ) { debug() << "Magnatune xml file does not exist"; return; } - QFile file( filename ); - auto device = new KCompressionDevice( &file, true, KCompressionDevice::BZip2 ); - if ( !device || !device->open( QIODevice::ReadOnly ) ) { + KCompressionDevice device( filename, KCompressionDevice::BZip2 ); + if ( !device.open( QIODevice::ReadOnly ) ) { debug() << "MagnatuneXmlParser::readConfigFile error reading file"; return ; } - if ( !doc.setContent( device ) ) + if ( !doc.setContent( &device ) ) { debug() << "MagnatuneXmlParser::readConfigFile error parsing file"; - device->close(); + device.close(); return ; } - device->close(); - delete device; + device.close(); m_dbHandler->destroyDatabase(); m_dbHandler->createDatabase(); //run through all the elements QDomElement docElem = doc.documentElement(); m_dbHandler->begin(); //start transaction (MAJOR speedup!!) parseElement( docElem ); m_dbHandler->commit(); //complete transaction - return ; + return; } void MagnatuneXmlParser::parseElement( const QDomElement &e ) { QString sElementName = e.tagName(); sElementName == "Album" ? parseAlbum( e ) : parseChildren( e ); } void MagnatuneXmlParser::parseChildren( const QDomElement &e ) { QDomNode n = e.firstChild(); while ( !n.isNull() ) { if ( n.isElement() ) parseElement( n.toElement() ); n = n.nextSibling(); } } void MagnatuneXmlParser::parseAlbum( const QDomElement &e ) { //DEBUG_BLOCK QString sElementName; QString name; QString albumCode; QStringList magnatuneGenres; int launchYear = 0; QString coverUrl; QString description; QString artistName; QString artistDescription; QUrl artistPhotoUrl; QString mp3Genre; QUrl artistPageUrl; QDomNode n = e.firstChild(); QDomElement childElement; while ( !n.isNull() ) { if ( n.isElement() ) { childElement = n.toElement(); QString sElementName = childElement.tagName(); if ( sElementName == "albumname" ) //printf(("|--+" + childElement.text() + "\n").toLatin1()); //m_currentAlbumItem = new MagnatuneListViewAlbumItem( m_currentArtistItem); name = childElement.text(); else if ( sElementName == "albumsku" ) albumCode = childElement.text(); else if ( sElementName == "magnatunegenres" ) magnatuneGenres = childElement.text().split(',', QString::SkipEmptyParts); else if ( sElementName == "launchdate" ) { QString dateString = childElement.text(); QDate date = QDate::fromString( dateString, Qt::ISODate ); launchYear = date.year(); } else if ( sElementName == "cover_small" ) coverUrl = childElement.text(); else if ( sElementName == "artist" ) artistName = childElement.text(); else if ( sElementName == "artistdesc" ) artistDescription = childElement.text(); else if ( sElementName == "artistphoto" ) artistPhotoUrl = QUrl( childElement.text() ); else if ( sElementName == "mp3genre" ) mp3Genre = childElement.text(); else if ( sElementName == "home" ) artistPageUrl = QUrl( childElement.text() ); else if ( sElementName == "Track" ) parseTrack( childElement ); else if ( sElementName == "album_notes" ) description = childElement.text(); } n = n.nextSibling(); } m_pCurrentAlbum.reset(new MagnatuneAlbum( name )); m_pCurrentAlbum->setAlbumCode( albumCode); m_pCurrentAlbum->setLaunchYear( launchYear ); m_pCurrentAlbum->setCoverUrl( coverUrl ); m_pCurrentAlbum->setDescription( description ); // now we should have gathered all info about current album (and artist)... //Time to add stuff to the database //check if artist already exists, if not, create him/her/them/it int artistId; if ( artistNameIdMap.contains( artistName ) ) { artistId = artistNameIdMap.value( artistName ); } else { //does not exist, lets create it... m_pCurrentArtist.reset(new MagnatuneArtist( artistName )); m_pCurrentArtist->setDescription( artistDescription ); m_pCurrentArtist->setPhotoUrl( artistPhotoUrl ); m_pCurrentArtist->setMagnatuneUrl( artistPageUrl ); //this is tricky in postgresql, returns id as 0 (we are within a transaction, might be the cause...) artistId = m_dbHandler->insertArtist( m_pCurrentArtist.data() ); m_nNumberOfArtists++; if ( artistId == 0 ) { artistId = m_dbHandler->getArtistIdByExactName( m_pCurrentArtist->name() ); } m_pCurrentArtist->setId( artistId ); artistNameIdMap.insert( m_pCurrentArtist->name() , artistId ); } m_pCurrentAlbum->setArtistId( artistId ); int albumId = m_dbHandler->insertAlbum( m_pCurrentAlbum.data() ); if ( albumId == 0 ) // again, postgres can play tricks on us... { albumId = m_dbHandler->getAlbumIdByAlbumCode( m_pCurrentAlbum->albumCode() ); } m_pCurrentAlbum->setId( albumId ); m_nNumberOfAlbums++; QList::iterator it; for ( it = m_currentAlbumTracksList.begin(); it != m_currentAlbumTracksList.end(); ++it ) { ( *it )->setAlbumId( m_pCurrentAlbum->id() ); ( *it )->setArtistId( artistId ); int trackId = m_dbHandler->insertTrack( ( *it ) ); m_dbHandler->insertMoods( trackId, ( *it )->moods() ); m_nNumberOfTracks++; } // handle genres foreach( const QString &genreName, magnatuneGenres ) { //debug() << "inserting genre with album_id = " << albumId << " and name = " << genreName; ServiceGenre currentGenre( genreName ); currentGenre.setAlbumId( albumId ); m_dbHandler->insertGenre( ¤tGenre ); } magnatuneGenres.clear(); qDeleteAll(m_currentAlbumTracksList); m_currentAlbumTracksList.clear(); } void MagnatuneXmlParser::parseTrack( const QDomElement &e ) { //DEBUG_BLOCK m_currentTrackMoodList.clear(); QString trackName; QString trackNumber; QString streamingUrl; QString sElementName; QDomElement childElement; MagnatuneTrack * pCurrentTrack = new MagnatuneTrack( QString() ); QDomNode n = e.firstChild(); while ( !n.isNull() ) { if ( n.isElement() ) { childElement = n.toElement(); QString sElementName = childElement.tagName(); if ( sElementName == "trackname" ) { pCurrentTrack->setTitle( childElement.text() ); } else if ( sElementName == "url" ) { pCurrentTrack->setUidUrl( childElement.text() ); } else if ( sElementName == "oggurl" ) { pCurrentTrack->setOggUrl( childElement.text() ); } else if ( sElementName == "mp3lofi" ) { pCurrentTrack->setLofiUrl( childElement.text() ); } else if ( sElementName == "tracknum" ) { pCurrentTrack->setTrackNumber( childElement.text().toInt() ); } else if ( sElementName == "seconds" ) { pCurrentTrack->setLength( childElement.text().toInt() ); } else if ( sElementName == "moods" ) { parseMoods( childElement ); } } n = n.nextSibling(); } pCurrentTrack->setMoods( m_currentTrackMoodList ); m_currentAlbumTracksList.append( pCurrentTrack ); } void MagnatuneXmlParser::parseMoods( const QDomElement &e ) { //DEBUG_BLOCK QDomNode n = e.firstChild(); QDomElement childElement; while ( !n.isNull() ) { if ( n.isElement() ) { childElement = n.toElement(); QString sElementName = childElement.tagName(); if ( sElementName == "mood" ) { m_currentTrackMoodList.append( childElement.text() ); } else { //error, should not be here.... } } n = n.nextSibling(); } } void MagnatuneXmlParser::setDbHandler(MagnatuneDatabaseHandler * dbHandler) { m_dbHandler = dbHandler; }