Additional work on batch processing
This commit is contained in:
+6
-6
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
+116
-21
@@ -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 ¶ms, 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();
|
||||||
|
if(async)
|
||||||
|
{
|
||||||
_semaphore.acquire();
|
_semaphore.acquire();
|
||||||
_pool->start(new ConvertRunable(file->absoluteFilePath(), info.absolutePath() + "/" + info.completeBaseName() + "." + format.toLower(), format, params, &_semaphore));
|
_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 ¶ms)
|
||||||
{
|
{
|
||||||
_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 ¶ms)
|
||||||
|
{
|
||||||
|
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
@@ -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 ¶ms, 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 ¶ms);
|
||||||
|
Q_INVOKABLE File* convertAsync(const QString &outpath, const QString &format, const QVariantMap ¶ms);
|
||||||
Q_INVOKABLE QJSValue stats();
|
Q_INVOKABLE QJSValue stats();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user