diff --git a/etc/Translation/Blank.ts b/etc/Translation/Blank.ts index 35f7bd4a..79585ce7 100644 --- a/etc/Translation/Blank.ts +++ b/etc/Translation/Blank.ts @@ -366,7 +366,7 @@ - + Failed to load the Cue Sheet file: @@ -377,156 +377,156 @@ - - - + + + Cue Sheet Error - + (System Default) - + Select ANSI Codepage for Cue Sheet file: - + OK - + Cancel - + An unknown error has occured! - + The file could not be opened for reading. Make sure you have the required rights! - + The provided file does not look like a valid Cue Sheet disc image file! - + Could not find any supported audio track in the Cue Sheet image! - + Note that LameXP can not handle "binary" Cue Sheet images. - + The selected Cue Sheet file contains inconsistent information. Take care! - + Unknown Artist - + Unknown Album - - + + Choose Output Directory - - + + LameXP - + Error: The selected output directory could not be created! - + Error: The selected output directory is not writable! - + Low Diskspace Warning - + There are less than %1 GB of free diskspace available in the selected output directory. - + It is highly recommend to free up more diskspace before proceeding with the import! - + Analyzing file(s), please wait... - + Analysis Failed - + Warning: The format of some of the input files could not be determined! - + Continue Anyway - + Abort - + Splitting file(s), please wait... - + Process was aborted by the user after %1 track(s)! - + An unexpected error has occured while splitting the Cue Sheet! - + Imported %1 track(s) from the Cue Sheet and skipped %2 track(s). - + Cue Sheet Completed @@ -583,44 +583,44 @@ CueSheetModel - + No. - + File / Track - + Index - + Duration - + File %1 - + Track %1 - - + + Unknown Artist - - + + Unknown Title diff --git a/etc/Translation/LameXP_PL.ts b/etc/Translation/LameXP_PL.ts index 38d74f22..83bcae91 100644 --- a/etc/Translation/LameXP_PL.ts +++ b/etc/Translation/LameXP_PL.ts @@ -366,7 +366,7 @@ - + Failed to load the Cue Sheet file: Ładowanie pliku Cue Sheet zakończone niepowodzeniem: @@ -377,156 +377,156 @@ - - - + + + Cue Sheet Error Błąd pliku Cue Sheet - + (System Default) - + Select ANSI Codepage for Cue Sheet file: - + OK OK - + Cancel Anuluj - + An unknown error has occured! Wystąpił nieokreśłony błąd! - + The file could not be opened for reading. Make sure you have the required rights! Plik nie mógł zostać odczytany. Upewnij się że masz prawo odczytu! - + The provided file does not look like a valid Cue Sheet disc image file! Dany plik nie wydaje się prawidłowym plikiem obrazu Cue Sheet! - + Could not find any supported audio track in the Cue Sheet image! Nie znaleziono wspieranego formatu dźwięku w żadnej ze ścieżek obrazu Cue Sheet! - + Note that LameXP can not handle "binary" Cue Sheet images. LameXP nie radzi sobie z formatem "binarnym" obrazu Cue Sheet. - + The selected Cue Sheet file contains inconsistent information. Take care! Wybrany plik Cue Sheet zawiera niespójne informacje. Prosze zachować ostrożność! - + Unknown Artist Nieznany Artysta - + Unknown Album Nieznany Album - - + + Choose Output Directory Wybierz folder wyjściowy - - + + LameXP LameXP - + Error: The selected output directory could not be created! Błąd: Wybrana lokalizacja wyjściowa nie może zostać utworzona! - + Error: The selected output directory is not writable! Błąd: Nie można zapisać w wybranej lokalizacji wyjściowej! - + Low Diskspace Warning Ostrzeżenie o małej ilości miejsca na dysku - + There are less than %1 GB of free diskspace available in the selected output directory. Jest mniej niż %1 GB wolnego miejsca w wybranej lokalizacji wyjściowej. - + It is highly recommend to free up more diskspace before proceeding with the import! Jest wysoce zalecane zwolnić miejsce na dysku zanim zaczniesz importować! - + Analyzing file(s), please wait... Analizowanie pliku/ów, prosze czekać... - + Analysis Failed Analiza zakończona niepowodzeniem - + Warning: The format of some of the input files could not be determined! Ostrzeżenie: Nie można rozpoznać formatu kilku plików wejściowych! - + Continue Anyway Kontynuuj pomimo to - + Abort Przerwij - + Splitting file(s), please wait... Dzielenie pliku/ów, prosze czekać... - + Process was aborted by the user after %1 track(s)! Proces został przerwany przez użytkownika po imporcie %1 ścieżek! - + An unexpected error has occured while splitting the Cue Sheet! Wystąpił nieoczekiwany błąd podczas podziału pliku Cue Sheet! - + Imported %1 track(s) from the Cue Sheet and skipped %2 track(s). Zaimportowano %1 ścieżek i opuszczono %2 ścieżek z pliku Cue Sheet. - + Cue Sheet Completed Stworzono plik Cue Sheet @@ -583,44 +583,44 @@ CueSheetModel - + No. Numer. - + File / Track Plik/ŚcieżKa - + Index Indeks - + Duration Czas trwania - + File %1 Plik %1 - + Track %1 Ścieżka %1 - - + + Unknown Artist Nieznany Artysta - - + + Unknown Title Nieznany Tytuł diff --git a/src/Config.h b/src/Config.h index 56908381..35dd8892 100644 --- a/src/Config.h +++ b/src/Config.h @@ -29,8 +29,8 @@ #define VER_LAMEXP_MINOR_HI 0 #define VER_LAMEXP_MINOR_LO 4 #define VER_LAMEXP_TYPE Alpha -#define VER_LAMEXP_PATCH 8 -#define VER_LAMEXP_BUILD 807 +#define VER_LAMEXP_PATCH 9 +#define VER_LAMEXP_BUILD 810 /////////////////////////////////////////////////////////////////////////////// // Tool versions (minimum expected versions!) diff --git a/src/Dialog_CueImport.cpp b/src/Dialog_CueImport.cpp index 87b4ab7f..58a961e7 100644 --- a/src/Dialog_CueImport.cpp +++ b/src/Dialog_CueImport.cpp @@ -120,12 +120,20 @@ int CueImportDialog::exec(void) QFile cueFile(cueFileInfo.canonicalFilePath()); cueFile.open(QIODevice::ReadOnly); - QByteArray bomCheck = cueFile.isOpen() ? cueFile.peek(128) : QByteArray(); + QByteArray bomCheck = cueFile.isOpen() ? cueFile.peek(16) : QByteArray(); - if((!bomCheck.isEmpty()) && bomCheck.contains("\xef\xbb\xbf")) + if((!bomCheck.isEmpty()) && bomCheck.startsWith("\xef\xbb\xbf")) { codec = QTextCodec::codecForName("UTF-8"); } + else if((!bomCheck.isEmpty()) && bomCheck.startsWith("\xff\xfe")) + { + codec = QTextCodec::codecForName("UTF-16LE"); + } + else if((!bomCheck.isEmpty()) && bomCheck.startsWith("\xfe\xff")) + { + codec = QTextCodec::codecForName("UTF-16BE"); + } else { const QString systemDefault = tr("(System Default)"); diff --git a/src/Model_CueSheet.cpp b/src/Model_CueSheet.cpp index 3c001264..3b947b4c 100644 --- a/src/Model_CueSheet.cpp +++ b/src/Model_CueSheet.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -549,7 +550,7 @@ int CueSheetModel::loadCueSheet(const QString &cueFileName, QCoreApplication *ap int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplication *application, const QTextCodec *codec) { - cueFile.seek(0); + cueFile.reset(); qDebug("\n[Cue Sheet Import]"); bool bForceLatin1 = false; @@ -566,11 +567,17 @@ int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplic QByteArray testData = cueFile.peek(1048576); if((!testData.isEmpty()) && codec->toUnicode(testData.constData(), testData.size()).contains(replacementSymbol)) { - qWarning("Decoding error using local codepage. Enforcing Latin-1."); + qWarning("Decoding error using selected codepage (%s). Enforcing Latin-1.", codec->name().constData()); bForceLatin1 = true; } testData.clear(); + //Init text stream + QTextStream cueStream(&cueFile); + cueStream.setAutoDetectUnicode(false); + cueStream.setCodec(bForceLatin1 ? "latin1" : codec->name()); + cueStream.seek(0i64); + //Create regular expressions QRegExp rxFile("^FILE\\s+(\"[^\"]+\"|\\S+)\\s+(\\w+)$", Qt::CaseInsensitive); QRegExp rxTrack("^TRACK\\s+(\\d+)\\s(\\w+)$", Qt::CaseInsensitive); @@ -600,14 +607,13 @@ int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplic if(lines < 128) Sleep(10); } - QByteArray lineData = cueFile.readLine(); - if(lineData.size() <= 0) + if(cueStream.atEnd()) { qDebug("End of Cue Sheet file."); break; } - QString line = (bForceLatin1 ? QString::fromLatin1(lineData.constData(), lineData.size()) : codec->toUnicode(lineData.constData(), lineData.size())).trimmed(); + QString line = cueStream.readLine().trimmed(); /* --- FILE --- */ if(rxFile.indexIn(line) >= 0) diff --git a/src/PlaylistImporter.cpp b/src/PlaylistImporter.cpp index 3e4e768d..f7c6a2a1 100644 --- a/src/PlaylistImporter.cpp +++ b/src/PlaylistImporter.cpp @@ -86,6 +86,13 @@ bool PlaylistImporter::importPlaylist(QStringList &fileList, const QString &play return false; } + //Skip very large files (parsing could take very long) + if(data.size() >= 10485760i64) + { + qWarning("File is very big. Probably not a Playlist. Rejecting..."); + return false; + } + //Parse playlist depending on type switch(playlistType) { @@ -132,14 +139,16 @@ PlaylistImporter::playlist_t PlaylistImporter::isPlaylist(const QString &fileNam bool PlaylistImporter::parsePlaylist_m3u(QFile &data, QStringList &fileList, const QDir &baseDir, const QDir &rootDir) { - QByteArray line = data.readLine(); - const bool preferUTF8 = data.fileName().endsWith(".m3u8", Qt::CaseInsensitive); const QTextCodec *codec = QTextCodec::codecForName("System"); + const bool preferUTF8 = data.fileName().endsWith(".m3u8", Qt::CaseInsensitive); + bool foundAtLeastOneFile = false; + + data.reset(); - - while(line.size() > 0) + while(!data.atEnd()) { QString filePath[3]; + QByteArray line = data.readLine(); if(preferUTF8) { @@ -156,24 +165,61 @@ bool PlaylistImporter::parsePlaylist_m3u(QFile &data, QStringList &fileList, con for(size_t i = 0; i < 3; i++) { - if(!(filePath[i].startsWith("#") || filePath[i].contains(QChar(QChar::ReplacementCharacter)))) + if(!(filePath[i].isEmpty() || filePath[i].startsWith("#") || filePath[i].contains(QChar(QChar::ReplacementCharacter)))) { QFileInfo filename(filePath[i]); filename.setCaching(false); fixFilePath(filename, baseDir, rootDir); - if(filename.exists()) + if(filename.exists() && filename.isFile()) { + qDebug("Found: \"%s\"", filePath[i].toUtf8().constData()); if(isPlaylist(filename.canonicalFilePath()) == notPlaylist) { fileList << filename.canonicalFilePath(); } + foundAtLeastOneFile = true; break; } } } + } - line = data.readLine(); + //If we did not find any files yet, try UTF-16 now + if(!foundAtLeastOneFile) + { + const char* codecs[2] = {"UTF-16LE", "UTF-16BE"}; + + for(size_t i = 0; i < 2; i++) + { + QTextStream stream(&data); + stream.setAutoDetectUnicode(false); + stream.setCodec(codecs[i]); + stream.seek(0i64); + + while(!stream.atEnd()) + { + QString filePath = stream.readLine().trimmed(); + + if(!(filePath.isEmpty() || filePath.startsWith("#") || filePath.contains(QChar(QChar::ReplacementCharacter)))) + { + QFileInfo filename(filePath); + filename.setCaching(false); + fixFilePath(filename, baseDir, rootDir); + + if(filename.exists() && filename.isFile()) + { + if(isPlaylist(filename.canonicalFilePath()) == notPlaylist) + { + fileList << filename.canonicalFilePath(); + } + foundAtLeastOneFile = true; + } + } + } + + if(foundAtLeastOneFile) break; + } } return true; @@ -183,11 +229,14 @@ bool PlaylistImporter::parsePlaylist_pls(QFile &data, QStringList &fileList, con { QRegExp plsEntry("File(\\d+)=(.+)", Qt::CaseInsensitive); const QTextCodec *codec = QTextCodec::codecForName("System"); - QByteArray line = data.readLine(); - - while(line.size() > 0) + bool foundAtLeastOneFile = false; + + data.reset(); + + while(!data.atEnd()) { QString filePath[3]; + QByteArray line = data.readLine(); filePath[0] = QString(QDir::fromNativeSeparators(codec->toUnicode(line.constData(), line.size()).trimmed())); filePath[1] = QString(QDir::fromNativeSeparators(QString::fromLatin1(line.constData(), line.size()).trimmed())); @@ -203,19 +252,58 @@ bool PlaylistImporter::parsePlaylist_pls(QFile &data, QStringList &fileList, con filename.setCaching(false); fixFilePath(filename, baseDir, rootDir); - if(filename.exists()) + if(filename.exists() && filename.isFile()) { if(isPlaylist(filename.canonicalFilePath()) == notPlaylist) { fileList << filename.canonicalFilePath(); } + foundAtLeastOneFile = true; break; } } } } + } - line = data.readLine(); + //If we did not find any files yet, try UTF-16 now + if(!foundAtLeastOneFile) + { + const char* codecs[2] = {"UTF-16LE", "UTF-16BE"}; + + for(size_t i = 0; i < 2; i++) + { + QTextStream stream(&data); + stream.setAutoDetectUnicode(false); + stream.setCodec(codecs[i]); + stream.seek(0i64); + + while(!stream.atEnd()) + { + QString filePath = stream.readLine().trimmed(); + + if(!filePath.contains(QChar(QChar::ReplacementCharacter))) + { + if(plsEntry.indexIn(filePath) >= 0) + { + QFileInfo filename(QDir::fromNativeSeparators(plsEntry.cap(2)).trimmed()); + filename.setCaching(false); + fixFilePath(filename, baseDir, rootDir); + + if(filename.exists() && filename.isFile()) + { + if(isPlaylist(filename.canonicalFilePath()) == notPlaylist) + { + fileList << filename.canonicalFilePath(); + } + foundAtLeastOneFile = true; + } + } + } + } + + if(foundAtLeastOneFile) break; + } } return true; @@ -247,7 +335,7 @@ bool PlaylistImporter::parsePlaylist_wpl(QFile &data, QStringList &fileList, con filename.setCaching(false); fixFilePath(filename, baseDir, rootDir); - if(filename.exists()) + if(filename.exists() && filename.isFile()) { if(isPlaylist(filename.canonicalFilePath()) == notPlaylist) {