- // Copyright (c) 2010 John Altenmueller | Altenmueller.com
- // This code may be freely used under the terms of the BSD license:
- // http://www.opensource.org/licenses/bsd-license.php
- #include <iostream>
- #include <string>
- #include <cstring>
- #include <cstdlib>
- #include <taglib/tag.h>
- #include <taglib/fileref.h>
- void printUsage();
- std::string tagToFilename( TagLib::Tag &tag, std::string format );
- int filenameToTag(TagLib::Tag &tag, std::string filename, std::string format);
- int filenameToTagWrapper(std::string format, std::string filename);
- int tagToFilenameWrapper( std::string format, std::string filename );
- std::string tagToFilename( TagLib::Tag &tag, std::string format )
- {
- char temp[1024];
- size_t pos=0;
- pos = format.find("%");
- while ( pos != std::string::npos )
- {
- switch( format[pos+1] )
- {
- case 'n':
- format.replace(pos, 2, tag.title().toCString());
- pos += tag.title().length();
- break;
- case 'a':
- format.replace(pos, 2, tag.artist().toCString());
- pos += tag.artist().length();
- break;
- case 'b':
- format.replace(pos, 2, tag.album().toCString());
- pos += tag.album().length();
- break;
- case 'g':
- format.replace(pos, 2, tag.genre().toCString());
- pos += tag.genre().length();
- break;
- case 'c':
- format.replace(pos, 2, tag.comment().toCString());
- pos += tag.comment().length();
- break;
- case 'y':
- sprintf(temp, "%d", tag.year());
- format.replace(pos, 2, temp);
- pos += strlen(temp);
- break;
- case 't':
- sprintf(temp, "%d", tag.track());
- format.replace(pos, 2, temp);
- pos += strlen(temp);
- break;
- default:
- return "";
- }
- pos = format.find("%", pos);
- }
- return format;
- }
- std::string trimWhitespace(std::string str)
- {
- str = str.erase( str.find_last_not_of(" ") + 1);
- str = str.erase( 0, str.find_first_not_of(" ") );
- return str;
- }
- int filenameToTag(TagLib::Tag &tag, std::string filename, std::string format)
- {
- size_t pos1, pos2;
- char type;
- int temp_int;
- char temp_str[1024];
- std::string temp_str2;
- std::string token;
- std::string temp_token;
- char extract[1024];
- char *extract_ptr;
- memset(temp_str, 0, 1024);
- filename = filename.substr(0, filename.rfind("."));
- pos1 = format.find("%");
- while (pos1 != std::string::npos)
- {
- pos2 = format.find("%", pos1+1);
- if (pos2 != std::string::npos)
- {
- token = format.substr(0, pos2);
- }
- else
- {
- token = format;
- }
- std::cout << "token=" << token << std::endl;
- switch (token[pos1+1])
- {
- case 'n':
- case 'a':
- case 'b':
- case 'g':
- case 'c':
- type = token[pos1+1];
- token[pos1+1] = 's';
- if (pos2 == std::string::npos)
- {
- size_t temp_pos = filename.rfind(format.substr(pos1+2));
- if (temp_pos != std::string::npos)
- {
- strncpy( temp_str, filename.substr(pos1, temp_pos-1).c_str(), 1024 );
- }
- else
- {
- strncpy( temp_str, filename.substr(pos1).c_str(), 1024 );
- }
- }
- else
- {
- temp_token = trimWhitespace(token.substr(2));
- if (temp_token.length())
- {
- temp_str2 = filename.substr(pos1, filename.find(temp_token));
- temp_str2 = trimWhitespace( temp_str2 );
- strncpy( temp_str, temp_str2.c_str(), 1024 );
- extract_ptr = temp_str;
- }
- else
- {
- sscanf( filename.c_str(), token.c_str(), temp_str );
- extract_ptr = temp_str;
- }
- }
- std::cout << "temp_str=" << temp_str << "|" << std::endl;
- if ( strlen(temp_str) )
- {
- switch (type)
- {
- case 'n':
- tag.setTitle(temp_str);
- break;
- case 'a':
- tag.setArtist(temp_str);
- break;
- case 'b':
- tag.setAlbum(temp_str);
- break;
- case 'g':
- tag.setGenre(temp_str);
- break;
- case 'c':
- tag.setComment(temp_str);
- break;
- }
- }
- break;
- case 'y':
- token[pos1+1] = 'd';
- if ( sscanf( filename.c_str(), token.c_str(), &temp_int ) )
- {
- sprintf(extract, "%d", temp_int);
- extract_ptr = extract;
- tag.setYear(temp_int);
- }
- else
- {
- memset( extract_ptr, 0, 1024 );
- }
- break;
- case 't':
- token[pos1+1] = 'd';
- if ( sscanf( filename.c_str(), token.c_str(), &temp_int ) )
- {
- std::cout << "temp_int=" << temp_int << std::endl;
- sprintf(extract, "%d", temp_int);
- extract_ptr = extract;
- tag.setTrack(temp_int);
- }
- else
- {
- memset( extract_ptr, 0, 1024 );
- }
- break;
- default:
- return -1;
- } // switch
- filename = filename.substr(filename.find(extract_ptr)+strlen(extract_ptr));
- format = format.substr(pos1+2);
- std::cout << "filename=" << filename << std::endl;
- std::cout << "format=" << format << std::endl;
- pos1 = format.find("%", 1);
- } // while
- return 0;
- }
- int filenameToTagWrapper(std::string format, std::string filename)
- {
- int success = 0;
- TagLib::FileRef f(filename.c_str());
- if ( filenameToTag(*f.tag(), filename, format) < 0 )
- {
- std::cerr << "Error: formatting string is bad!\n\n";
- printUsage();
- success = -1;
- }
- else
- {
- f.save();
- }
- return success;
- }
- void printUsage()
- {
- std::cout << "Usage: opentag format file1.mp3 file2.mp3 ...\n";
- std::cout << "where format is a string containing type specs:\n";
- std::cout << " %n - track name\n";
- std::cout << " %a - artist\n";
- std::cout << " %b - album\n";
- std::cout << " %g - genre\n";
- std::cout << " %c - comment\n";
- std::cout << " %y - year\n";
- std::cout << " %t - track number\n";
- }
- int main(int argc, char** argv)
- {
- if (argc < 3)
- {
- printUsage();
- exit(0);
- }
- TagLib::FileRef f("07-knobbers.mp3");
- filenameToTag(*f.tag(), "fatboy slim - dance bitch.mp3", "%a - %n");
- f.save();
- /* filenameToTagWrapper( "%t-%n", "07-knobbers.mp3" );*/
- return 0;
- }
