1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
/* AUDEX CDDA EXTRACTOR
* Copyright (C) 2007-2014 Marco Nelles (audex@maniatek.com)
* <http://kde.maniatek.com/audex>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "encoderwrapper.h"
EncoderWrapper::EncoderWrapper(QObject* parent, const QString& commandPattern, const QString& encoderName, const bool deleteFractionFiles) : QObject(parent) {
command_pattern = commandPattern;
encoder_name = encoderName;
delete_fraction_files = deleteFractionFiles;
connect(&proc, SIGNAL(readyReadStandardError()), this, SLOT(parseOutput()));
connect(&proc, SIGNAL(readyReadStandardOutput()), this, SLOT(parseOutput()));
connect(&proc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processFinished(int, QProcess::ExitStatus)));
connect(&proc, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
proc.setOutputChannelMode(KProcess::SeparateChannels);
proc.setReadChannel(KProcess::StandardError);
termination = FALSE;
processing = 0;
not_found_counter = 0;
}
EncoderWrapper::~EncoderWrapper() {
}
bool EncoderWrapper::encode(int n,
int cdno, int trackoffset, int nooftracks,
const QString& artist, const QString& album,
const QString& tartist, const QString& ttitle,
const QString& genre, const QString& date, const QString& suffix, CachedImage *cover,
bool fat_compatible, const QString& tmppath,
const QString& input, const QString& output) {
if (!processing) processing = 1; else return FALSE;
termination = FALSE;
if (command_pattern.isEmpty()) { emit error(i18n("Command pattern is empty.")); return FALSE; }
PatternParser patternparser;
QString command = patternparser.parseCommandPattern(command_pattern, input, output, n, cdno, trackoffset, nooftracks, artist, album, tartist, ttitle, date, genre, suffix, cover, fat_compatible, tmppath, encoder_name);
kDebug() << "executing command " << command;
proc.setShellCommand(command);
proc.start();
proc.waitForStarted();
processing_filename = output;
emit info(i18n("Encoding track %1...", n));
return TRUE;
}
void EncoderWrapper::cancel() {
if (!processing) return;
//we need to suppress normal error messages, because with a cancel the user known what he does
termination = TRUE;
proc.terminate();
if (delete_fraction_files) {
QFile file(processing_filename);
if (file.exists()) {
file.remove();
emit warning(i18n("Deleted partial file \"%1\".", processing_filename.mid(processing_filename.lastIndexOf("/")+1)));
kDebug() << "deleted partial file" << processing_filename;
}
}
emit error(i18n("User canceled encoding."));
kDebug() << "Interrupt encoding.";
}
bool EncoderWrapper::isProcessing() {
return (processing>0);
}
const QStringList& EncoderWrapper::protocol() {
return _protocol;
}
void EncoderWrapper::parseOutput() {
QByteArray rawoutput = proc.readAllStandardError();
if (rawoutput.size() == 0) rawoutput = proc.readAllStandardOutput();
bool found = FALSE;
if (rawoutput.size() > 0) {
QString output(rawoutput); QStringList list = output.trimmed().split("\n");
_protocol << list;
for (int i = 0; i < list.count(); ++i) {
if (list.at(i).contains('%')) {
QString line = list.at(i);
int startPos = line.indexOf(QRegExp("\\d+[,.]?\\d*\\%"));
if (startPos == -1) continue;
QString p = line.mid(startPos);
p = p.left(p.indexOf('%'));
bool conversionSuccessful = FALSE;
double percent = p.toDouble(&conversionSuccessful);
if ((conversionSuccessful) && (percent >= 0) && (percent <= 100)) {
emit progress((int)percent);
found = TRUE;
not_found_counter = 0;
}
}
}
}
if (!found) {
if (not_found_counter > 5) emit progress(-1); else ++not_found_counter;
}
}
void EncoderWrapper::processFinished(int exitCode, QProcess::ExitStatus exitStatus) {
processing = 0;
if (termination) { emit finished(); return; }
if ((exitStatus == QProcess::NormalExit) && (exitCode==0)) {
emit info(i18n("Encoding OK (\"%1\").", processing_filename));
} else {
emit error(i18n("An error occurred while encoding file \"%1\".", processing_filename),
i18n("Please check your profile."));
}
emit finished();
kDebug() << "encoding finished.";
}
void EncoderWrapper::processError(QProcess::ProcessError err) {
if (termination) return;
switch (err) {
case QProcess::FailedToStart :
emit error(i18n("%1 failed to start.", encoder), i18n("Either it is missing, or you may have insufficient permissions to invoke the program.")); break;
case QProcess::Crashed :
emit error(i18n("%1 crashed some time after starting successfully.", encoder), i18n("Please check your profile.")); break;
case QProcess::Timedout :
emit error(i18n("%1 timed out. This should not happen.", encoder), i18n("Please check your profile.")); break;
case QProcess::WriteError :
emit error(i18n("An error occurred when attempting to write to %1.", encoder), i18n("For example, the process may not be running, or it may have closed its input channel.")); break;
case QProcess::ReadError :
emit error(i18n("An error occurred when attempting to read from %1.", encoder), i18n("For example, the process may not be running.")); break;
case QProcess::UnknownError :
emit error(i18n("An unknown error occurred to %1. This should not happen.", encoder), i18n("Please check your profile.")); break;
}
emit finished();
kDebug() << "encoding finished.";
}
|