diff --git a/src/playlistrenamer.cpp b/src/playlistrenamer.cpp new file mode 100644 index 0000000..eaa18bc --- /dev/null +++ b/src/playlistrenamer.cpp @@ -0,0 +1,143 @@ +#include +#include "playlistrenamer.h" +#include "binaryfile.h" +#include "replace.h" +#include "wrapregex.h" +#include + +bool PlayListRenamer::run ( + const std::string& folder ) +{ + std::string m3uFile, m3uBuffer; + m3uFile = folder + "playlist.m3u"; + if ( !readFile ( m3uFile, m3uBuffer ) ) + return false; + + std::vector lines; + if ( !splitBuffer ( m3uBuffer, lines ) ) + return false; + + std::string title, from, to; + size_t lineCount = lines.size(); + int trackNo = 0; + for ( size_t i = 0; i < lineCount; i++ ) + { + if ( lines[i][0] == '#' ) + { + if ( !lines[i].find ( "EXTINF" ) ) + continue; + + //isolate m3u trackname + std::string pattern0 = ".*?,"; + WrapRegex re0 ( pattern0, true ); + int replacements; + title = re0.replaceGlobal ( lines[i], &replacements ); + + bool abbrev = false; + if ( title.size() > 22 ) + { + title.erase ( 18 ); + abbrev = true; + } + + // no trailing whitespace + std::string pattern1 = "\\s+$"; + WrapRegex re1 ( pattern1, false ); + title = re1.replaceGlobal ( title, &replacements ); + + // no contiguous whitespace + std::string pattern2 = "\\s\\s+"; + std::string replace2 = " "; + WrapRegex re2 ( pattern2, false, replace2 ); + title = re2.replaceGlobal ( title, &replacements ); + + // alphanumeric only + std::string pattern3 = "[;\\.\\[\\],!^&*()]"; + WrapRegex re3 ( pattern3, false ); + title = re3.replaceGlobal ( title, &replacements ); + + if ( abbrev ) + title.append ( "... " ); + + title += ".mp3"; + } + else + { + from = lines[i]; + to = title; + + renameFile ( from, to, folder ); + editFiles ( from, to, folder ); + + title.clear(); + } + } +} + +bool PlayListRenamer::readFile ( const std::string& path, std::string& buffer ) +{ + buffer.clear(); + try { + BinaryFile bf ( path.c_str() ); + buffer.append ( bf.getData(), bf.getDataLen() ); + } + catch ( ... ) + { + return false; + } + return true; +} + +bool PlayListRenamer::splitBuffer ( const std::string& buffer, std::vector lineVector ) +{ + std::string line; + lineVector.clear(); + size_t bufferSize = buffer.size(); + + for ( size_t i = 0; i < bufferSize; i++ ) + { + if ( buffer[i] == '\n' ) + { + if ( !line.empty() ) + { + lineVector.push_back ( line ); + line.clear(); + } + } + else if ( buffer[i] == '\r' ) + { + ; + } + else + line.append ( buffer[i], 1 ); + } + if ( !line.empty() ) + lineVector.push_back ( line ); + + if ( lineVector.empty() ) + return false; + + return true; +} + +std::string PlayListRenamer::numToString ( int i) +{ + std::stringstream sstr; + sstr << i; + + return sstr.str(); +} + +void PlayListRenamer::renameFile ( const std::string& from, const std::string& to, const std::string& folder ) +{ + wxString wideFrom, wideTo, wideFolder; + wideFolder = wxString ( folder.c_str(), wxConvUTF8, folder.size() ); + wideFrom = wxString ( from.c_str(), wxConvUTF8, from.size() ); + wideTo = wxString ( to.c_str(), wxConvUTF8, to.size() ); + wxRenameFile ( wideFolder + wideFrom, wideFolder + wideTo ); +} + +void PlayListRenamer::editFiles ( const std::string& from, const std::string& to, const std::string& folder ) +{ + //tbd +} diff --git a/src/xmlcopyimg.cpp b/src/xmlcopyimg.cpp new file mode 100644 index 0000000..8895bb1 --- /dev/null +++ b/src/xmlcopyimg.cpp @@ -0,0 +1,203 @@ +#include +#include +#include +#include +#include +#include +#include +#include "xmlcopyimg.h" +#include "xmlcopyeditorcopy.h" + +XmlCopyImg::XmlCopyImg ( + const wxString& blankImage, + const wxString& imagesDir, + const wxString& mediaDir, + const wxString& path, + bool parseDeclaration, + bool expandInternalEntities, + size_t size ) : + d ( new ImgData() ) +{ + wxCopyFile ( + blankImage, + imagesDir + wxFileName::GetPathSeparator() + _T("blank.jpg"), + true ); + + d->buffer.reserve ( size ); + d->blankImage = blankImage; + d->imagesDir = imagesDir; + d->mediaDir = mediaDir; + + // use only dir component of path + wxString volumeComponent, pathComponent; + wxFileName::SplitPath ( path, &volumeComponent, &pathComponent, NULL, NULL ); + + d->path = volumeComponent + _T(":") + pathComponent; + + XML_SetUserData ( p, d.get() ); + + // parse declaration? + if ( parseDeclaration ) + XML_SetXmlDeclHandler ( p, xmldeclhandler ); + + // internal entities + if ( expandInternalEntities ) + XML_SetDefaultHandlerExpand ( p, defaulthandler ); + else + XML_SetDefaultHandler ( p, defaulthandler ); + + XML_SetElementHandler ( p, start, end ); +} + +XmlCopyImg::~XmlCopyImg() +{} + +void XMLCALL XmlCopyImg::xmldeclhandler ( + void *data, + const XML_Char *version, + const XML_Char *encoding, + int standalone ) +{ + ImgData *d; + d = ( ImgData * ) data; + + d->encoding = ( encoding ) ? encoding : "UTF-8"; + + d->buffer.append ( "buffer.append ( version ); + d->buffer.append ( "\" encoding=\"" ); + d->buffer.append ( d->encoding ); + d->buffer.append ( "\"" ); + + if ( standalone != -1 ) + { + d->buffer.append ( " standalone=\"" ); + d->buffer.append ( ( standalone == 1 ) ? "yes" : "no" ); + d->buffer.append ( "\"" ); + } + d->buffer.append ( "?>" ); +} + +void XMLCALL XmlCopyImg::defaulthandler ( + void *data, + const XML_Char *s, + int len ) +{ + ImgData *d; + d = ( ImgData * ) data; + d->buffer.append ( s, len ); +} + +void XMLCALL XmlCopyImg::start ( void *data, + const XML_Char *el, + const XML_Char **attr ) +{ + ImgData *pd; + pd = ( ImgData * ) data; + + std::string tag, value; + tag += "<"; + tag += el; + + wxString wideFile, wideDestination; + for ( ; *attr; attr += 2 ) + { + value = ( const char * ) *(attr + 1); + if ( !strcmp ( el, "img" ) && !strcmp (*attr, "src") ) + { + wideFile = wxString ( value.c_str(), wxConvUTF8, value.size() ); + wxFileName fn ( wideFile ); + if ( fn.IsRelative() ) + { + fn.MakeAbsolute ( pd->path ); + wideFile = fn.GetFullPath(); + } + + if ( !wxFileName::FileExists ( wideFile ) ) + { + wideDestination = pd->blankImage; + value = "images/blank.jpg"; + } + else + { + value = "images/"; + value += fn.GetFullName().mb_str( wxConvUTF8 ); + wideDestination = pd->imagesDir + + wxFileName::GetPathSeparator() + + fn.GetFullName(); + wxCopyFile ( wideFile, wideDestination, true ); + } + + if ( + wideDestination.Contains ( _T(".eps" ) ) || + wideDestination.Contains ( _T(".tif") ) || + wideDestination.Contains ( _T(".bmp") ) ) + { + wxString cmd; + cmd += IMAGEMAGICK_CONVERT_PATH; + cmd += _T(" \""); + cmd += wideFile; + cmd += _T("\" \""); + cmd += wideDestination; + cmd += _T(".png\""); + + if ( wxExecute ( cmd, wxEXEC_SYNC ) ) + { + wxString error; + error.Printf ( _T("Please ensure that ImageMagick is installed on your system and that the conversion tool is located at:\n\n%s\n\nYou can download ImageMagick from:\n\n%s\n\nIf your document contains encapsulated PostScript (EPS) graphics, you need to install GhostScript as well.\n\nYou can download GhostScript from:\n\n%s"), + IMAGEMAGICK_CONVERT_PATH, + IMAGEMAGICK_INSTALL_URL, + GHOSTSCRIPT_INSTALL_URL ); + wxMessageBox ( error, _T("ImageMagick conversion failed") ); + } + value += ".png"; + } + wideDestination.clear(); + } // img + src + else if ( !strcmp ( el, "a" ) && + !strcmp (*attr, "href") && + strstr ( value.c_str(), ".mp3" ) || strstr ( value.c_str(), ".pdf" ) ) + { + wideFile = wxString ( value.c_str(), wxConvUTF8, value.size() ); + wxFileName fn ( wideFile ); + if ( fn.IsRelative() ) + { + fn.MakeAbsolute ( pd->path ); + wideFile = fn.GetFullPath(); + } + if ( !wxFileName::FileExists ( wideFile ) ) + { + value = "images/blank.jpg"; + } + else + { + value = "media/"; + value += fn.GetFullName().mb_str( wxConvUTF8 ); + wideDestination = pd->mediaDir + + wxFileName::GetPathSeparator() + + fn.GetFullName(); + wxCopyFile ( wideFile, wideDestination, true ); + } + } // a + href + + tag += " "; + tag += *attr; + tag += "=\""; + tag += value.c_str(); + tag += "\""; + } + + tag += ">"; + + pd->buffer += tag; +} + +void XMLCALL XmlCopyImg::end ( void *data, const XML_Char *el ) +{ + ImgData *pd; + pd = ( ImgData * ) data; + + pd->buffer += "buffer += el; + pd->buffer += ">"; +}