rockbox/rbutil/rbutilqt/base/talkfile.cpp
Dominik Riebeling 4d2ce949b3 Use cutelogger for Rockbox Utility internal trace.
Change tracing from qDebug() to use cutelogger, which is available under the
LGPL2.1. This allows to automatically add filename and line number to the log,
and also provides multiple log levels.

Change-Id: I5dbdaf902ba54ea99f07ae10a07467c52fdac910
2013-11-04 23:32:52 +01:00

302 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"
#include "Logger.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)
{
LOG_INFO() << "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;
LOG_INFO() << "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;
LOG_INFO() << "toSpeak:" << entry.toSpeak
<< "target:" << entry.target
<< "intermediates:"
<< entry.wavfilename << entry.talkfilename;
m_talkList.append(entry);
}
}
QCoreApplication::processEvents();
}
LOG_INFO() << "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
LOG_INFO() << "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();
}