|
|
|
/*! @file
|
|
|
|
|
|
|
|
@id $Id$
|
|
|
|
*/
|
|
|
|
// 1 2 3 4 5 6 7 8
|
|
|
|
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
|
|
|
|
|
|
|
#ifndef QBROWSERLIB_EXECUTOR_HXX
|
|
|
|
#define QBROWSERLIB_EXECUTOR_HXX
|
|
|
|
|
|
|
|
#include <qbrowserlib/log.hxx>
|
|
|
|
#include <qbrowserlib/settings.hxx>
|
|
|
|
#include <qbrowserlib/temporaryfile.hxx>
|
|
|
|
|
|
|
|
#include <QtCore/QDir>
|
|
|
|
#include <QtCore/QProcess>
|
|
|
|
#include <QtNetwork/QNetworkReply>
|
|
|
|
|
|
|
|
namespace qbrowserlib {
|
|
|
|
|
|
|
|
//! Execute external processes
|
|
|
|
/*! Implements a singleton pattern */
|
|
|
|
class Executor: public QObject {
|
|
|
|
|
|
|
|
Q_OBJECT;
|
|
|
|
|
|
|
|
signals:
|
|
|
|
|
|
|
|
void applicationStarted();
|
|
|
|
void applicationFinished();
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
Executor() {} // singleton
|
|
|
|
Executor(const Executor&); // singleton
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
static Executor& instance() {
|
|
|
|
static Executor _instance;
|
|
|
|
return _instance;
|
|
|
|
}
|
|
|
|
|
|
|
|
~Executor() {
|
|
|
|
TRC;
|
|
|
|
for (DownloadProcesses::iterator it(_downloadProcesses.begin());
|
|
|
|
it!=_downloadProcesses.end(); ++it) {
|
|
|
|
LOG<<"cleanup:"<<it->second->fileName();
|
|
|
|
it->second->setAutoRemove(qbrowserlib::Settings::instance()
|
|
|
|
.flag("CloseApps"));
|
|
|
|
delete it->second;
|
|
|
|
it->second = 0;
|
|
|
|
if (qbrowserlib::Settings::instance().flag("CloseApps")) {
|
|
|
|
LOG<<"terminate process";
|
|
|
|
it->first->terminate();
|
|
|
|
delete it->first;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Q_SLOTS:
|
|
|
|
|
|
|
|
void run(QNetworkReply* reply, QString filename, QString command) {
|
|
|
|
TRC; LOG<<filename<<command;
|
|
|
|
_reply = reply;
|
|
|
|
_filename = filename;
|
|
|
|
_command = command;
|
|
|
|
if (_reply->isFinished()) {
|
|
|
|
LOG<<"run immediate";
|
|
|
|
downloadFinished();
|
|
|
|
} else {
|
|
|
|
LOG<<"run later";
|
|
|
|
assert(connect(reply, SIGNAL(finished()), SLOT(downloadFinished())));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private Q_SLOTS:
|
|
|
|
|
|
|
|
void downloadFinished() {
|
|
|
|
TRC;
|
|
|
|
TemporaryFile *file(new TemporaryFile
|
|
|
|
(QDir::tempPath()+QDir::separator()
|
|
|
|
+QFileInfo(_filename).fileName()));
|
|
|
|
file->open();
|
|
|
|
_reply->seek(0);
|
|
|
|
file->write(_reply->readAll());
|
|
|
|
file->close();
|
|
|
|
LOG<<"Stored as:"<<file->fileName();
|
|
|
|
QProcess* process(new QProcess);
|
|
|
|
_downloadProcesses[process] = file;
|
|
|
|
assert(connect(process, SIGNAL(finished(int, QProcess::ExitStatus)),
|
|
|
|
SLOT(processFinished())));
|
|
|
|
QStringList args(_command.split(" ")
|
|
|
|
.replaceInStrings("%1", file->fileName()));
|
|
|
|
QString prg(args.takeFirst());
|
|
|
|
LOG<<"Running:"<<prg<<args.join(" ");
|
|
|
|
process->start(prg, args);
|
|
|
|
applicationStarted();
|
|
|
|
}
|
|
|
|
|
|
|
|
void processFinished() {
|
|
|
|
TRC;
|
|
|
|
if (_downloadProcesses.find(qobject_cast<QProcess*>(sender()))
|
|
|
|
== _downloadProcesses.end()) return;
|
|
|
|
if (_downloadProcesses[qobject_cast<QProcess*>(sender())])
|
|
|
|
_downloadProcesses[qobject_cast<QProcess*>(sender())]
|
|
|
|
->setAutoRemove(qbrowserlib::Settings::instance()
|
|
|
|
.flag("CloseApps"));
|
|
|
|
delete _downloadProcesses[qobject_cast<QProcess*>(sender())];
|
|
|
|
_downloadProcesses.erase(qobject_cast<QProcess*>(sender()));
|
|
|
|
applicationFinished();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
typedef std::map<QProcess*, TemporaryFile*> DownloadProcesses;
|
|
|
|
DownloadProcesses _downloadProcesses;
|
|
|
|
QNetworkReply* _reply;
|
|
|
|
QString _filename;
|
|
|
|
QString _command;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|