Additional work on batch processing

This commit is contained in:
2024-03-29 18:08:57 +01:00
parent c3588e1c36
commit 933fd4a2a0
3 changed files with 143 additions and 36 deletions
+6 -6
View File
@@ -17,12 +17,12 @@
#include <QMessageBox> #include <QMessageBox>
#endif #endif
QStringList scanDirectories(const QStringList &paths) QList<QPair<QString, QString>> scanDirectories(const QStringList &paths)
{ {
QStringList files; QList<QPair<QString, QString>> files;
QStringList scannedDirs; QStringList scannedDirs;
std::function<void(const QString &path)> scanDirectory = [&](const QString &path) std::function<void(const QString &root, const QString &path)> scanDirectory = [&](const QString &root, const QString &path)
{ {
QFileInfo info(path); QFileInfo info(path);
if(info.isDir() && !scannedDirs.contains(info.canonicalFilePath())) if(info.isDir() && !scannedDirs.contains(info.canonicalFilePath()))
@@ -31,16 +31,16 @@ QStringList scanDirectories(const QStringList &paths)
QDir dir(path); QDir dir(path);
QStringList entries = dir.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); QStringList entries = dir.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
for(QString &entry : entries) for(QString &entry : entries)
scanDirectory(dir.absoluteFilePath(entry)); scanDirectory(root, dir.absoluteFilePath(entry));
} }
else if(info.isFile()) else if(info.isFile())
{ {
files.append(path); files.append({path, root});
} }
}; };
for(const QString &path : paths) for(const QString &path : paths)
scanDirectory(path); scanDirectory(path, path);
return files; return files;
} }
+117 -22
View File
@@ -20,7 +20,7 @@ ScriptEngine::ScriptEngine(QObject *parent) : QObject(parent)
_semaphore.release(_pool->maxThreadCount()); _semaphore.release(_pool->maxThreadCount());
} }
void ScriptEngine::setParams(const QString &scriptPath, const QStringList &paths, const QString &outputDir) void ScriptEngine::setParams(const QString &scriptPath, const QList<QPair<QString, QString>> &paths, const QString &outputDir)
{ {
_scriptPath = scriptPath; _scriptPath = scriptPath;
_paths = paths; _paths = paths;
@@ -67,7 +67,23 @@ bool ScriptEngine::isMarked(const File *file) const
return _database->isMarked(file->absoluteFilePath()); return _database->isMarked(file->absoluteFilePath());
} }
bool ScriptEngine::convert(File *file, QString &outpath, QString format, QVariantMap params) void ScriptEngine::setMaxThread(int maxthread)
{
int newval = std::max(std::min(QThread::idealThreadCount(), maxthread), 1);
int oldval = _pool->maxThreadCount();
if(newval > oldval)
_semaphore.release(newval - oldval);
else if(newval < oldval)
_semaphore.acquire(oldval - newval);
_pool->setMaxThreadCount(newval);
}
void ScriptEngine::sync()
{
_pool->waitForDone();
}
bool ScriptEngine::convert(File *file, QString &outpath, const QString &format, const QVariantMap &params, bool async)
{ {
QString path; QString path;
QDir dir(_outputDir); QDir dir(_outputDir);
@@ -79,9 +95,17 @@ bool ScriptEngine::convert(File *file, QString &outpath, QString format, QVarian
path = dir.absoluteFilePath(outpath); path = dir.absoluteFilePath(outpath);
info.setFile(path); info.setFile(path);
//qDebug() << info.absolutePath() + "/" + info.completeBaseName() + "." + format.toLower(); outpath = info.absolutePath() + "/" + info.completeBaseName() + "." + format.toLower();
_semaphore.acquire(); if(async)
_pool->start(new ConvertRunable(file->absoluteFilePath(), info.absolutePath() + "/" + info.completeBaseName() + "." + format.toLower(), format, params, &_semaphore)); {
_semaphore.acquire();
_pool->start(new ConvertRunable(file->absoluteFilePath(), outpath, format, params, &_semaphore));
}
else
{
ConvertRunable crun(file->absoluteFilePath(), outpath, format, params, nullptr);
crun.run();
}
return true; return true;
} }
@@ -90,11 +114,16 @@ QJSValue ScriptEngine::newObject()
return _jsEngine->newObject(); return _jsEngine->newObject();
} }
QJSValue ScriptEngine::newArray(uint size)
{
return _jsEngine->newArray(size);
}
void ScriptEngine::run() void ScriptEngine::run()
{ {
QJSValue jsPaths = _jsEngine->newArray(_paths.size()); QJSValue jsPaths = _jsEngine->newArray(_paths.size());
for(qsizetype i=0; i<_paths.size(); i++) for(qsizetype i=0; i<_paths.size(); i++)
jsPaths.setProperty(i, _jsEngine->newQObject(new File(_paths[i], this))); jsPaths.setProperty(i, _jsEngine->newQObject(new File(_paths[i].first, _paths[i].second, this)));
_jsEngine->globalObject().setProperty("files", jsPaths); _jsEngine->globalObject().setProperty("files", jsPaths);
@@ -138,9 +167,10 @@ void File::loadFitsKeywords()
} }
else return; else return;
for(const FITSRecord &record : info.fitsHeader) for(auto &record : info.fitsHeader)
{ {
_fitsKeywords[record.key] = record.value.toString(); _fitsKeywords.append(record.key);
_fitsRecords.insert(record.key, record);
} }
} }
} }
@@ -165,9 +195,14 @@ bool File::mkpath(const QString &path) const
} }
} }
File::File(const QString &path, Script::ScriptEngine *engine) : File::File(const QString &path, Script::ScriptEngine *engine) : File(path, QString(), engine)
{
}
File::File(const QString &path, const QString &root, ScriptEngine *engine) :
_engine(engine), _engine(engine),
_path(path), _path(path),
_root(root),
_info(path) _info(path)
{ {
} }
@@ -187,6 +222,18 @@ QString File::absolutePath() const
return _info.absolutePath(); return _info.absolutePath();
} }
QString File::relativeFilePath() const
{
QDir dir(_root);
return dir.relativeFilePath(_info.absoluteFilePath());
}
QString File::relativePath() const
{
QDir dir(_root);
return dir.relativeFilePath(_info.absolutePath());
}
QString File::baseName() const QString File::baseName() const
{ {
return _info.baseName(); return _info.baseName();
@@ -209,53 +256,101 @@ qint64 File::size() const
QStringList File::fitsKeywords() QStringList File::fitsKeywords()
{ {
QThread::msleep(500);
loadFitsKeywords(); loadFitsKeywords();
return _fitsKeywords.keys(); return _fitsKeywords;
} }
QString File::fitsValue(const QString &key) QString File::fitsValue(const QString &key)
{ {
loadFitsKeywords(); loadFitsKeywords();
if(_fitsKeywords.contains(key)) if(_fitsRecords.contains(key))
return _fitsKeywords[key]; return _fitsRecords[key].value.toString();
else else
return QString(); return QString();
} }
QJSValue File::fitsValues(const QString &key)
{
loadFitsKeywords();
if(_fitsRecords.contains(key))
{
QList<FITSRecord> values = _fitsRecords.values(key);
QJSValue array = _engine->newArray(values.size());
for(qsizetype i=0; i<values.size(); i++)
array.setProperty(i, values[i].value.toString());
return array;
}
else
return QString();
}
QJSValue File::fitsRecords()
{
loadFitsKeywords();
QJSValue array = _engine->newArray(_fitsRecords.size());
uint i = 0;
for(auto &record : _fitsRecords)
{
QJSValue item = _engine->newObject();
item.setProperty("key", QString::fromUtf8(record.key));
item.setProperty("value", record.value.toString());
item.setProperty("comment", QString::fromUtf8(record.comment));
item.setProperty("xisf", record.xisf);
array.setProperty(i++, item);
}
return array;
}
bool File::isMarked() const bool File::isMarked() const
{ {
return _engine->isMarked(this); return _engine->isMarked(this);
} }
bool File::copy(const QString &newpath) const File* File::copy(const QString &newpath) const
{ {
if(mkpath(newpath)) if(mkpath(newpath))
{ {
if(QFile::copy(_path, _engine->outputDir() + newpath)) if(QFile::copy(_path, _engine->outputDir() + newpath))
return true; return new File(_engine->outputDir() + newpath, _engine);
_engine->logError("Failed copy to " + newpath); _engine->logError("Failed copy to " + newpath);
return false; return nullptr;
} }
return false; return nullptr;
} }
bool File::move(const QString &newpath) const bool File::move(const QString &newpath)
{ {
if(mkpath(newpath)) if(mkpath(newpath))
{ {
if(QFile::rename(_path, _engine->outputDir() + newpath)) if(QFile::rename(_path, _engine->outputDir() + newpath))
{
_path = _engine->outputDir() + newpath;
return true; return true;
}
_engine->logError("Failed move to " + newpath); _engine->logError("Failed move to " + newpath);
return false; return false;
} }
return false; return false;
} }
bool File::convertTo(const QString &format) File* File::convert(const QString &outpath, const QString &format, const QVariantMap &params)
{ {
_engine->reportError("Not implemented"); QString path = outpath;
return false; if(_engine->convert(this, path, format, params, false))
return new File(path, _engine);
else
return nullptr;
}
File* File::convertAsync(const QString &outpath, const QString &format, const QVariantMap &params)
{
QString path = outpath;
if(_engine->convert(this, path, format, params, true))
return new File(path, _engine);
else
return nullptr;
} }
QJSValue File::stats() QJSValue File::stats()
@@ -298,7 +393,7 @@ ScriptEngineThread::~ScriptEngineThread()
if(_engine)_engine->interrupt(); if(_engine)_engine->interrupt();
} }
void ScriptEngineThread::setParams(const QString &scriptPath, const QStringList &paths, const QString &outputDir) void ScriptEngineThread::setParams(const QString &scriptPath, const QList<QPair<QString, QString>> &paths, const QString &outputDir)
{ {
_engine->setParams(scriptPath, paths, outputDir); _engine->setParams(scriptPath, paths, outputDir);
} }
+20 -8
View File
@@ -8,6 +8,7 @@
#include <QThreadPool> #include <QThreadPool>
#include <QSemaphore> #include <QSemaphore>
#include "database.h" #include "database.h"
#include "imageinfo.h"
namespace Script namespace Script
{ {
@@ -23,10 +24,10 @@ class ScriptEngine : public QObject
QSemaphore _semaphore; QSemaphore _semaphore;
QString _scriptPath; QString _scriptPath;
QString _outputDir; QString _outputDir;
QStringList _paths; QList<QPair<QString, QString>> _paths;
public: public:
explicit ScriptEngine(QObject *parent = nullptr); explicit ScriptEngine(QObject *parent = nullptr);
void setParams(const QString &scriptPath, const QStringList &paths, const QString &outputDir); void setParams(const QString &scriptPath, const QList<QPair<QString, QString>> &paths, const QString &outputDir);
void reportError(const QString &message); void reportError(const QString &message);
const QString& outputDir() const; const QString& outputDir() const;
void interrupt(); void interrupt();
@@ -35,8 +36,11 @@ public:
Q_INVOKABLE void mark(File *file); Q_INVOKABLE void mark(File *file);
Q_INVOKABLE void unmark(File *file); Q_INVOKABLE void unmark(File *file);
Q_INVOKABLE bool isMarked(const File *file) const; Q_INVOKABLE bool isMarked(const File *file) const;
Q_INVOKABLE bool convert(File *file, QString &outpath, QString format, QVariantMap params); Q_INVOKABLE void setMaxThread(int maxthread);
Q_INVOKABLE void sync();
bool convert(File *file, QString &outpath, const QString &format, const QVariantMap &params, bool async);
QJSValue newObject(); QJSValue newObject();
QJSValue newArray(uint size);
public slots: public slots:
void run(); void run();
signals: signals:
@@ -52,7 +56,7 @@ class ScriptEngineThread : public QObject
public: public:
ScriptEngineThread(QObject *parent = nullptr); ScriptEngineThread(QObject *parent = nullptr);
~ScriptEngineThread(); ~ScriptEngineThread();
void setParams(const QString &scriptPath, const QStringList &paths, const QString &outputDir); void setParams(const QString &scriptPath, const QList<QPair<QString, QString>> &paths, const QString &outputDir);
void start(); void start();
void interrupt(); void interrupt();
signals: signals:
@@ -65,27 +69,35 @@ class File : public QObject
Q_OBJECT Q_OBJECT
ScriptEngine *_engine; ScriptEngine *_engine;
QString _path; QString _path;
QString _root;
QFileInfo _info; QFileInfo _info;
bool _fitsKeywordsLoaded = false; bool _fitsKeywordsLoaded = false;
QMap<QString, QString> _fitsKeywords; QStringList _fitsKeywords;
QMultiHash<QString, FITSRecord> _fitsRecords;
void loadFitsKeywords(); void loadFitsKeywords();
bool mkpath(const QString &path) const; bool mkpath(const QString &path) const;
QJSValue _stats; QJSValue _stats;
public: public:
explicit File(const QString &path, ScriptEngine *engine); explicit File(const QString &path, ScriptEngine *engine);
explicit File(const QString &path, const QString &root, ScriptEngine *engine);
Q_INVOKABLE QString fileName() const; Q_INVOKABLE QString fileName() const;
Q_INVOKABLE QString absoluteFilePath() const; Q_INVOKABLE QString absoluteFilePath() const;
Q_INVOKABLE QString absolutePath() const; Q_INVOKABLE QString absolutePath() const;
Q_INVOKABLE QString relativeFilePath() const;
Q_INVOKABLE QString relativePath() const;
Q_INVOKABLE QString baseName() const; Q_INVOKABLE QString baseName() const;
Q_INVOKABLE QString completeBaseName() const; Q_INVOKABLE QString completeBaseName() const;
Q_INVOKABLE QString suffix() const; Q_INVOKABLE QString suffix() const;
Q_INVOKABLE qint64 size() const; Q_INVOKABLE qint64 size() const;
Q_INVOKABLE QStringList fitsKeywords(); Q_INVOKABLE QStringList fitsKeywords();
Q_INVOKABLE QString fitsValue(const QString &key); Q_INVOKABLE QString fitsValue(const QString &key);
Q_INVOKABLE QJSValue fitsValues(const QString &key);
Q_INVOKABLE QJSValue fitsRecords();
Q_INVOKABLE bool isMarked() const; Q_INVOKABLE bool isMarked() const;
Q_INVOKABLE bool copy(const QString &newpath) const; Q_INVOKABLE File* copy(const QString &newpath) const;
Q_INVOKABLE bool move(const QString &newpath) const; Q_INVOKABLE bool move(const QString &newpath);
Q_INVOKABLE bool convertTo(const QString &format); Q_INVOKABLE File* convert(const QString &outpath, const QString &format, const QVariantMap &params);
Q_INVOKABLE File* convertAsync(const QString &outpath, const QString &format, const QVariantMap &params);
Q_INVOKABLE QJSValue stats(); Q_INVOKABLE QJSValue stats();
}; };