rockbox/rbutil/rbutilqt/base/talkfile.cpp
Dominik Riebeling 05caadbca3 Correctly construct the path for talkfile generation.
While TalkFileCreator uses the current mountpoint for writing logging
information it does not use it for constructing the correct path to generate
talkfiles for.

Since there is not much point in generating talkfiles for files that are not on
the player (and the UI limits the paths that can get selected to folders on the
player) make TalkFileCreator use the mountpoint for creating correct paths.
Fixes FS#12748.

Change-Id: Id682a3738649e4167556255599553edc6e2acd48
2012-09-05 20:21:59 +02:00

301 lines
10 KiB
C++

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2007 by Dominik Wenger
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "talkfile.h"
#include "rbsettings.h"
TalkFileCreator::TalkFileCreator(QObject* parent): QObject(parent)
{
}
//! \brief Creates Talkfiles.
//!
//! \param logger A pointer to a Loggerobject
bool TalkFileCreator::createTalkFiles()
{
m_abort = false;
QString errStr;
emit logItem(tr("Starting Talk file generation for folder %1")
.arg(m_dir), LOGINFO);
emit logProgress(0,0);
QCoreApplication::processEvents();
// read in Maps of paths - file/dirnames
emit logItem(tr("Reading Filelist..."),LOGINFO);
if(createTalkList(m_mountpoint + "/" + m_dir) == false)
{
emit logItem(tr("Talk file creation aborted"),LOGERROR);
doAbort();
return false;
}
QCoreApplication::processEvents();
// generate entries
{
TalkGenerator generator(this);
// no string corrections yet: do not set language for TalkGenerator.
connect(&generator,SIGNAL(done(bool)),this,SIGNAL(done(bool)));
connect(&generator,SIGNAL(logItem(QString,int)),this,SIGNAL(logItem(QString,int)));
connect(&generator,SIGNAL(logProgress(int,int)),this,SIGNAL(logProgress(int,int)));
connect(this,SIGNAL(aborted()),&generator,SLOT(abort()));
if(generator.process(&m_talkList) == TalkGenerator::eERROR)
{
doAbort();
return false;
}
}
// Copying talk files
emit logItem(tr("Copying Talkfiles..."),LOGINFO);
if(copyTalkFiles(&errStr) == false)
{
emit logItem(errStr,LOGERROR);
doAbort();
return false;
}
// Deleting left overs
if( !cleanup())
return false;
emit logItem(tr("Finished creating Talk files"),LOGOK);
emit logProgress(1,1);
emit done(false);
return true;
}
//! \brief Strips everything after and including the last dot in a string. If there is no dot, nothing is changed
//!
//! \param filename The filename from which to strip the Extension
//! \returns the modified string
QString TalkFileCreator::stripExtension(QString filename)
{
// only strip extension if there is a dot in the filename and there are chars before the dot
if(filename.lastIndexOf(".") != -1 && filename.left(filename.lastIndexOf(".")) != "")
return filename.left(filename.lastIndexOf("."));
else
return filename;
}
//! \brief Does needed Tasks when we need to abort. Cleans up Files. Stops the Logger, Stops TTS and Encoder
//!
void TalkFileCreator::doAbort()
{
cleanup();
emit logProgress(0,1);
emit done(true);
}
//! \brief creates a list of what to generate
//!
//! \param startDir The directory from which to start scanning
bool TalkFileCreator::createTalkList(QDir startDir)
{
qDebug() << "[TalkGenerator] generating list of files" << startDir;
m_talkList.clear();
// create Iterator
QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags;
if(m_recursive)
flags = QDirIterator::Subdirectories;
QDirIterator it(startDir,flags);
//create temp directory
QDir tempDir(QDir::tempPath()+ "/talkfiles/");
if(!tempDir.exists())
tempDir.mkpath(QDir::tempPath()+ "/talkfiles/");
// read in Maps of paths - file/dirnames
while (it.hasNext())
{
it.next();
if(m_abort)
{
return false;
}
QFileInfo fileInf = it.fileInfo();
// its a dir
if(fileInf.isDir())
{
QDir dir = fileInf.dir();
// insert into List
if(!dir.dirName().isEmpty() && m_talkFolders)
{
// check if we should ignore it
if(m_generateOnlyNew && QFileInfo(dir.path() + "/_dirname.talk").exists())
{
continue;
}
//generate entry
TalkGenerator::TalkEntry entry;
entry.toSpeak = dir.dirName();
entry.wavfilename = QDir::tempPath() + "/talkfiles/"
+ QCryptographicHash::hash(entry.toSpeak.toUtf8(),
QCryptographicHash::Md5).toHex() + ".wav";
entry.talkfilename = QDir::tempPath() + "/talkfiles/"
+ QCryptographicHash::hash(entry.toSpeak.toUtf8(),
QCryptographicHash::Md5).toHex() + ".talk";
entry.target = dir.path() + "/_dirname.talk";
entry.voiced = false;
entry.encoded = false;
qDebug() << "[TalkFileCreator] toSpeak:" << entry.toSpeak
<< "target:" << entry.target
<< "intermediates:" << entry.wavfilename << entry.talkfilename;
m_talkList.append(entry);
}
}
else // its a File
{
// insert into List
if( !fileInf.fileName().isEmpty() && !fileInf.fileName().endsWith(".talk") && m_talkFiles)
{
//test if we should ignore this file
bool match = false;
for(int i=0; i < m_ignoreFiles.size();i++)
{
QRegExp rx(m_ignoreFiles[i].trimmed());
rx.setPatternSyntax(QRegExp::Wildcard);
if(rx.exactMatch(fileInf.fileName()))
match = true;
}
if(match)
continue;
// check if we should ignore it
if(m_generateOnlyNew && QFileInfo(fileInf.path() + "/" + fileInf.fileName() + ".talk").exists())
{
continue;
}
//generate entry
TalkGenerator::TalkEntry entry;
if(m_stripExtensions)
entry.toSpeak = stripExtension(fileInf.fileName());
else
entry.toSpeak = fileInf.fileName();
entry.wavfilename = QDir::tempPath() + "/talkfiles/"
+ QCryptographicHash::hash(entry.toSpeak.toUtf8(),
QCryptographicHash::Md5).toHex() + ".wav";
entry.talkfilename = QDir::tempPath() + "/talkfiles/"
+ QCryptographicHash::hash(entry.toSpeak.toUtf8(),
QCryptographicHash::Md5).toHex() + ".talk";
entry.target = fileInf.path() + "/" + fileInf.fileName() + ".talk";
entry.voiced = false;
entry.encoded = false;
qDebug() << "[TalkFileCreator] toSpeak:" << entry.toSpeak
<< "target:" << entry.target
<< "intermediates:" <<
entry.wavfilename << entry.talkfilename;
m_talkList.append(entry);
}
}
QCoreApplication::processEvents();
}
qDebug() << "[TalkFileCreator] list created, entries:" << m_talkList.size();
return true;
}
//! \brief copys Talkfiles from the temp dir to the target. Progress and installlog is handled inside
//!
//! \param errString Pointer to a QString where the error cause is written.
//! \returns true on success, false on error or user abort
bool TalkFileCreator::copyTalkFiles(QString* errString)
{
int progressMax = m_talkList.size();
int m_progress = 0;
emit logProgress(m_progress,progressMax);
QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
installlog.beginGroup("talkfiles");
for(int i=0; i < m_talkList.size(); i++)
{
if(m_abort)
{
*errString = tr("File copy aborted");
return false;
}
// skip not encoded files
if(m_talkList[i].encoded == false)
{
emit logProgress(++m_progress,progressMax);
continue; // this file was skipped in one of the previous steps
}
// remove target if it exists, and if we should overwrite it
if(QFile::exists(m_talkList[i].target))
QFile::remove(m_talkList[i].target);
// copying
qDebug() << "[TalkFileCreator] copying" << m_talkList[i].talkfilename
<< "to" << m_talkList[i].target;
if(!QFile::copy(m_talkList[i].talkfilename,m_talkList[i].target))
{
*errString = tr("Copying of %1 to %2 failed").arg(m_talkList[i].talkfilename).arg(m_talkList[i].target);
return false;
}
// add to installlog
QString now = QDate::currentDate().toString("yyyyMMdd");
installlog.setValue(m_talkList[i].target.remove(0,m_mountpoint.length()),now);
emit logProgress(++m_progress,progressMax);
QCoreApplication::processEvents();
}
installlog.endGroup();
installlog.sync();
return true;
}
//! \brief Cleans up Files potentially left in the temp dir
//!
bool TalkFileCreator::cleanup()
{
emit logItem(tr("Cleaning up..."),LOGINFO);
for(int i=0; i < m_talkList.size(); i++)
{
if(QFile::exists(m_talkList[i].wavfilename))
QFile::remove(m_talkList[i].wavfilename);
if(QFile::exists(m_talkList[i].talkfilename))
QFile::remove(m_talkList[i].talkfilename);
QCoreApplication::processEvents();
}
emit logItem(tr("Finished"),LOGINFO);
return true;
}
//! \brief slot, which is connected to the abort of the Logger. Sets a flag, so Creating Talkfiles ends at the next possible position
//!
void TalkFileCreator::abort()
{
m_abort = true;
emit aborted();
}