File: encoderwrapper.cpp

package info (click to toggle)
audex 0.78-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 3,844 kB
  • ctags: 1,461
  • sloc: cpp: 10,604; makefile: 7; sh: 3
file content (167 lines) | stat: -rw-r--r-- 6,157 bytes parent folder | download | duplicates (2)
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.";
}