From c876d3bbefe0dc00c27ca0c12d29da5874946962 Mon Sep 17 00:00:00 2001 From: Dominik Riebeling Date: Wed, 15 Dec 2021 21:04:28 +0100 Subject: rbutil: Merge rbutil with utils folder. rbutil uses several components from the utils folder, and can be considered part of utils too. Having it in a separate folder is an arbitrary split that doesn't help anymore these days, so merge them. This also allows other utils to easily use libtools.make without the need to navigate to a different folder. Change-Id: I3fc2f4de19e3e776553efb5dea5f779dfec0dc21 --- utils/rbutilqt/base/talkfile.cpp | 300 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 utils/rbutilqt/base/talkfile.cpp (limited to 'utils/rbutilqt/base/talkfile.cpp') diff --git a/utils/rbutilqt/base/talkfile.cpp b/utils/rbutilqt/base/talkfile.cpp new file mode 100644 index 0000000000..cef53c852b --- /dev/null +++ b/utils/rbutilqt/base/talkfile.cpp @@ -0,0 +1,300 @@ +/*************************************************************************** + * __________ __ ___. + * 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, &TalkGenerator::done, this, &TalkFileCreator::done); + connect(&generator, &TalkGenerator::logItem, this, &TalkFileCreator::logItem); + connect(&generator, &TalkGenerator::logProgress, this, &TalkFileCreator::logProgress); + connect(this, &TalkFileCreator::aborted, &generator, &TalkGenerator::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::exists(dir.path() + "/_dirname.talk")) + { + 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::exists(fileInf.path() + "/" + fileInf.fileName() + ".talk")) + { + 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, nullptr); + 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(); +} + -- cgit v1.2.3