diff options
Diffstat (limited to 'utils/rbutilqt/base/talkfile.cpp')
-rw-r--r-- | utils/rbutilqt/base/talkfile.cpp | 300 |
1 files changed, 300 insertions, 0 deletions
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 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * Copyright (C) 2007 by Dominik Wenger | ||
10 | * | ||
11 | * All files in this archive are subject to the GNU General Public License. | ||
12 | * See the file COPYING in the source tree root for full license agreement. | ||
13 | * | ||
14 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
15 | * KIND, either express or implied. | ||
16 | * | ||
17 | ****************************************************************************/ | ||
18 | |||
19 | #include "talkfile.h" | ||
20 | #include "rbsettings.h" | ||
21 | #include "Logger.h" | ||
22 | |||
23 | TalkFileCreator::TalkFileCreator(QObject* parent): QObject(parent) | ||
24 | { | ||
25 | |||
26 | } | ||
27 | |||
28 | //! \brief Creates Talkfiles. | ||
29 | //! | ||
30 | //! \param logger A pointer to a Loggerobject | ||
31 | bool TalkFileCreator::createTalkFiles() | ||
32 | { | ||
33 | m_abort = false; | ||
34 | QString errStr; | ||
35 | |||
36 | emit logItem(tr("Starting Talk file generation for folder %1") | ||
37 | .arg(m_dir), LOGINFO); | ||
38 | emit logProgress(0,0); | ||
39 | QCoreApplication::processEvents(); | ||
40 | |||
41 | // read in Maps of paths - file/dirnames | ||
42 | emit logItem(tr("Reading Filelist..."),LOGINFO); | ||
43 | if(createTalkList(m_mountpoint + "/" + m_dir) == false) | ||
44 | { | ||
45 | emit logItem(tr("Talk file creation aborted"),LOGERROR); | ||
46 | doAbort(); | ||
47 | return false; | ||
48 | } | ||
49 | QCoreApplication::processEvents(); | ||
50 | |||
51 | // generate entries | ||
52 | TalkGenerator generator(this); | ||
53 | // no string corrections yet: do not set language for TalkGenerator. | ||
54 | connect(&generator, &TalkGenerator::done, this, &TalkFileCreator::done); | ||
55 | connect(&generator, &TalkGenerator::logItem, this, &TalkFileCreator::logItem); | ||
56 | connect(&generator, &TalkGenerator::logProgress, this, &TalkFileCreator::logProgress); | ||
57 | connect(this, &TalkFileCreator::aborted, &generator, &TalkGenerator::abort); | ||
58 | |||
59 | if(generator.process(&m_talkList) == TalkGenerator::eERROR) | ||
60 | { | ||
61 | doAbort(); | ||
62 | return false; | ||
63 | } | ||
64 | |||
65 | // Copying talk files | ||
66 | emit logItem(tr("Copying Talkfiles..."),LOGINFO); | ||
67 | if(copyTalkFiles(&errStr) == false) | ||
68 | { | ||
69 | emit logItem(errStr,LOGERROR); | ||
70 | doAbort(); | ||
71 | return false; | ||
72 | } | ||
73 | |||
74 | // Deleting left overs | ||
75 | if( !cleanup()) | ||
76 | return false; | ||
77 | |||
78 | emit logItem(tr("Finished creating Talk files"),LOGOK); | ||
79 | emit logProgress(1,1); | ||
80 | emit done(false); | ||
81 | |||
82 | return true; | ||
83 | } | ||
84 | |||
85 | //! \brief Strips everything after and including the last dot in a string. If there is no dot, nothing is changed | ||
86 | //! | ||
87 | //! \param filename The filename from which to strip the Extension | ||
88 | //! \returns the modified string | ||
89 | QString TalkFileCreator::stripExtension(QString filename) | ||
90 | { | ||
91 | // only strip extension if there is a dot in the filename and there are chars before the dot | ||
92 | if(filename.lastIndexOf(".") != -1 && filename.left(filename.lastIndexOf(".")) != "") | ||
93 | return filename.left(filename.lastIndexOf(".")); | ||
94 | else | ||
95 | return filename; | ||
96 | } | ||
97 | |||
98 | //! \brief Does needed Tasks when we need to abort. Cleans up Files. Stops the Logger, Stops TTS and Encoder | ||
99 | //! | ||
100 | void TalkFileCreator::doAbort() | ||
101 | { | ||
102 | cleanup(); | ||
103 | emit logProgress(0,1); | ||
104 | emit done(true); | ||
105 | } | ||
106 | //! \brief creates a list of what to generate | ||
107 | //! | ||
108 | //! \param startDir The directory from which to start scanning | ||
109 | bool TalkFileCreator::createTalkList(QDir startDir) | ||
110 | { | ||
111 | LOG_INFO() << "generating list of files" << startDir; | ||
112 | m_talkList.clear(); | ||
113 | |||
114 | // create Iterator | ||
115 | QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags; | ||
116 | if(m_recursive) | ||
117 | flags = QDirIterator::Subdirectories; | ||
118 | |||
119 | QDirIterator it(startDir,flags); | ||
120 | |||
121 | //create temp directory | ||
122 | QDir tempDir(QDir::tempPath()+ "/talkfiles/"); | ||
123 | if(!tempDir.exists()) | ||
124 | tempDir.mkpath(QDir::tempPath()+ "/talkfiles/"); | ||
125 | |||
126 | // read in Maps of paths - file/dirnames | ||
127 | while (it.hasNext()) | ||
128 | { | ||
129 | it.next(); | ||
130 | if(m_abort) | ||
131 | { | ||
132 | return false; | ||
133 | } | ||
134 | |||
135 | QFileInfo fileInf = it.fileInfo(); | ||
136 | |||
137 | // its a dir | ||
138 | if(fileInf.isDir()) | ||
139 | { | ||
140 | QDir dir = fileInf.dir(); | ||
141 | |||
142 | // insert into List | ||
143 | if(!dir.dirName().isEmpty() && m_talkFolders) | ||
144 | { | ||
145 | // check if we should ignore it | ||
146 | if(m_generateOnlyNew && QFileInfo::exists(dir.path() + "/_dirname.talk")) | ||
147 | { | ||
148 | continue; | ||
149 | } | ||
150 | |||
151 | //generate entry | ||
152 | TalkGenerator::TalkEntry entry; | ||
153 | entry.toSpeak = dir.dirName(); | ||
154 | entry.wavfilename = QDir::tempPath() + "/talkfiles/" | ||
155 | + QCryptographicHash::hash(entry.toSpeak.toUtf8(), | ||
156 | QCryptographicHash::Md5).toHex() + ".wav"; | ||
157 | entry.talkfilename = QDir::tempPath() + "/talkfiles/" | ||
158 | + QCryptographicHash::hash(entry.toSpeak.toUtf8(), | ||
159 | QCryptographicHash::Md5).toHex() + ".talk"; | ||
160 | entry.target = dir.path() + "/_dirname.talk"; | ||
161 | entry.voiced = false; | ||
162 | entry.encoded = false; | ||
163 | LOG_INFO() << "toSpeak:" << entry.toSpeak | ||
164 | << "target:" << entry.target | ||
165 | << "intermediates:" << entry.wavfilename << entry.talkfilename; | ||
166 | m_talkList.append(entry); | ||
167 | } | ||
168 | } | ||
169 | else // its a File | ||
170 | { | ||
171 | // insert into List | ||
172 | if( !fileInf.fileName().isEmpty() && !fileInf.fileName().endsWith(".talk") && m_talkFiles) | ||
173 | { | ||
174 | //test if we should ignore this file | ||
175 | bool match = false; | ||
176 | for(int i=0; i < m_ignoreFiles.size();i++) | ||
177 | { | ||
178 | QRegExp rx(m_ignoreFiles[i].trimmed()); | ||
179 | rx.setPatternSyntax(QRegExp::Wildcard); | ||
180 | if(rx.exactMatch(fileInf.fileName())) | ||
181 | match = true; | ||
182 | } | ||
183 | if(match) | ||
184 | continue; | ||
185 | |||
186 | // check if we should ignore it | ||
187 | if(m_generateOnlyNew && QFileInfo::exists(fileInf.path() + "/" + fileInf.fileName() + ".talk")) | ||
188 | { | ||
189 | continue; | ||
190 | } | ||
191 | |||
192 | //generate entry | ||
193 | TalkGenerator::TalkEntry entry; | ||
194 | if(m_stripExtensions) | ||
195 | entry.toSpeak = stripExtension(fileInf.fileName()); | ||
196 | else | ||
197 | entry.toSpeak = fileInf.fileName(); | ||
198 | entry.wavfilename = QDir::tempPath() + "/talkfiles/" | ||
199 | + QCryptographicHash::hash(entry.toSpeak.toUtf8(), | ||
200 | QCryptographicHash::Md5).toHex() + ".wav"; | ||
201 | entry.talkfilename = QDir::tempPath() + "/talkfiles/" | ||
202 | + QCryptographicHash::hash(entry.toSpeak.toUtf8(), | ||
203 | QCryptographicHash::Md5).toHex() + ".talk"; | ||
204 | entry.target = fileInf.path() + "/" + fileInf.fileName() + ".talk"; | ||
205 | entry.voiced = false; | ||
206 | entry.encoded = false; | ||
207 | LOG_INFO() << "toSpeak:" << entry.toSpeak | ||
208 | << "target:" << entry.target | ||
209 | << "intermediates:" | ||
210 | << entry.wavfilename << entry.talkfilename; | ||
211 | m_talkList.append(entry); | ||
212 | } | ||
213 | } | ||
214 | QCoreApplication::processEvents(); | ||
215 | } | ||
216 | LOG_INFO() << "list created, entries:" << m_talkList.size(); | ||
217 | return true; | ||
218 | } | ||
219 | |||
220 | |||
221 | //! \brief copys Talkfiles from the temp dir to the target. Progress and installlog is handled inside | ||
222 | //! | ||
223 | //! \param errString Pointer to a QString where the error cause is written. | ||
224 | //! \returns true on success, false on error or user abort | ||
225 | bool TalkFileCreator::copyTalkFiles(QString* errString) | ||
226 | { | ||
227 | int progressMax = m_talkList.size(); | ||
228 | int m_progress = 0; | ||
229 | emit logProgress(m_progress,progressMax); | ||
230 | |||
231 | QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, nullptr); | ||
232 | installlog.beginGroup("talkfiles"); | ||
233 | |||
234 | for(int i=0; i < m_talkList.size(); i++) | ||
235 | { | ||
236 | if(m_abort) | ||
237 | { | ||
238 | *errString = tr("File copy aborted"); | ||
239 | return false; | ||
240 | } | ||
241 | |||
242 | // skip not encoded files | ||
243 | if(m_talkList[i].encoded == false) | ||
244 | { | ||
245 | emit logProgress(++m_progress,progressMax); | ||
246 | continue; // this file was skipped in one of the previous steps | ||
247 | } | ||
248 | // remove target if it exists, and if we should overwrite it | ||
249 | if(QFile::exists(m_talkList[i].target)) | ||
250 | QFile::remove(m_talkList[i].target); | ||
251 | |||
252 | // copying | ||
253 | LOG_INFO() << "copying" << m_talkList[i].talkfilename | ||
254 | << "to" << m_talkList[i].target; | ||
255 | if(!QFile::copy(m_talkList[i].talkfilename,m_talkList[i].target)) | ||
256 | { | ||
257 | *errString = tr("Copying of %1 to %2 failed").arg(m_talkList[i].talkfilename).arg(m_talkList[i].target); | ||
258 | return false; | ||
259 | } | ||
260 | |||
261 | // add to installlog | ||
262 | QString now = QDate::currentDate().toString("yyyyMMdd"); | ||
263 | installlog.setValue(m_talkList[i].target.remove(0,m_mountpoint.length()),now); | ||
264 | |||
265 | emit logProgress(++m_progress,progressMax); | ||
266 | QCoreApplication::processEvents(); | ||
267 | } | ||
268 | installlog.endGroup(); | ||
269 | installlog.sync(); | ||
270 | return true; | ||
271 | } | ||
272 | |||
273 | |||
274 | //! \brief Cleans up Files potentially left in the temp dir | ||
275 | //! | ||
276 | bool TalkFileCreator::cleanup() | ||
277 | { | ||
278 | emit logItem(tr("Cleaning up..."),LOGINFO); | ||
279 | |||
280 | for(int i=0; i < m_talkList.size(); i++) | ||
281 | { | ||
282 | if(QFile::exists(m_talkList[i].wavfilename)) | ||
283 | QFile::remove(m_talkList[i].wavfilename); | ||
284 | if(QFile::exists(m_talkList[i].talkfilename)) | ||
285 | QFile::remove(m_talkList[i].talkfilename); | ||
286 | |||
287 | QCoreApplication::processEvents(); | ||
288 | } | ||
289 | emit logItem(tr("Finished"),LOGINFO); | ||
290 | return true; | ||
291 | } | ||
292 | |||
293 | //! \brief slot, which is connected to the abort of the Logger. Sets a flag, so Creating Talkfiles ends at the next possible position | ||
294 | //! | ||
295 | void TalkFileCreator::abort() | ||
296 | { | ||
297 | m_abort = true; | ||
298 | emit aborted(); | ||
299 | } | ||
300 | |||