/* * tagguesser.cpp - (c) 2003 Frerich Raabe * * 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. */ #include "tagguesser.h" #include #include #include #include #include FileNameScheme::FileNameScheme(const TQString &s) : m_regExp(), m_titleField(-1), m_artistField(-1), m_albumField(-1), m_trackField(-1), m_commentField(-1) { int fieldNumber = 1; int i = s.find('%'); while (i > -1) { switch (s[ i + 1 ]) { case 't': m_titleField = fieldNumber++; break; case 'a': m_artistField = fieldNumber++; break; case 'A': m_albumField = fieldNumber++; break; case 'T': m_trackField = fieldNumber++; break; case 'c': m_commentField = fieldNumber++; break; default: break; } i = s.find('%', i + 1); } m_regExp.setPattern(composeRegExp(s)); } bool FileNameScheme::matches(const TQString &fileName) const { /* Strip extension ('.mp3') because '.' may be part of a title, and thus * does not work as a separator. */ TQString stripped = fileName; stripped.truncate(stripped.findRev('.')); return m_regExp.exactMatch(stripped); } TQString FileNameScheme::title() const { if(m_titleField == -1) return TQString(); return m_regExp.capturedTexts()[ m_titleField ]; } TQString FileNameScheme::artist() const { if(m_artistField == -1) return TQString(); return m_regExp.capturedTexts()[ m_artistField ]; } TQString FileNameScheme::album() const { if(m_albumField == -1) return TQString(); return m_regExp.capturedTexts()[ m_albumField ]; } TQString FileNameScheme::track() const { if(m_trackField == -1) return TQString(); return m_regExp.capturedTexts()[ m_trackField ]; } TQString FileNameScheme::comment() const { if(m_commentField == -1) return TQString(); return m_regExp.capturedTexts()[ m_commentField ]; } TQString FileNameScheme::composeRegExp(const TQString &s) const { TQMap substitutions; TDEConfigGroup config(TDEGlobal::config(), "TagGuesser"); substitutions[ 't' ] = config.readEntry("Title regexp", "([\\w\\s'&_,\\.]+)"); substitutions[ 'a' ] = config.readEntry("Artist regexp", "([\\w\\s'&_,\\.]+)"); substitutions[ 'A' ] = config.readEntry("Album regexp", "([\\w\\s'&_,\\.]+)"); substitutions[ 'T' ] = config.readEntry("Track regexp", "(\\d+)"); substitutions[ 'c' ] = config.readEntry("Comment regexp", "([\\w\\s_]+)"); TQString regExp = TQRegExp::escape(s.simplifyWhiteSpace()); regExp = ".*" + regExp; regExp.replace(' ', "\\s+"); regExp = KMacroExpander::expandMacros(regExp, substitutions); regExp += "[^/]*$"; return regExp; } TQStringList TagGuesser::schemeStrings() { TQStringList schemes; TDEConfigGroup config(TDEGlobal::config(), "TagGuesser"); schemes = config.readListEntry("Filename schemes"); if ( schemes.isEmpty() ) { schemes += "%a - (%T) - %t [%c]"; schemes += "%a - (%T) - %t (%c)"; schemes += "%a - (%T) - %t"; schemes += "%a - [%T] - %t [%c]"; schemes += "%a - [%T] - %t (%c)"; schemes += "%a - [%T] - %t"; schemes += "%a - %T - %t [%c]"; schemes += "%a - %T - %t (%c)"; schemes += "%a - %T - %t"; schemes += "(%T) %a - %t [%c]"; schemes += "(%T) %a - %t (%c)"; schemes += "(%T) %a - %t"; schemes += "[%T] %a - %t [%c]"; schemes += "[%T] %a - %t (%c)"; schemes += "[%T] %a - %t"; schemes += "%T %a - %t [%c]"; schemes += "%T %a - %t (%c)"; schemes += "%T %a - %t"; schemes += "(%a) %t [%c]"; schemes += "(%a) %t (%c)"; schemes += "(%a) %t"; schemes += "%a - %t [%c]"; schemes += "%a - %t (%c)"; schemes += "%a - %t"; schemes += "%a/%A/[%T] %t [%c]"; schemes += "%a/%A/[%T] %t (%c)"; schemes += "%a/%A/[%T] %t"; } return schemes; } void TagGuesser::setSchemeStrings(const TQStringList &schemes) { TDEConfig *cfg = kapp->config(); { TDEConfigGroupSaver saver(cfg, "TagGuesser"); cfg->writeEntry("Filename schemes", schemes); } cfg->sync(); } TagGuesser::TagGuesser() { loadSchemes(); } TagGuesser::TagGuesser(const TQString &absFileName) { loadSchemes(); guess(absFileName); } void TagGuesser::loadSchemes() { const TQStringList schemes = schemeStrings(); TQStringList::ConstIterator it = schemes.begin(); TQStringList::ConstIterator end = schemes.end(); for ( ; it != end; ++it ) m_schemes += FileNameScheme( *it ); } void TagGuesser::guess(const TQString &absFileName) { m_title = m_artist = m_album = m_track = m_comment = TQString(); FileNameScheme::List::ConstIterator it = m_schemes.begin(); FileNameScheme::List::ConstIterator end = m_schemes.end(); for (; it != end; ++it) { const FileNameScheme schema(*it); if(schema.matches(absFileName)) { m_title = capitalizeWords(schema.title().replace('_', " ")).stripWhiteSpace(); m_artist = capitalizeWords(schema.artist().replace('_', " ")).stripWhiteSpace(); m_album = capitalizeWords(schema.album().replace('_', " ")).stripWhiteSpace(); m_track = schema.track().stripWhiteSpace(); m_comment = schema.comment().replace('_', " ").stripWhiteSpace(); break; } } } TQString TagGuesser::capitalizeWords(const TQString &s) { if(s.isEmpty()) return s; TQString result = s; result[ 0 ] = result[ 0 ].upper(); const TQRegExp wordRegExp("\\s\\w"); int i = result.find( wordRegExp ); while ( i > -1 ) { result[ i + 1 ] = result[ i + 1 ].upper(); i = result.find( wordRegExp, ++i ); } return result; } // vim:ts=4:sw=4:noet