Erste Version
This commit is contained in:
commit
e5944d9b97
74 files changed
+30486
No files matched your search
+107
@@ -0,0 +1,107 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright (C) 2026 Dany Thinnes
|
||||
|
||||
#include "xdftool.h"
|
||||
|
||||
#include <QPair>
|
||||
#include <QProcess>
|
||||
#include <QProcessEnvironment>
|
||||
#include <QRegularExpression>
|
||||
#include <QVector>
|
||||
|
||||
XdfTool::XdfTool(const QString &program) : m_program(program) {}
|
||||
|
||||
XdfTool::Result XdfTool::runBatch(const QString &image, const QList<QStringList> &commands) const
|
||||
{
|
||||
Result r;
|
||||
|
||||
QStringList args;
|
||||
args << image;
|
||||
for (int i = 0; i < commands.size(); ++i) {
|
||||
if (i > 0)
|
||||
args << QStringLiteral("+");
|
||||
args << commands.at(i);
|
||||
}
|
||||
|
||||
QStringList shown;
|
||||
for (const QString &a : args)
|
||||
shown << (a.contains(' ') ? QStringLiteral("\"%1\"").arg(a) : a);
|
||||
r.commandLine = m_program + ' ' + shown.join(' ');
|
||||
|
||||
QProcess p;
|
||||
#ifdef Q_OS_WIN
|
||||
// Python-Ausgabe unter Windows auf UTF-8 zwingen (sonst Umlaute in Dateinamen kaputt)
|
||||
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||
env.insert(QStringLiteral("PYTHONUTF8"), QStringLiteral("1"));
|
||||
env.insert(QStringLiteral("PYTHONIOENCODING"), QStringLiteral("utf-8"));
|
||||
p.setProcessEnvironment(env);
|
||||
#endif
|
||||
p.start(m_program, args);
|
||||
if (!p.waitForStarted(5000)) {
|
||||
r.err = QStringLiteral("Konnte '%1' nicht starten: %2").arg(m_program, p.errorString());
|
||||
return r;
|
||||
}
|
||||
p.waitForFinished(-1);
|
||||
|
||||
r.out = QString::fromUtf8(p.readAllStandardOutput());
|
||||
r.err = QString::fromUtf8(p.readAllStandardError());
|
||||
r.ok = (p.exitStatus() == QProcess::NormalExit && p.exitCode() == 0);
|
||||
return r;
|
||||
}
|
||||
|
||||
XdfTool::Result XdfTool::list(const QString &image, QList<AdfEntry> &entries) const
|
||||
{
|
||||
Result r = runBatch(image, { { QStringLiteral("list") } });
|
||||
if (r.ok)
|
||||
entries = parseList(r.out);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Erwartet das typische Ausgabeformat von "xdftool <img> list":
|
||||
// pro Zeile ein Eintrag, Unterverzeichnisse um je 2 Leerzeichen eingerueckt,
|
||||
// danach eine Spalte mit "DIR" bzw. der Dateigroesse in Bytes.
|
||||
QList<AdfEntry> XdfTool::parseList(const QString &text)
|
||||
{
|
||||
static const QRegularExpression reWide(
|
||||
QStringLiteral(R"(^( *)(.*?)\s{2,}(DIR|\d+)(?:\s.*)?$)"));
|
||||
static const QRegularExpression reNarrow(
|
||||
QStringLiteral(R"(^( *)(.*?)\s+(DIR|\d+)(?:\s.*)?$)"));
|
||||
|
||||
QList<AdfEntry> result;
|
||||
QVector<QPair<int, QString>> stack; // (Einrueckung, Pfad) offener Verzeichnisse
|
||||
|
||||
const QStringList lines = text.split('\n');
|
||||
for (QString line : lines) {
|
||||
if (line.endsWith('\r'))
|
||||
line.chop(1);
|
||||
if (line.trimmed().isEmpty())
|
||||
continue;
|
||||
|
||||
QRegularExpressionMatch m = reWide.match(line);
|
||||
if (!m.hasMatch())
|
||||
m = reNarrow.match(line);
|
||||
if (!m.hasMatch())
|
||||
continue;
|
||||
|
||||
const int indent = m.captured(1).size();
|
||||
const QString name = m.captured(2).trimmed();
|
||||
if (name.isEmpty())
|
||||
continue;
|
||||
|
||||
while (!stack.isEmpty() && stack.last().first >= indent)
|
||||
stack.removeLast();
|
||||
|
||||
const QString parent = stack.isEmpty() ? QString() : stack.last().second;
|
||||
|
||||
AdfEntry e;
|
||||
e.name = name;
|
||||
e.path = parent.isEmpty() ? name : parent + QLatin1Char('/') + name;
|
||||
e.isDir = (m.captured(3) == QLatin1String("DIR"));
|
||||
e.size = e.isDir ? 0 : m.captured(3).toLongLong();
|
||||
result << e;
|
||||
|
||||
if (e.isDir)
|
||||
stack.append({ indent, e.path });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
Reference in new issue
Block a user