/*************************************************************************** * Copyright (C) 2003-2005 Max Howell * * (C) 2003-2010 Mark Kretschmann * * (C) 2005-2007 Alexandre Oliveira * * (C) 2008 Dan Meltzer * * (C) 2008-2009 Jeff Mitchell * * * * 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "Track.h" #include "utils.h" #include "MetaTagLib.h" #include "MetaReplayGain.h" #include #include #include #include #include #include bool CollectionScanner::Track::s_useCharsetDetector = false; CollectionScanner::Track::Track( const QString &path, CollectionScanner::Directory* directory ) : m_valid( true ) , m_directory( directory ) , m_filetype( Amarok::Unknown ) , m_compilation( false ) , m_noCompilation( false ) , m_hasCover( false ) , m_year( -1 ) , m_disc( -1 ) , m_track( -1 ) , m_bpm( -1.0 ) , m_bitrate( -1 ) , m_length( -1.0 ) , m_samplerate( -1 ) , m_filesize( -1 ) , m_trackGain( -1.0 ) , m_trackPeakGain( -1.0 ) , m_albumGain( -1.0 ) , m_albumPeakGain( -1.0 ) , m_rating( -1.0 ) , m_score( -1.0 ) , m_playcount( -1.0 ) { static const int MAX_SENSIBLE_LENGTH = 1023; // the maximum length for normal strings. // in corner cases a longer string might cause problems see BUG:276894 // for the unit test. // in a debug build a file called "crash_amarok_here.ogg" will crash the collection // scanner if( path.contains("crash_amarok_here.ogg") ) { qDebug() << "Crashing at"<atEnd()) { reader->readNext(); if( reader->isStartElement() ) { QStringRef name = reader->name(); if( name == QLatin1String("uniqueid") ) m_uniqueid = reader->readElementText(QXmlStreamReader::SkipChildElements); else if( name == QLatin1String("path") ) m_path = reader->readElementText(QXmlStreamReader::SkipChildElements); else if( name == QLatin1String("rpath") ) m_rpath = reader->readElementText(QXmlStreamReader::SkipChildElements); else if( name == QLatin1String("filetype") ) m_filetype = (Amarok::FileType)reader->readElementText(QXmlStreamReader::SkipChildElements).toInt(); else if( name == QLatin1String("title") ) m_title = reader->readElementText(QXmlStreamReader::SkipChildElements); else if( name == QLatin1String("artist") ) m_artist = reader->readElementText(QXmlStreamReader::SkipChildElements); else if( name == QLatin1String("albumArtist") ) m_albumArtist = reader->readElementText(QXmlStreamReader::SkipChildElements); else if( name == QLatin1String("album") ) m_album = reader->readElementText(); else if( name == QLatin1String("compilation") ) { m_compilation = true; reader->skipCurrentElement(); } else if( name == QLatin1String("noCompilation") ) { m_noCompilation = true; reader->skipCurrentElement(); } else if( name == QLatin1String("hasCover") ) { m_hasCover = true; reader->skipCurrentElement(); } else if( name == QLatin1String("comment") ) m_comment = reader->readElementText(QXmlStreamReader::SkipChildElements); else if( name == QLatin1String("genre") ) m_genre = reader->readElementText(QXmlStreamReader::SkipChildElements); else if( name == QLatin1String("year") ) m_year = reader->readElementText(QXmlStreamReader::SkipChildElements).toInt(); else if( name == QLatin1String("disc") ) m_disc = reader->readElementText(QXmlStreamReader::SkipChildElements).toInt(); else if( name == QLatin1String("track") ) m_track = reader->readElementText(QXmlStreamReader::SkipChildElements).toInt(); else if( name == QLatin1String("bpm") ) m_bpm = reader->readElementText(QXmlStreamReader::SkipChildElements).toFloat(); else if( name == QLatin1String("bitrate") ) m_bitrate = reader->readElementText(QXmlStreamReader::SkipChildElements).toInt(); else if( name == QLatin1String("length") ) m_length = reader->readElementText(QXmlStreamReader::SkipChildElements).toLong(); else if( name == QLatin1String("samplerate") ) m_samplerate = reader->readElementText(QXmlStreamReader::SkipChildElements).toInt(); else if( name == QLatin1String("filesize") ) m_filesize = reader->readElementText(QXmlStreamReader::SkipChildElements).toLong(); else if( name == QLatin1String("mtime") ) m_modified = QDateTime::fromTime_t(reader->readElementText(QXmlStreamReader::SkipChildElements).toLong()); else if( name == QLatin1String("trackGain") ) m_trackGain = reader->readElementText(QXmlStreamReader::SkipChildElements).toFloat(); else if( name == QLatin1String("trackPeakGain") ) m_trackPeakGain = reader->readElementText(QXmlStreamReader::SkipChildElements).toFloat(); else if( name == QLatin1String("albumGain") ) m_albumGain = reader->readElementText(QXmlStreamReader::SkipChildElements).toFloat(); else if( name == QLatin1String("albumPeakGain") ) m_albumPeakGain = reader->readElementText(QXmlStreamReader::SkipChildElements).toFloat(); else if( name == QLatin1String("composer") ) m_composer = reader->readElementText(QXmlStreamReader::SkipChildElements); else if( name == QLatin1String("rating") ) m_rating = reader->readElementText(QXmlStreamReader::SkipChildElements).toFloat(); else if( name == QLatin1String("score") ) m_score = reader->readElementText(QXmlStreamReader::SkipChildElements).toFloat(); else if( name == QLatin1String("playcount") ) m_playcount = reader->readElementText(QXmlStreamReader::SkipChildElements).toInt(); else { qDebug() << "Unexpected xml start element"<skipCurrentElement(); } } else if( reader->isEndElement() ) { break; } } } void CollectionScanner::Track::write( QXmlStreamWriter *writer, const QString &tag, const QString &str ) const { if( !str.isEmpty() ) writer->writeTextElement( tag, escapeXml10(str) ); } void CollectionScanner::Track::toXml( QXmlStreamWriter *writer ) const { if( !m_valid ) return; write( writer, QLatin1String("uniqueid"), m_uniqueid ); write( writer, QLatin1String("path"), m_path ); write( writer, QLatin1String("rpath"), m_rpath ); write(writer, QLatin1String("filetype"), QString::number( (int)m_filetype ) ); write( writer, QLatin1String("title"), m_title); write( writer, QLatin1String("artist"), m_artist); write( writer, QLatin1String("albumArtist"), m_albumArtist); write( writer, QLatin1String("album"), m_album); if( m_compilation ) writer->writeEmptyElement( QLatin1String("compilation") ); if( m_noCompilation ) writer->writeEmptyElement( QLatin1String("noCompilation") ); if( m_hasCover ) writer->writeEmptyElement( QLatin1String("hasCover") ); write( writer, QLatin1String("comment"), m_comment); write( writer, QLatin1String("genre"), m_genre); if( m_year != -1 ) write(writer, QLatin1String("year"), QString::number( m_year ) ); if( m_disc != -1 ) write(writer, QLatin1String("disc"), QString::number( m_disc ) ); if( m_track != -1 ) write(writer, QLatin1String("track"), QString::number( m_track ) ); if( m_bpm != -1 ) write(writer, QLatin1String("bpm"), QString::number( m_bpm ) ); if( m_bitrate != -1 ) write(writer, QLatin1String("bitrate"), QString::number( m_bitrate ) ); if( m_length != -1 ) write(writer, QLatin1String("length"), QString::number( m_length ) ); if( m_samplerate != -1 ) write(writer, QLatin1String("samplerate"), QString::number( m_samplerate ) ); if( m_filesize != -1 ) write(writer, QLatin1String("filesize"), QString::number( m_filesize ) ); if( m_modified.isValid() ) write(writer, QLatin1String("mtime"), QString::number( m_modified.toTime_t() ) ); if( m_trackGain != 0 ) write(writer, QLatin1String("trackGain"), QString::number( m_trackGain ) ); if( m_trackPeakGain != 0 ) write(writer, QLatin1String("trackPeakGain"), QString::number( m_trackPeakGain ) ); if( m_albumGain != 0 ) write(writer, QLatin1String("albumGain"), QString::number( m_albumGain ) ); if( m_albumPeakGain != 0 ) write(writer, QLatin1String("albumPeakGain"), QString::number( m_albumPeakGain ) ); write( writer, QLatin1String("composer"), m_composer); if( m_rating != -1 ) write(writer, QLatin1String("rating"), QString::number( m_rating ) ); if( m_score != -1 ) write(writer, QLatin1String("score"), QString::number( m_score ) ); if( m_playcount != -1 ) write(writer, QLatin1String("playcount"), QString::number( m_playcount ) ); } bool CollectionScanner::Track::isValid() const { return m_valid; } CollectionScanner::Directory* CollectionScanner::Track::directory() const { return m_directory; } QString CollectionScanner::Track::uniqueid() const { return m_uniqueid; } QString CollectionScanner::Track::path() const { return m_path; } QString CollectionScanner::Track::rpath() const { return m_rpath; } Amarok::FileType CollectionScanner::Track::filetype() const { return m_filetype; } QString CollectionScanner::Track::title() const { return m_title; } QString CollectionScanner::Track::artist() const { return m_artist; } QString CollectionScanner::Track::albumArtist() const { return m_albumArtist; } QString CollectionScanner::Track::album() const { return m_album; } bool CollectionScanner::Track::isCompilation() const { return m_compilation; } bool CollectionScanner::Track::isNoCompilation() const { return m_noCompilation; } bool CollectionScanner::Track::hasCover() const { return m_hasCover; } QString CollectionScanner::Track::comment() const { return m_comment; } QString CollectionScanner::Track::genre() const { return m_genre; } int CollectionScanner::Track::year() const { return m_year; } int CollectionScanner::Track::disc() const { return m_disc; } int CollectionScanner::Track::track() const { return m_track; } int CollectionScanner::Track::bpm() const { return m_bpm; } int CollectionScanner::Track::bitrate() const { return m_bitrate; } qint64 CollectionScanner::Track::length() const { return m_length; } int CollectionScanner::Track::samplerate() const { return m_samplerate; } qint64 CollectionScanner::Track::filesize() const { return m_filesize; } QDateTime CollectionScanner::Track::modified() const { return m_modified; } QString CollectionScanner::Track::composer() const { return m_composer; } qreal CollectionScanner::Track::replayGain( Meta::ReplayGainTag mode ) const { switch( mode ) { case Meta::ReplayGain_Track_Gain: return m_trackGain; case Meta::ReplayGain_Track_Peak: return m_trackPeakGain; case Meta::ReplayGain_Album_Gain: return m_albumGain; case Meta::ReplayGain_Album_Peak: return m_albumPeakGain; } return 0.0; } qreal CollectionScanner::Track::rating() const { return m_rating; } qreal CollectionScanner::Track::score() const { return m_score; } int CollectionScanner::Track::playcount() const { return m_playcount; } void CollectionScanner::Track::setUseCharsetDetector( bool value ) { s_useCharsetDetector = value; }