summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRagnar Thomsen <rthomsen6@gmail.com>2016-11-04 19:03:09 (GMT)
committerRagnar Thomsen <rthomsen6@gmail.com>2016-11-04 19:03:09 (GMT)
commit1074bf07a9b971a9cc6cb406b51436fbcd891b81 (patch)
tree70f18627a40a46bb4948b8fa1892b4cd96d3c842
parentb01c0c21f23d2926899e59ec3298a4d48efd0788 (diff)
Refactor CliInterface
CliInterface is refactored to be more simple. A new class CliProperties is added which holds all the commands, switches and regex's for the cli executables. Alot of code is moved from CliInterface to the new class. Two new member variables are added to ReadOnlyArchiveInterface of types QMimeType and KPluginMetaData. These are passed to CliProperties which it uses to call ArchiveFormat::fromMetadata() so it can check archive format properties. The KPluginMetaData is passed from Archive to ReadOnlyArchiveInterface as the second item in the args QVariantList. CompressionMethods provided in the plugin json files was changed from a QStringList to a QVariantMap so it can hold pairs of values: One user- visible string and one value for the cli-switch. Differential Revision: D3235
-rw-r--r--autotests/kerfuffle/jobstest.cpp5
-rw-r--r--autotests/plugins/cli7zplugin/cli7ztest.cpp81
-rw-r--r--autotests/plugins/clirarplugin/clirartest.cpp92
-rw-r--r--autotests/plugins/cliunarchiverplugin/cliunarchivertest.cpp52
-rw-r--r--autotests/plugins/clizipplugin/cliziptest.cpp76
-rw-r--r--autotests/plugins/clizipplugin/cliziptest.h7
-rw-r--r--kerfuffle/CMakeLists.txt1
-rw-r--r--kerfuffle/archive_kerfuffle.cpp3
-rw-r--r--kerfuffle/archive_kerfuffle.h2
-rw-r--r--kerfuffle/archiveformat.cpp11
-rw-r--r--kerfuffle/archiveformat.h6
-rw-r--r--kerfuffle/archiveinterface.cpp12
-rw-r--r--kerfuffle/archiveinterface.h7
-rw-r--r--kerfuffle/cliinterface.cpp542
-rw-r--r--kerfuffle/cliinterface.h324
-rw-r--r--kerfuffle/cliproperties.cpp342
-rw-r--r--kerfuffle/cliproperties.h152
-rw-r--r--kerfuffle/compressionoptionswidget.cpp2
-rw-r--r--plugins/cli7zplugin/cliplugin.cpp156
-rw-r--r--plugins/cli7zplugin/cliplugin.h9
-rw-r--r--plugins/cli7zplugin/kerfuffle_cli7z.json.cmake36
-rw-r--r--plugins/clirarplugin/cliplugin.cpp154
-rw-r--r--plugins/clirarplugin/cliplugin.h5
-rw-r--r--plugins/clirarplugin/kerfuffle_clirar.json.cmake20
-rw-r--r--plugins/cliunarchiverplugin/cliplugin.cpp52
-rw-r--r--plugins/cliunarchiverplugin/cliplugin.h4
-rw-r--r--plugins/cliunarchiverplugin/kerfuffle_cliunarchiver.json.cmake10
-rw-r--r--plugins/clizipplugin/cliplugin.cpp112
-rw-r--r--plugins/clizipplugin/cliplugin.h4
-rw-r--r--plugins/clizipplugin/kerfuffle_clizip.json.cmake16
30 files changed, 999 insertions, 1296 deletions
diff --git a/autotests/kerfuffle/jobstest.cpp b/autotests/kerfuffle/jobstest.cpp
index 7a748c0..dd7db1a 100644
--- a/autotests/kerfuffle/jobstest.cpp
+++ b/autotests/kerfuffle/jobstest.cpp
@@ -28,6 +28,8 @@
#include "kerfuffle/jobs.h"
#include "kerfuffle/archiveentry.h"
+#include <KPluginMetaData>
+
#include <QDebug>
#include <QEventLoop>
#include <QTest>
@@ -91,7 +93,8 @@ void JobsTest::slotNewEntry(Archive::Entry *entry)
JSONArchiveInterface *JobsTest::createArchiveInterface(const QString& filePath)
{
- JSONArchiveInterface *iface = new JSONArchiveInterface(this, {filePath});
+ JSONArchiveInterface *iface = new JSONArchiveInterface(this, {filePath,
+ QVariant().fromValue(KPluginMetaData())});
if (!iface->open()) {
qDebug() << "Could not open" << filePath;
return Q_NULLPTR;
diff --git a/autotests/plugins/cli7zplugin/cli7ztest.cpp b/autotests/plugins/cli7zplugin/cli7ztest.cpp
index 769b988..cdcfac0 100644
--- a/autotests/plugins/cli7zplugin/cli7ztest.cpp
+++ b/autotests/plugins/cli7zplugin/cli7ztest.cpp
@@ -164,7 +164,8 @@ void Cli7zTest::testList_data()
void Cli7zTest::testList()
{
qRegisterMetaType<Archive::Entry*>("Archive::Entry*");
- CliPlugin *plugin = new CliPlugin(this, {QStringLiteral("dummy.7z")});
+ CliPlugin *plugin = new CliPlugin(this, {QStringLiteral("dummy.7z"),
+ QVariant::fromValue(m_plugin->metaData())});
QSignalSpy signalSpyEntry(plugin, &CliPlugin::entry);
QSignalSpy signalSpyCompMethod(plugin, &CliPlugin::compressionMethodFound);
@@ -242,17 +243,18 @@ void Cli7zTest::testListArgs_data()
void Cli7zTest::testListArgs()
{
+ if (!m_plugin->isValid()) {
+ QSKIP("cli7z plugin not available. Skipping test.", SkipSingle);
+ }
+
QFETCH(QString, archiveName);
- CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName)});
+ CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName),
+ QVariant::fromValue(m_plugin->metaData())});
QVERIFY(plugin);
- const QStringList listArgs = { QStringLiteral("l"),
- QStringLiteral("-slt"),
- QStringLiteral("$PasswordSwitch"),
- QStringLiteral("$Archive") };
-
QFETCH(QString, password);
- const auto replacedArgs = plugin->substituteListVariables(listArgs, password);
+
+ const auto replacedArgs = plugin->cliProperties()->listArgs(archiveName, password);
QFETCH(QStringList, expectedArgs);
QCOMPARE(replacedArgs, expectedArgs);
@@ -275,9 +277,10 @@ void Cli7zTest::testAddArgs_data()
<< QString() << false << 5 << QStringLiteral("LZMA2") << 0UL
<< QStringList {
QStringLiteral("a"),
- QStringLiteral("/tmp/foo.7z"),
+ QStringLiteral("-l"),
QStringLiteral("-mx=5"),
- QStringLiteral("-m0=LZMA2")
+ QStringLiteral("-m0=LZMA2"),
+ QStringLiteral("/tmp/foo.7z")
};
QTest::newRow("encrypted")
@@ -285,10 +288,11 @@ void Cli7zTest::testAddArgs_data()
<< QStringLiteral("1234") << false << 5 << QStringLiteral("LZMA2") << 0UL
<< QStringList {
QStringLiteral("a"),
- QStringLiteral("/tmp/foo.7z"),
+ QStringLiteral("-l"),
QStringLiteral("-p1234"),
QStringLiteral("-mx=5"),
- QStringLiteral("-m0=LZMA2")
+ QStringLiteral("-m0=LZMA2"),
+ QStringLiteral("/tmp/foo.7z")
};
QTest::newRow("header-encrypted")
@@ -296,11 +300,12 @@ void Cli7zTest::testAddArgs_data()
<< QStringLiteral("1234") << true << 5 << QStringLiteral("LZMA2") << 0UL
<< QStringList {
QStringLiteral("a"),
- QStringLiteral("/tmp/foo.7z"),
+ QStringLiteral("-l"),
QStringLiteral("-p1234"),
QStringLiteral("-mhe=on"),
QStringLiteral("-mx=5"),
- QStringLiteral("-m0=LZMA2")
+ QStringLiteral("-m0=LZMA2"),
+ QStringLiteral("/tmp/foo.7z")
};
QTest::newRow("multi-volume")
@@ -308,10 +313,11 @@ void Cli7zTest::testAddArgs_data()
<< QString() << false << 5 << QStringLiteral("LZMA2") << 2500UL
<< QStringList {
QStringLiteral("a"),
- QStringLiteral("/tmp/foo.7z"),
+ QStringLiteral("-l"),
QStringLiteral("-mx=5"),
QStringLiteral("-m0=LZMA2"),
- QStringLiteral("-v2500k")
+ QStringLiteral("-v2500k"),
+ QStringLiteral("/tmp/foo.7z")
};
QTest::newRow("comp-method-bzip2")
@@ -319,33 +325,31 @@ void Cli7zTest::testAddArgs_data()
<< QString() << false << 5 << QStringLiteral("BZip2") << 0UL
<< QStringList {
QStringLiteral("a"),
- QStringLiteral("/tmp/foo.7z"),
+ QStringLiteral("-l"),
QStringLiteral("-mx=5"),
- QStringLiteral("-m0=BZip2")
+ QStringLiteral("-m0=BZip2"),
+ QStringLiteral("/tmp/foo.7z")
};
}
void Cli7zTest::testAddArgs()
{
+ if (!m_plugin->isValid()) {
+ QSKIP("cli7z plugin not available. Skipping test.", SkipSingle);
+ }
+
QFETCH(QString, archiveName);
- CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName)});
+ CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName),
+ QVariant::fromValue(m_plugin->metaData())});
QVERIFY(plugin);
- const QStringList addArgs = { QStringLiteral("a"),
- QStringLiteral("$Archive"),
- QStringLiteral("$PasswordSwitch"),
- QStringLiteral("$CompressionLevelSwitch"),
- QStringLiteral("$CompressionMethodSwitch"),
- QStringLiteral("$MultiVolumeSwitch"),
- QStringLiteral("$Files") };
-
QFETCH(QString, password);
QFETCH(bool, encryptHeader);
QFETCH(int, compressionLevel);
QFETCH(ulong, volumeSize);
QFETCH(QString, compressionMethod);
- QStringList replacedArgs = plugin->substituteAddVariables(addArgs, {}, password, encryptHeader, compressionLevel, volumeSize, compressionMethod);
+ const auto replacedArgs = plugin->cliProperties()->addArgs(archiveName, {}, password, encryptHeader, compressionLevel, compressionMethod, volumeSize);
QFETCH(QStringList, expectedArgs);
QCOMPARE(replacedArgs, expectedArgs);
@@ -422,24 +426,29 @@ void Cli7zTest::testExtractArgs_data()
void Cli7zTest::testExtractArgs()
{
+ if (!m_plugin->isValid()) {
+ QSKIP("cli7z plugin not available. Skipping test.", SkipSingle);
+ }
+
QFETCH(QString, archiveName);
- CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName)});
+ CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName),
+ QVariant::fromValue(m_plugin->metaData())});
QVERIFY(plugin);
- const QStringList extractArgs = { QStringLiteral("$PreservePathSwitch"),
- QStringLiteral("$PasswordSwitch"),
- QStringLiteral("$Archive"),
- QStringLiteral("$Files") };
-
QFETCH(QVector<Archive::Entry*>, files);
+ QStringList filesList;
+ foreach (const Archive::Entry *e, files) {
+ filesList << e->fullPath(NoTrailingSlash);
+ }
+
QFETCH(bool, preservePaths);
QFETCH(QString, password);
- QStringList replacedArgs = plugin->substituteExtractVariables(extractArgs, files, preservePaths, password);
- QVERIFY(replacedArgs.size() >= extractArgs.size());
+ const auto replacedArgs = plugin->cliProperties()->extractArgs(archiveName, filesList, preservePaths, password);
QFETCH(QStringList, expectedArgs);
QCOMPARE(replacedArgs, expectedArgs);
plugin->deleteLater();
}
+
diff --git a/autotests/plugins/clirarplugin/clirartest.cpp b/autotests/plugins/clirarplugin/clirartest.cpp
index b629b05..3920d4f 100644
--- a/autotests/plugins/clirarplugin/clirartest.cpp
+++ b/autotests/plugins/clirarplugin/clirartest.cpp
@@ -204,7 +204,8 @@ void CliRarTest::testList_data()
void CliRarTest::testList()
{
qRegisterMetaType<Archive::Entry*>("Archive::Entry*");
- CliPlugin *rarPlugin = new CliPlugin(this, {QStringLiteral("dummy.rar")});
+ CliPlugin *rarPlugin = new CliPlugin(this, {QStringLiteral("dummy.rar"),
+ QVariant::fromValue(m_plugin->metaData())});
QSignalSpy signalSpyEntry(rarPlugin, &CliPlugin::entry);
QSignalSpy signalSpyCompMethod(rarPlugin, &CliPlugin::compressionMethodFound);
QSignalSpy signalSpyError(rarPlugin, &CliPlugin::error);
@@ -300,17 +301,17 @@ void CliRarTest::testListArgs_data()
void CliRarTest::testListArgs()
{
+ if (!m_plugin->isValid()) {
+ QSKIP("clirar plugin not available. Skipping test.", SkipSingle);
+ }
+
QFETCH(QString, archiveName);
- CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName)});
+ CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName),
+ QVariant::fromValue(m_plugin->metaData())});
QVERIFY(plugin);
- const QStringList listArgs = { QStringLiteral("vt"),
- QStringLiteral("-v"),
- QStringLiteral("$PasswordSwitch"),
- QStringLiteral("$Archive") };
-
QFETCH(QString, password);
- const auto replacedArgs = plugin->substituteListVariables(listArgs, password);
+ const auto replacedArgs = plugin->cliProperties()->listArgs(archiveName, password);
QFETCH(QStringList, expectedArgs);
QCOMPARE(replacedArgs, expectedArgs);
@@ -333,9 +334,9 @@ void CliRarTest::testAddArgs_data()
<< QString() << false << 3 << QStringLiteral("RAR4") << 0UL
<< QStringList {
QStringLiteral("a"),
- QStringLiteral("/tmp/foo.rar"),
QStringLiteral("-m3"),
- QStringLiteral("-ma4")
+ QStringLiteral("-ma4"),
+ QStringLiteral("/tmp/foo.rar")
};
QTest::newRow("encrypted")
@@ -343,9 +344,9 @@ void CliRarTest::testAddArgs_data()
<< QStringLiteral("1234") << false << 3 << QString() << 0UL
<< QStringList {
QStringLiteral("a"),
- QStringLiteral("/tmp/foo.rar"),
QStringLiteral("-p1234"),
- QStringLiteral("-m3")
+ QStringLiteral("-m3"),
+ QStringLiteral("/tmp/foo.rar")
};
QTest::newRow("header-encrypted")
@@ -353,9 +354,9 @@ void CliRarTest::testAddArgs_data()
<< QStringLiteral("1234") << true << 3 << QString() << 0UL
<< QStringList {
QStringLiteral("a"),
- QStringLiteral("/tmp/foo.rar"),
QStringLiteral("-hp1234"),
- QStringLiteral("-m3")
+ QStringLiteral("-m3"),
+ QStringLiteral("/tmp/foo.rar")
};
QTest::newRow("multi-volume")
@@ -363,34 +364,31 @@ void CliRarTest::testAddArgs_data()
<< QString() << false << 3 << QString() << 2500UL
<< QStringList {
QStringLiteral("a"),
- QStringLiteral("/tmp/foo.rar"),
QStringLiteral("-m3"),
- QStringLiteral("-v2500k")
+ QStringLiteral("-v2500k"),
+ QStringLiteral("/tmp/foo.rar")
};
QTest::newRow("comp-method-RAR5")
<< QStringLiteral("/tmp/foo.rar")
<< QString() << false << 3 << QStringLiteral("RAR5") << 0UL
<< QStringList {
QStringLiteral("a"),
- QStringLiteral("/tmp/foo.rar"),
QStringLiteral("-m3"),
- QStringLiteral("-ma5")
+ QStringLiteral("-ma5"),
+ QStringLiteral("/tmp/foo.rar")
};
}
void CliRarTest::testAddArgs()
{
- QFETCH(QString, archiveName);
- CliPlugin *rarPlugin = new CliPlugin(this, {QVariant(archiveName)});
- QVERIFY(rarPlugin);
+ if (!m_plugin->isValid()) {
+ QSKIP("clirar plugin not available. Skipping test.", SkipSingle);
+ }
- const QStringList addArgs = { QStringLiteral("a"),
- QStringLiteral("$Archive"),
- QStringLiteral("$PasswordSwitch"),
- QStringLiteral("$CompressionLevelSwitch"),
- QStringLiteral("$CompressionMethodSwitch"),
- QStringLiteral("$MultiVolumeSwitch"),
- QStringLiteral("$Files") };
+ QFETCH(QString, archiveName);
+ CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName),
+ QVariant::fromValue(m_plugin->metaData())});
+ QVERIFY(plugin);
QFETCH(QString, password);
QFETCH(bool, encryptHeader);
@@ -398,12 +396,12 @@ void CliRarTest::testAddArgs()
QFETCH(QString, compressionMethod);
QFETCH(ulong, volumeSize);
- QStringList replacedArgs = rarPlugin->substituteAddVariables(addArgs, {}, password, encryptHeader, compressionLevel, volumeSize, compressionMethod);
+ const auto replacedArgs = plugin->cliProperties()->addArgs(archiveName, {}, password, encryptHeader, compressionLevel, compressionMethod, volumeSize);
QFETCH(QStringList, expectedArgs);
QCOMPARE(replacedArgs, expectedArgs);
- rarPlugin->deleteLater();
+ plugin->deleteLater();
}
void CliRarTest::testExtractArgs_data()
@@ -422,9 +420,9 @@ void CliRarTest::testExtractArgs_data()
}
<< true << QStringLiteral("1234")
<< QStringList {
+ QStringLiteral("x"),
QStringLiteral("-kb"),
QStringLiteral("-p-"),
- QStringLiteral("x"),
QStringLiteral("-p1234"),
QStringLiteral("/tmp/foo.rar"),
QStringLiteral("aDir/textfile2.txt"),
@@ -439,9 +437,9 @@ void CliRarTest::testExtractArgs_data()
}
<< true << QString()
<< QStringList {
+ QStringLiteral("x"),
QStringLiteral("-kb"),
QStringLiteral("-p-"),
- QStringLiteral("x"),
QStringLiteral("/tmp/foo.rar"),
QStringLiteral("aDir/textfile2.txt"),
QStringLiteral("c.txt"),
@@ -455,9 +453,9 @@ void CliRarTest::testExtractArgs_data()
}
<< false << QStringLiteral("1234")
<< QStringList {
+ QStringLiteral("e"),
QStringLiteral("-kb"),
QStringLiteral("-p-"),
- QStringLiteral("e"),
QStringLiteral("-p1234"),
QStringLiteral("/tmp/foo.rar"),
QStringLiteral("aDir/textfile2.txt"),
@@ -472,9 +470,9 @@ void CliRarTest::testExtractArgs_data()
}
<< false << QString()
<< QStringList {
+ QStringLiteral("e"),
QStringLiteral("-kb"),
QStringLiteral("-p-"),
- QStringLiteral("e"),
QStringLiteral("/tmp/foo.rar"),
QStringLiteral("aDir/textfile2.txt"),
QStringLiteral("c.txt"),
@@ -483,26 +481,28 @@ void CliRarTest::testExtractArgs_data()
void CliRarTest::testExtractArgs()
{
- QFETCH(QString, archiveName);
- CliPlugin *rarPlugin = new CliPlugin(this, {QVariant(archiveName)});
- QVERIFY(rarPlugin);
+ if (!m_plugin->isValid()) {
+ QSKIP("clirar plugin not available. Skipping test.", SkipSingle);
+ }
- const QStringList extractArgs = { QStringLiteral("-kb"),
- QStringLiteral("-p-"),
- QStringLiteral("$PreservePathSwitch"),
- QStringLiteral("$PasswordSwitch"),
- QStringLiteral("$Archive"),
- QStringLiteral("$Files") };
+ QFETCH(QString, archiveName);
+ CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName),
+ QVariant::fromValue(m_plugin->metaData())});
+ QVERIFY(plugin);
QFETCH(QVector<Archive::Entry*>, files);
+ QStringList filesList;
+ foreach (const Archive::Entry *e, files) {
+ filesList << e->fullPath(NoTrailingSlash);
+ }
+
QFETCH(bool, preservePaths);
QFETCH(QString, password);
- QStringList replacedArgs = rarPlugin->substituteExtractVariables(extractArgs, files, preservePaths, password);
- QVERIFY(replacedArgs.size() >= extractArgs.size());
+ const auto replacedArgs = plugin->cliProperties()->extractArgs(archiveName, filesList, preservePaths, password);
QFETCH(QStringList, expectedArgs);
QCOMPARE(replacedArgs, expectedArgs);
- rarPlugin->deleteLater();
+ plugin->deleteLater();
}
diff --git a/autotests/plugins/cliunarchiverplugin/cliunarchivertest.cpp b/autotests/plugins/cliunarchiverplugin/cliunarchivertest.cpp
index 52d7198..bded166 100644
--- a/autotests/plugins/cliunarchiverplugin/cliunarchivertest.cpp
+++ b/autotests/plugins/cliunarchiverplugin/cliunarchivertest.cpp
@@ -141,8 +141,9 @@ void CliUnarchiverTest::testList_data()
void CliUnarchiverTest::testList()
{
qRegisterMetaType<Archive::Entry*>("Archive::Entry*");
- CliPlugin *unarPlugin = new CliPlugin(this, {QStringLiteral("dummy.rar")});
- QSignalSpy signalSpy(unarPlugin, &CliPlugin::entry);
+ CliPlugin *plugin = new CliPlugin(this, {QStringLiteral("dummy.rar"),
+ QVariant::fromValue(m_plugin->metaData())});
+ QSignalSpy signalSpy(plugin, &CliPlugin::entry);
QFETCH(QString, jsonFilePath);
QFETCH(int, expectedEntriesCount);
@@ -151,7 +152,7 @@ void CliUnarchiverTest::testList()
QVERIFY(jsonFile.open(QIODevice::ReadOnly));
QTextStream stream(&jsonFile);
- unarPlugin->setJsonOutput(stream.readAll());
+ plugin->setJsonOutput(stream.readAll());
QCOMPARE(signalSpy.count(), expectedEntriesCount);
@@ -177,7 +178,7 @@ void CliUnarchiverTest::testList()
QFETCH(QString, expectedTimestamp);
QCOMPARE(entry->property("timestamp").toString(), expectedTimestamp);
- unarPlugin->deleteLater();
+ plugin->deleteLater();
}
void CliUnarchiverTest::testListArgs_data()
@@ -199,24 +200,25 @@ void CliUnarchiverTest::testListArgs_data()
<< QStringLiteral("1234")
<< QStringList {
QStringLiteral("-json"),
- QStringLiteral("/tmp/foo.rar"),
QStringLiteral("-password"),
- QStringLiteral("1234")
+ QStringLiteral("1234"),
+ QStringLiteral("/tmp/foo.rar")
};
}
void CliUnarchiverTest::testListArgs()
{
+ if (!m_plugin->isValid()) {
+ QSKIP("cliunarchiver plugin not available. Skipping test.", SkipSingle);
+ }
+
QFETCH(QString, archiveName);
- CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName)});
+ CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName),
+ QVariant::fromValue(m_plugin->metaData())});
QVERIFY(plugin);
- const QStringList listArgs = { QStringLiteral("-json"),
- QStringLiteral("$Archive"),
- QStringLiteral("$PasswordSwitch") };
-
QFETCH(QString, password);
- const auto replacedArgs = plugin->substituteListVariables(listArgs, password);
+ const auto replacedArgs = plugin->cliProperties()->listArgs(archiveName, password);
QFETCH(QStringList, expectedArgs);
QCOMPARE(replacedArgs, expectedArgs);
@@ -352,11 +354,11 @@ void CliUnarchiverTest::testExtractArgs_data()
<< QStringLiteral("1234")
<< QStringList {
QStringLiteral("-D"),
+ QStringLiteral("-password"),
+ QStringLiteral("1234"),
QStringLiteral("/tmp/foo.rar"),
QStringLiteral("aDir/b.txt"),
- QStringLiteral("c.txt"),
- QStringLiteral("-password"),
- QStringLiteral("1234")
+ QStringLiteral("c.txt")
};
QTest::newRow("unencrypted, multiple files")
@@ -376,20 +378,24 @@ void CliUnarchiverTest::testExtractArgs_data()
void CliUnarchiverTest::testExtractArgs()
{
+ if (!m_plugin->isValid()) {
+ QSKIP("cliunarchiver plugin not available. Skipping test.", SkipSingle);
+ }
+
QFETCH(QString, archiveName);
- CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName)});
+ CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName),
+ QVariant::fromValue(m_plugin->metaData())});
QVERIFY(plugin);
- const QStringList extractArgs = { QStringLiteral("-D"),
- QStringLiteral("$Archive"),
- QStringLiteral("$Files"),
- QStringLiteral("$PasswordSwitch") };
-
QFETCH(QVector<Archive::Entry*>, files);
+ QStringList filesList;
+ foreach (const Archive::Entry *e, files) {
+ filesList << e->fullPath(NoTrailingSlash);
+ }
+
QFETCH(QString, password);
- QStringList replacedArgs = plugin->substituteExtractVariables(extractArgs, files, false, password);
- QVERIFY(replacedArgs.size() >= extractArgs.size());
+ const auto replacedArgs = plugin->cliProperties()->extractArgs(archiveName, filesList, false, password);
QFETCH(QStringList, expectedArgs);
QCOMPARE(replacedArgs, expectedArgs);
diff --git a/autotests/plugins/clizipplugin/cliziptest.cpp b/autotests/plugins/clizipplugin/cliziptest.cpp
index d77a6b0..22a5b2e 100644
--- a/autotests/plugins/clizipplugin/cliziptest.cpp
+++ b/autotests/plugins/clizipplugin/cliziptest.cpp
@@ -30,6 +30,17 @@ QTEST_GUILESS_MAIN(CliZipTest)
using namespace Kerfuffle;
+void CliZipTest::initTestCase()
+{
+ m_plugin = new Plugin(this);
+ foreach (Plugin *plugin, m_pluginManger.availablePlugins()) {
+ if (plugin->metaData().pluginId() == QStringLiteral("kerfuffle_clizip")) {
+ m_plugin = plugin;
+ return;
+ }
+ }
+}
+
void CliZipTest::testListArgs_data()
{
QTest::addColumn<QString>("archiveName");
@@ -47,16 +58,16 @@ void CliZipTest::testListArgs_data()
void CliZipTest::testListArgs()
{
+ if (!m_plugin->isValid()) {
+ QSKIP("clizip plugin not available. Skipping test.", SkipSingle);
+ }
+
QFETCH(QString, archiveName);
- CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName)});
+ CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName),
+ QVariant::fromValue(m_plugin->metaData())});
QVERIFY(plugin);
- const QStringList listArgs = { QStringLiteral("-l"),
- QStringLiteral("-T"),
- QStringLiteral("-z"),
- QStringLiteral("$Archive") };
-
- const auto replacedArgs = plugin->substituteListVariables(listArgs, QString());
+ const auto replacedArgs = plugin->cliProperties()->listArgs(archiveName, QString());
QFETCH(QStringList, expectedArgs);
QCOMPARE(replacedArgs, expectedArgs);
@@ -74,12 +85,12 @@ void CliZipTest::testAddArgs_data()
QTest::newRow("unencrypted")
<< QStringLiteral("/tmp/foo.zip")
- << QString() << 3 << QStringLiteral("deflate")
+ << QString() << 3 << QStringLiteral("Deflate")
<< QStringList {
QStringLiteral("-r"),
- QStringLiteral("/tmp/foo.zip"),
QStringLiteral("-3"),
- QStringLiteral("-Zdeflate")
+ QStringLiteral("-Zdeflate"),
+ QStringLiteral("/tmp/foo.zip")
};
QTest::newRow("encrypted")
@@ -87,40 +98,38 @@ void CliZipTest::testAddArgs_data()
<< QStringLiteral("1234") << 3 << QString()
<< QStringList {
QStringLiteral("-r"),
- QStringLiteral("/tmp/foo.zip"),
QStringLiteral("-P1234"),
- QStringLiteral("-3")
+ QStringLiteral("-3"),
+ QStringLiteral("/tmp/foo.zip")
};
QTest::newRow("comp-method-bzip2")
<< QStringLiteral("/tmp/foo.zip")
- << QString() << 3 << QStringLiteral("bzip2")
+ << QString() << 3 << QStringLiteral("BZip2")
<< QStringList {
QStringLiteral("-r"),
- QStringLiteral("/tmp/foo.zip"),
QStringLiteral("-3"),
- QStringLiteral("-Zbzip2")
+ QStringLiteral("-Zbzip2"),
+ QStringLiteral("/tmp/foo.zip")
};
}
void CliZipTest::testAddArgs()
{
+ if (!m_plugin->isValid()) {
+ QSKIP("clizip plugin not available. Skipping test.", SkipSingle);
+ }
+
QFETCH(QString, archiveName);
- CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName)});
+ CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName),
+ QVariant::fromValue(m_plugin->metaData())});
QVERIFY(plugin);
- const QStringList addArgs = { QStringLiteral("-r"),
- QStringLiteral("$Archive"),
- QStringLiteral("$PasswordSwitch"),
- QStringLiteral("$CompressionLevelSwitch"),
- QStringLiteral("$CompressionMethodSwitch"),
- QStringLiteral("$Files") };
-
QFETCH(QString, password);
QFETCH(int, compressionLevel);
QFETCH(QString, compressionMethod);
- QStringList replacedArgs = plugin->substituteAddVariables(addArgs, {}, password, false, compressionLevel, 0, compressionMethod);
+ const auto replacedArgs = plugin->cliProperties()->addArgs(archiveName, {}, password, false, compressionLevel, compressionMethod, 0);
QFETCH(QStringList, expectedArgs);
QCOMPARE(replacedArgs, expectedArgs);
@@ -195,20 +204,25 @@ void CliZipTest::testExtractArgs_data()
void CliZipTest::testExtractArgs()
{
+ if (!m_plugin->isValid()) {
+ QSKIP("clizip plugin not available. Skipping test.", SkipSingle);
+ }
+
QFETCH(QString, archiveName);
- CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName)});
+ CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName),
+ QVariant::fromValue(m_plugin->metaData())});
QVERIFY(plugin);
- const QStringList extractArgs = { QStringLiteral("$PreservePathSwitch"),
- QStringLiteral("$PasswordSwitch"),
- QStringLiteral("$Archive"),
- QStringLiteral("$Files") };
-
QFETCH(QVector<Archive::Entry*>, files);
+ QStringList filesList;
+ foreach (const Archive::Entry *e, files) {
+ filesList << e->fullPath(NoTrailingSlash);
+ }
+
QFETCH(bool, preservePaths);
QFETCH(QString, password);
- QStringList replacedArgs = plugin->substituteExtractVariables(extractArgs, files, preservePaths, password);
+ const auto replacedArgs = plugin->cliProperties()->extractArgs(archiveName, filesList, preservePaths, password);
QFETCH(QStringList, expectedArgs);
QCOMPARE(replacedArgs, expectedArgs);
diff --git a/autotests/plugins/clizipplugin/cliziptest.h b/autotests/plugins/clizipplugin/cliziptest.h
index 6f8aed2..4b25371 100644
--- a/autotests/plugins/clizipplugin/cliziptest.h
+++ b/autotests/plugins/clizipplugin/cliziptest.h
@@ -29,6 +29,7 @@
#include "cliplugin.h"
#include "autotests/testhelper/testhelper.h"
#include "kerfuffle/jobs.h"
+#include "pluginmanager.h"
using namespace Kerfuffle;
@@ -37,13 +38,17 @@ class CliZipTest : public QObject
Q_OBJECT
private Q_SLOTS:
-
+ void initTestCase();
void testListArgs_data();
void testListArgs();
void testAddArgs_data();
void testAddArgs();
void testExtractArgs_data();
void testExtractArgs();
+
+private:
+ PluginManager m_pluginManger;
+ Plugin *m_plugin;
};
#endif
diff --git a/kerfuffle/CMakeLists.txt b/kerfuffle/CMakeLists.txt
index f114bd0..663e2ef 100644
--- a/kerfuffle/CMakeLists.txt
+++ b/kerfuffle/CMakeLists.txt
@@ -16,6 +16,7 @@ set(kerfuffle_SRCS
queries.cpp
addtoarchive.cpp
cliinterface.cpp
+ cliproperties.cpp
mimetypes.cpp
plugin.cpp
pluginmanager.cpp
diff --git a/kerfuffle/archive_kerfuffle.cpp b/kerfuffle/archive_kerfuffle.cpp
index 78e2edb..7b80749 100644
--- a/kerfuffle/archive_kerfuffle.cpp
+++ b/kerfuffle/archive_kerfuffle.cpp
@@ -85,7 +85,8 @@ Archive *Archive::create(const QString &fileName, Plugin *plugin, QObject *paren
return new Archive(FailedPlugin, parent);
}
- const QVariantList args = {QVariant(QFileInfo(fileName).absoluteFilePath())};
+ const QVariantList args = {QVariant(QFileInfo(fileName).absoluteFilePath()),
+ QVariant().fromValue(plugin->metaData())};
ReadOnlyArchiveInterface *iface = factory->create<ReadOnlyArchiveInterface>(Q_NULLPTR, args);
if (!iface) {
qCWarning(ARK) << "Could not create plugin instance" << plugin->metaData().pluginId();
diff --git a/kerfuffle/archive_kerfuffle.h b/kerfuffle/archive_kerfuffle.h
index b3daa8b..80ebb54 100644
--- a/kerfuffle/archive_kerfuffle.h
+++ b/kerfuffle/archive_kerfuffle.h
@@ -242,4 +242,6 @@ private:
} // namespace Kerfuffle
+Q_DECLARE_METATYPE(KPluginMetaData)
+
#endif // ARCHIVE_H
diff --git a/kerfuffle/archiveformat.cpp b/kerfuffle/archiveformat.cpp
index a32b8ec..454c3f7 100644
--- a/kerfuffle/archiveformat.cpp
+++ b/kerfuffle/archiveformat.cpp
@@ -24,6 +24,7 @@
*/
#include "archiveformat.h"
+#include "ark_debug.h"
#include <QJsonArray>
@@ -43,7 +44,7 @@ ArchiveFormat::ArchiveFormat(const QMimeType& mimeType,
bool supportsWriteComment,
bool supportsTesting,
bool supportsMultiVolume,
- QStringList compressionMethods,
+ QVariantMap compressionMethods,
QString defaultCompressionMethod) :
m_mimeType(mimeType),
m_encryptionType(encryptionType),
@@ -76,11 +77,7 @@ ArchiveFormat ArchiveFormat::fromMetadata(const QMimeType& mimeType, const KPlug
bool supportsTesting = formatProps[QStringLiteral("SupportsTesting")].toBool();
bool supportsMultiVolume = formatProps[QStringLiteral("SupportsMultiVolume")].toBool();
- QStringList compressionMethods;
- QJsonArray array = formatProps[QStringLiteral("CompressionMethods")].toArray();
- foreach (const QJsonValue &value, array) {
- compressionMethods.append(value.toString());
- }
+ QVariantMap compressionMethods = formatProps[QStringLiteral("CompressionMethods")].toObject().toVariantMap();
QString defaultCompMethod = formatProps[QStringLiteral("CompressionMethodDefault")].toString();
Archive::EncryptionType encType = Archive::Unencrypted;
@@ -136,7 +133,7 @@ bool ArchiveFormat::supportsMultiVolume() const
return m_supportsMultiVolume;
}
-QStringList ArchiveFormat::compressionMethods() const
+QVariantMap ArchiveFormat::compressionMethods() const
{
return m_compressionMethods;
}
diff --git a/kerfuffle/archiveformat.h b/kerfuffle/archiveformat.h
index 4e741aa..c093857 100644
--- a/kerfuffle/archiveformat.h
+++ b/kerfuffle/archiveformat.h
@@ -45,7 +45,7 @@ public:
bool supportsWriteComment,
bool supportsTesting,
bool suppportsMultiVolume,
- QStringList compressionMethods,
+ QVariantMap compressionMethods,
QString defaultCompressionMethod);
/**
@@ -69,7 +69,7 @@ public:
bool supportsWriteComment() const;
bool supportsTesting() const;
bool supportsMultiVolume() const;
- QStringList compressionMethods() const;
+ QVariantMap compressionMethods() const;
QString defaultCompressionMethod() const;
private:
@@ -81,7 +81,7 @@ private:
bool m_supportsWriteComment;
bool m_supportsTesting;
bool m_supportsMultiVolume;
- QStringList m_compressionMethods;
+ QVariantMap m_compressionMethods;
QString m_defaultCompressionMethod;
};
diff --git a/kerfuffle/archiveinterface.cpp b/kerfuffle/archiveinterface.cpp
index d9e7090..6728135 100644
--- a/kerfuffle/archiveinterface.cpp
+++ b/kerfuffle/archiveinterface.cpp
@@ -28,6 +28,7 @@
#include "archiveinterface.h"
#include "ark_debug.h"
+#include "mimetypes.h"
#include <kfileitem.h>
@@ -46,9 +47,13 @@ ReadOnlyArchiveInterface::ReadOnlyArchiveInterface(QObject *parent, const QVaria
, m_isCorrupt(false)
, m_isMultiVolume(false)
{
+ Q_ASSERT(args.size() >= 2);
+
qCDebug(ARK) << "Created read-only interface for" << args.first().toString();
m_filename = args.first().toString();
+ m_mimetype = determineMimeType(m_filename);
connect(this, &ReadOnlyArchiveInterface::entry, this, &ReadOnlyArchiveInterface::onEntry);
+ m_metaData = args.at(1).value<KPluginMetaData>();
}
ReadOnlyArchiveInterface::~ReadOnlyArchiveInterface()
@@ -144,7 +149,7 @@ QString ReadOnlyArchiveInterface::multiVolumeName() const
return filename();
}
-ReadWriteArchiveInterface::ReadWriteArchiveInterface(QObject *parent, const QVariantList & args)
+ReadWriteArchiveInterface::ReadWriteArchiveInterface(QObject *parent, const QVariantList &args)
: ReadOnlyArchiveInterface(parent, args)
{
qCDebug(ARK) << "Created read-write interface for" << args.first().toString();
@@ -254,6 +259,11 @@ bool ReadOnlyArchiveInterface::isHeaderEncryptionEnabled() const
return m_isHeaderEncryptionEnabled;
}
+QMimeType ReadOnlyArchiveInterface::mimetype() const
+{
+ return m_mimetype;
+}
+
bool ReadWriteArchiveInterface::isReadOnly() const
{
// We set corrupt archives to read-only to avoid add/delete actions, that
diff --git a/kerfuffle/archiveinterface.h b/kerfuffle/archiveinterface.h
index afb19ed..4b009f3 100644
--- a/kerfuffle/archiveinterface.h
+++ b/kerfuffle/archiveinterface.h
@@ -47,7 +47,7 @@ class KERFUFFLE_EXPORT ReadOnlyArchiveInterface: public QObject
{
Q_OBJECT
public:
- explicit ReadOnlyArchiveInterface(QObject *parent, const QVariantList & args);
+ explicit ReadOnlyArchiveInterface(QObject *parent, const QVariantList &args);
virtual ~ReadOnlyArchiveInterface();
/**
@@ -157,6 +157,7 @@ public:
virtual QString multiVolumeName() const;
void setMultiVolume(bool value);
int numberOfEntries() const;
+ QMimeType mimetype() const;
signals:
void cancelled();
@@ -182,9 +183,11 @@ protected:
QString m_comment;
int m_numberOfVolumes;
int m_numberOfEntries;
+ KPluginMetaData m_metaData;
private:
QString m_filename;
+ QMimeType m_mimetype;
QString m_password;
bool m_waitForFinishedSignal;
bool m_isHeaderEncryptionEnabled;
@@ -203,7 +206,7 @@ public:
List, Extract, Add, Move, Copy, Delete, Comment, Test
};
- explicit ReadWriteArchiveInterface(QObject *parent, const QVariantList & args);
+ explicit ReadWriteArchiveInterface(QObject *parent, const QVariantList &args);
virtual ~ReadWriteArchiveInterface();
bool isReadOnly() const Q_DECL_OVERRIDE;
diff --git a/kerfuffle/cliinterface.cpp b/kerfuffle/cliinterface.cpp
index f0d2bdb..9482d7a 100644
--- a/kerfuffle/cliinterface.cpp
+++ b/kerfuffle/cliinterface.cpp
@@ -73,16 +73,7 @@ CliInterface::CliInterface(QObject *parent, const QVariantList & args)
if (QMetaType::type("QProcess::ExitStatus") == 0) {
qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
}
-}
-
-void CliInterface::cacheParameterList()
-{
- m_param = parameterList();
- Q_ASSERT(m_param.contains(ExtractProgram));
- Q_ASSERT(m_param.contains(ListProgram));
- Q_ASSERT(m_param.contains(PreservePathSwitch));
- Q_ASSERT(m_param.contains(FileExistsExpression));
- Q_ASSERT(m_param.contains(FileExistsInput));
+ m_cliProps = new CliProperties(this, m_metaData, mimetype());
}
CliInterface::~CliInterface()
@@ -104,13 +95,10 @@ int CliInterface::copyRequiredSignals() const
bool CliInterface::list()
{
resetParsing();
- cacheParameterList();
m_operationMode = List;
m_numberOfEntries = 0;
- const auto args = substituteListVariables(m_param.value(ListArgs).toStringList(), password());
-
- if (!runProcess(m_param.value(ListProgram).toStringList(), args)) {
+ if (!runProcess(m_cliProps->property("listProgram").toString(), m_cliProps->listArgs(filename(), password()))) {
return false;
}
@@ -121,26 +109,20 @@ bool CliInterface::extractFiles(const QVector<Archive::Entry*> &files, const QSt
{
qCDebug(ARK) << Q_FUNC_INFO << "to" << destinationDirectory;
- cacheParameterList();
m_operationMode = Extract;
m_extractionOptions = options;
m_extractedFiles = files;
m_extractDestDir = destinationDirectory;
- const QStringList extractArgs = m_param.value(ExtractArgs).toStringList();
- if (extractArgs.contains(QStringLiteral("$PasswordSwitch")) && options.encryptedArchiveHint() && password().isEmpty()) {
+
+
+ if (!m_cliProps->property("passwordSwitch").toString().isEmpty() && options.encryptedArchiveHint() && password().isEmpty()) {
qCDebug(ARK) << "Password hint enabled, querying user";
if (!passwordQuery()) {
return false;
}
}
- // Populate the argument list.
- const QStringList args = substituteExtractVariables(extractArgs,
- files,
- options.preservePaths(),
- password());
-
QUrl destDir = QUrl(destinationDirectory);
QDir::setCurrent(destDir.adjusted(QUrl::RemoveScheme).url());
@@ -162,7 +144,11 @@ bool CliInterface::extractFiles(const QVector<Archive::Entry*> &files, const QSt
QDir::setCurrent(destDir.adjusted(QUrl::RemoveScheme).url());
}
- if (!runProcess(m_param.value(ExtractProgram).toStringList(), args)) {
+ if (!runProcess(m_cliProps->property("extractProgram").toString(),
+ m_cliProps->extractArgs(filename(),
+ extractFilesList(files),
+ options.preservePaths(),
+ password()))) {
return false;
}
@@ -173,12 +159,8 @@ bool CliInterface::addFiles(const QVector<Archive::Entry*> &files, const Archive
{
Q_UNUSED(numberOfEntriesToAdd)
- cacheParameterList();
-
m_operationMode = Add;
- const QStringList addArgs = m_param.value(AddArgs).toStringList();
-
QVector<Archive::Entry*> filesToPass = QVector<Archive::Entry*>();
// If destination path is specified, we have recreate its structure inside the temp directory
// and then place symlinks of targeted files there.
@@ -223,40 +205,38 @@ bool CliInterface::addFiles(const QVector<Archive::Entry*> &files, const Archive
filesToPass = files;
}
- if (addArgs.contains(QStringLiteral("$PasswordSwitch")) && options.encryptedArchiveHint() && password().isEmpty()) {
+ if (!m_cliProps->property("passwordSwitch").toString().isEmpty() && options.encryptedArchiveHint() && password().isEmpty()) {
qCDebug(ARK) << "Password hint enabled, querying user";
if (!passwordQuery()) {
return false;
}
}
- const auto args = substituteAddVariables(m_param.value(AddArgs).toStringList(),
- filesToPass,
- password(),
- isHeaderEncryptionEnabled(),
- options.compressionLevel(),
- options.volumeSize(),
- options.compressionMethod());
-
- return runProcess(m_param.value(AddProgram).toStringList(), args);
+ return runProcess(m_cliProps->property("addProgram").toString(),
+ m_cliProps->addArgs(filename(),
+ entryFullPaths(filesToPass, NoTrailingSlash),
+ password(),
+ isHeaderEncryptionEnabled(),
+ options.compressionLevel(),
+ options.compressionMethod(),
+ options.volumeSize()));
}
bool CliInterface::moveFiles(const QVector<Archive::Entry*> &files, Archive::Entry *destination, const CompressionOptions &options)
{
Q_UNUSED(options);
- cacheParameterList();
m_operationMode = Move;
m_removedFiles = files;
QVector<Archive::Entry*> withoutChildren = entriesWithoutChildren(files);
setNewMovedFiles(files, destination, withoutChildren.count());
- const auto moveArgs = m_param.value(MoveArgs).toStringList();
-
- const auto args = substituteMoveVariables(moveArgs, withoutChildren, destination, password());
-
- return runProcess(m_param.value(MoveProgram).toStringList(), args);
+ return runProcess(m_cliProps->property("moveProgram").toString(),
+ m_cliProps->moveArgs(filename(),
+ withoutChildren,
+ destination,
+ password()));
}
bool CliInterface::copyFiles(const QVector<Archive::Entry*> &files, Archive::Entry *destination, const CompressionOptions &options)
@@ -278,45 +258,29 @@ bool CliInterface::copyFiles(const QVector<Archive::Entry*> &files, Archive::Ent
bool CliInterface::deleteFiles(const QVector<Archive::Entry*> &files)
{
- cacheParameterList();
m_operationMode = Delete;
m_removedFiles = files;
- const auto deleteArgs = m_param.value(DeleteArgs).toStringList();
-
- const auto args = substituteDeleteVariables(deleteArgs,
- files,
- password());
-
- return runProcess(m_param.value(DeleteProgram).toStringList(), args);
+ return runProcess(m_cliProps->property("deleteProgram").toString(),
+ m_cliProps->deleteArgs(filename(), files, password()));
}
bool CliInterface::testArchive()
{
resetParsing();
- cacheParameterList();
m_operationMode = Test;
- const auto args = substituteTestVariables(m_param.value(TestArgs).toStringList(), password());
-
- return runProcess(m_param.value(TestProgram).toStringList(), args);
+ return runProcess(m_cliProps->property("testProgram").toString(), m_cliProps->testArgs(filename(), password()));
}
-bool CliInterface::runProcess(const QStringList& programNames, const QStringList& arguments)
+bool CliInterface::runProcess(const QString& programName, const QStringList& arguments)
{
Q_ASSERT(!m_process);
- QString programPath;
- for (int i = 0; i < programNames.count(); i++) {
- programPath = QStandardPaths::findExecutable(programNames.at(i));
- if (!programPath.isEmpty())
- break;
- }
+ QString programPath = QStandardPaths::findExecutable(programName);
if (programPath.isEmpty()) {
- const QString names = programNames.join(QStringLiteral(", "));
- emit error(xi18ncp("@info", "Failed to locate program <filename>%2</filename> on disk.",
- "Failed to locate programs <filename>%2</filename> on disk.", programNames.count(), names));
+ emit error(xi18nc("@info", "Failed to locate program <filename>%2</filename> on disk.", programName));
emit finished(false);
return false;
}
@@ -685,248 +649,6 @@ bool CliInterface::moveToDestination(const QDir &tempDir, const QDir &destDir, b
return true;
}
-QStringList CliInterface::substituteListVariables(const QStringList &listArgs, const QString &password)
-{
- // Required if we call this function from unit tests.
- cacheParameterList();
-
- QStringList args;
- foreach (const QString& arg, listArgs) {
- if (arg == QLatin1String("$Archive")) {
- args << filename();
- continue;
- }
-
- if (arg == QLatin1String("$PasswordSwitch")) {
- args << passwordSwitch(password);
- continue;
- }
-
- // Simple argument (e.g. -slt in 7z), nothing to substitute, just add it to the list.
- args << arg;
- }
-
- // Remove empty strings, if any.
- args.removeAll(QString());
-
- return args;
-}
-
-QStringList CliInterface::substituteExtractVariables(const QStringList &extractArgs, const QVector<Archive::Entry*> &entries, bool preservePaths, const QString &password)
-{
- // Required if we call this function from unit tests.
- cacheParameterList();
-
- QStringList args;
- foreach (const QString& arg, extractArgs) {
- qCDebug(ARK) << "Processing argument" << arg;
-
- if (arg == QLatin1String("$Archive")) {
- args << filename();
- continue;
- }
-
- if (arg == QLatin1String("$PreservePathSwitch")) {
- args << preservePathSwitch(preservePaths);
- continue;
- }
-
- if (arg == QLatin1String("$PasswordSwitch")) {
- args << passwordSwitch(password);
- continue;
- }
-
- if (arg == QLatin1String("$Files")) {
- args << extractFilesList(entries);
- continue;
- }
-
- // Simple argument (e.g. -kb in unrar), nothing to substitute, just add it to the list.
- args << arg;
- }
-
- // Remove empty strings, if any.
- args.removeAll(QString());
-
- return args;
-}
-
-QStringList CliInterface::substituteAddVariables(const QStringList &addArgs, const QVector<Archive::Entry*> &entries, const QString &password, bool encryptHeader, int compLevel, ulong volumeSize, QString compMethod)
-{
- // Required if we call this function from unit tests.
- cacheParameterList();
-
- QStringList args;
- foreach (const QString& arg, addArgs) {
- qCDebug(ARK) << "Processing argument " << arg;
-
- if (arg == QLatin1String("$Archive")) {
- args << filename();
- continue;
- }
-
- if (arg == QLatin1String("$PasswordSwitch")) {
- args << (encryptHeader ? passwordHeaderSwitch(password) : passwordSwitch(password));
- continue;
- }
-
- if (arg == QLatin1String("$CompressionLevelSwitch")) {
- args << compressionLevelSwitch(compLevel);
- continue;
- }
-
- if (arg == QLatin1String("$CompressionMethodSwitch")) {
- args << compressionMethodSwitch(compMethod);
- continue;
- }
-
- if (arg == QLatin1String("$MultiVolumeSwitch")) {
- args << multiVolumeSwitch(volumeSize);
- continue;
- }
-
- if (arg == QLatin1String("$Files")) {
- args << entryFullPaths(entries, NoTrailingSlash);
- continue;
- }
-
- // Simple argument (e.g. a in 7z), nothing to substitute, just add it to the list.
- args << arg;
- }
-
- // Remove empty strings, if any.
- args.removeAll(QString());
-
- return args;
-}
-
-QStringList CliInterface::substituteMoveVariables(const QStringList &moveArgs, const QVector<Archive::Entry*> &entriesWithoutChildren, const Archive::Entry *destination, const QString &password)
-{
- // Required if we call this function from unit tests.
- cacheParameterList();
-
- QStringList args;
- foreach (const QString& arg, moveArgs) {
- qCDebug(ARK) << "Processing argument " << arg;
-
- if (arg == QLatin1String("$Archive")) {
- args << filename();
- continue;
- }
-
- if (arg == QLatin1String("$PasswordSwitch")) {
- args << passwordSwitch(password);
- continue;
- }
-
- if (arg == QLatin1String("$PathPairs")) {
- args << entryPathDestinationPairs(entriesWithoutChildren, destination);
- continue;
- }
-
- // Simple argument (e.g. a in 7z), nothing to substitute, just add it to the list.
- args << arg;
- }
-
- // Remove empty strings, if any.
- args.removeAll(QString());
-
- return args;
-}
-
-QStringList CliInterface::substituteDeleteVariables(const QStringList &deleteArgs, const QVector<Archive::Entry*> &entries, const QString &password)
-{
- cacheParameterList();
-
- QStringList args;
- foreach (const QString& arg, deleteArgs) {
- qCDebug(ARK) << "Processing argument" << arg;
-
- if (arg == QLatin1String("$Archive")) {
- args << filename();
- continue;
- }
-
- if (arg == QLatin1String("$PasswordSwitch")) {
- args << passwordSwitch(password);
- continue;
- }
-
- if (arg == QLatin1String("$Files")) {
- foreach (const Archive::Entry *e, entries) {
- args << escapeFileName(e->fullPath(NoTrailingSlash));
- }
- continue;
- }
-
- // Simple argument (e.g. d in rar), nothing to substitute, just add it to the list.
- args << arg;
- }
-
- // Remove empty strings, if any.
- args.removeAll(QString());
-
- return args;
-}
-
-QStringList CliInterface::substituteCommentVariables(const QStringList &commentArgs, const QString &commentFile)
-{
- // Required if we call this function from unit tests.
- cacheParameterList();
-
- QStringList args;
- foreach (const QString& arg, commentArgs) {
- qCDebug(ARK) << "Processing argument " << arg;
-
- if (arg == QLatin1String("$Archive")) {
- args << filename();
- continue;
- }
-
- if (arg == QLatin1String("$CommentSwitch")) {
- QString commentSwitch = m_param.value(CommentSwitch).toString();
- commentSwitch.replace(QStringLiteral("$CommentFile"), commentFile);
- args << commentSwitch;
- continue;
- }
-
- args << arg;
- }
-
- // Remove empty strings, if any.
- args.removeAll(QString());
-
- return args;
-}
-
-QStringList CliInterface::substituteTestVariables(const QStringList &testArgs, const QString &password)
-{
- // Required if we call this function from unit tests.
- cacheParameterList();
-
- QStringList args;
- foreach (const QString& arg, testArgs) {
- qCDebug(ARK) << "Processing argument " << arg;
-
- if (arg == QLatin1String("$Archive")) {
- args << filename();
- continue;
- }
-
- if (arg == QLatin1String("$PasswordSwitch")) {
- args << passwordSwitch(password);
- continue;
- }
-
- args << arg;
- }
-
- // Remove empty strings, if any.
- args.removeAll(QString());
-
- return args;
-}
-
void CliInterface::setNewMovedFiles(const QVector<Archive::Entry*> &entries, const Archive::Entry *destination, int entriesWithoutChildren)
{
m_newMovedFiles.clear();
@@ -971,104 +693,6 @@ void CliInterface::setNewMovedFiles(const QVector<Archive::Entry*> &entries, con
}
}
-QString CliInterface::preservePathSwitch(bool preservePaths) const
-{
- Q_ASSERT(m_param.contains(PreservePathSwitch));
- const QStringList theSwitch = m_param.value(PreservePathSwitch).toStringList();
- Q_ASSERT(theSwitch.size() == 2);
-
- return (preservePaths ? theSwitch.at(0) : theSwitch.at(1));
-}
-
-QStringList CliInterface::passwordHeaderSwitch(const QString& password) const
-{
- if (password.isEmpty()) {
- return QStringList();
- }
-
- Q_ASSERT(m_param.contains(PasswordHeaderSwitch));
-
- QStringList passwordHeaderSwitch = m_param.value(PasswordHeaderSwitch).toStringList();
- Q_ASSERT(!passwordHeaderSwitch.isEmpty() && passwordHeaderSwitch.size() <= 2);
-
- if (passwordHeaderSwitch.size() == 1) {
- passwordHeaderSwitch[0].replace(QLatin1String("$Password"), password);
- } else {
- passwordHeaderSwitch[1] = password;
- }
-
- return passwordHeaderSwitch;
-}
-
-QStringList CliInterface::passwordSwitch(const QString& password) const
-{
- if (password.isEmpty()) {
- return QStringList();
- }
-
- Q_ASSERT(m_param.contains(PasswordSwitch));
-
- QStringList passwordSwitch = m_param.value(PasswordSwitch).toStringList();
- Q_ASSERT(!passwordSwitch.isEmpty() && passwordSwitch.size() <= 2);
-
- if (passwordSwitch.size() == 1) {
- passwordSwitch[0].replace(QLatin1String("$Password"), password);
- } else {
- passwordSwitch[1] = password;
- }
-
- return passwordSwitch;
-}
-
-QString CliInterface::compressionLevelSwitch(int level) const
-{
- if (level < 0 || level > 9) {
- return QString();
- }
-
- Q_ASSERT(m_param.contains(CompressionLevelSwitch));
-
- QString compLevelSwitch = m_param.value(CompressionLevelSwitch).toString();
- Q_ASSERT(!compLevelSwitch.isEmpty());
-
- compLevelSwitch.replace(QLatin1String("$CompressionLevel"), QString::number(level));
-
- return compLevelSwitch;
-}
-
-QString CliInterface::compressionMethodSwitch(const QString &method) const
-{
- if (method.isEmpty()) {
- return QString();
- }
-
- Q_ASSERT(m_param.contains(CompressionMethodSwitch));
- QString compMethodSwitch = m_param.value(CompressionMethodSwitch).toString();
- Q_ASSERT(!compMethodSwitch.isEmpty());
-
- compMethodSwitch.replace(QLatin1String("$CompressionMethod"), method);
-
- return compMethodSwitch;
-}
-
-QString CliInterface::multiVolumeSwitch(ulong volumeSize) const
-{
- // The maximum value we allow in the QDoubleSpinBox is 1000MB. Converted to
- // KB this is 1024000.
- if (volumeSize <= 0 || volumeSize > 1024000) {
- return QString();
- }
-
- Q_ASSERT(m_param.contains(MultiVolumeSwitch));
-
- QString multiVolumeSwitch = m_param.value(MultiVolumeSwitch).toString();
- Q_ASSERT(!multiVolumeSwitch.isEmpty());
-
- multiVolumeSwitch.replace(QLatin1String("$VolumeSize"), QString::number(volumeSize));
-
- return multiVolumeSwitch;
-}
-
QStringList CliInterface::extractFilesList(const QVector<Archive::Entry*> &entries) const
{
QStringList filesList;
@@ -1163,14 +787,14 @@ void CliInterface::readStdout(bool handleAll)
// TODO: The same check methods are called in handleLine(), this
// is suboptimal.
- bool wrongPasswordMessage = checkForErrorMessage(QLatin1String( lines.last() ), WrongPasswordPatterns);
+ bool wrongPasswordMessage = m_cliProps->isWrongPasswordMsg(QLatin1String(lines.last()));
bool foundErrorMessage =
(wrongPasswordMessage ||
- checkForErrorMessage(QLatin1String(lines.last()), DiskFullPatterns) ||
- checkForErrorMessage(QLatin1String(lines.last()), ExtractionFailedPatterns) ||
- checkForPasswordPromptMessage(QLatin1String(lines.last())) ||
- checkForErrorMessage(QLatin1String(lines.last()), FileExistsExpression));
+ m_cliProps->isDiskFullMsg(QLatin1String(lines.last())) ||
+ m_cliProps->isExtractionFailedMsg(QLatin1String(lines.last())) ||
+ m_cliProps->isfileExistsMsg(QLatin1String(lines.last()))) ||
+ m_cliProps->isPasswordPrompt(QLatin1String(lines.last()));
if (foundErrorMessage) {
handleAll = true;
@@ -1226,7 +850,7 @@ bool CliInterface::handleLine(const QString& line)
{
// TODO: This should be implemented by each plugin; the way progress is
// shown by each CLI application is subject to a lot of variation.
- if ((m_operationMode == Extract || m_operationMode == Add) && m_param.contains(CaptureProgress) && m_param.value(CaptureProgress).toBool()) {
+ if ((m_operationMode == Extract || m_operationMode == Add) && m_cliProps->property("captureProgress").toBool()) {
//read the percentage
int pos = line.indexOf(QLatin1Char( '%' ));
if (pos > 1) {
@@ -1238,7 +862,7 @@ bool CliInterface::handleLine(const QString& line)
if (m_operationMode == Extract) {
- if (checkForPasswordPromptMessage(line)) {
+ if (m_cliProps->isPasswordPrompt(line)) {
qCDebug(ARK) << "Found a password prompt";
Kerfuffle::PasswordNeededQuery query(filename());
@@ -1258,20 +882,20 @@ bool CliInterface::handleLine(const QString& line)
return true;
}
- if (checkForErrorMessage(line, DiskFullPatterns)) {
+ if (m_cliProps->isDiskFullMsg(line)) {
qCWarning(ARK) << "Found disk full message:" << line;
emit error(i18nc("@info", "Extraction failed because the disk is full."));
return false;
}
- if (checkForErrorMessage(line, WrongPasswordPatterns)) {
+ if (m_cliProps->isWrongPasswordMsg(line)) {
qCWarning(ARK) << "Wrong password!";
setPassword(QString());
emit error(i18nc("@info", "Extraction failed: Incorrect password"));
return false;
}
- if (checkForErrorMessage(line, ExtractionFailedPatterns)) {
+ if (m_cliProps->isExtractionFailedMsg(line)) {
qCWarning(ARK) << "Error in extraction:" << line;
emit error(i18n("Extraction failed because of an unexpected error."));
return false;
@@ -1283,7 +907,7 @@ bool CliInterface::handleLine(const QString& line)
}
if (m_operationMode == List) {
- if (checkForPasswordPromptMessage(line)) {
+ if (m_cliProps->isPasswordPrompt(line)) {
qCDebug(ARK) << "Found a password prompt";
Kerfuffle::PasswordNeededQuery query(filename());
@@ -1303,20 +927,20 @@ bool CliInterface::handleLine(const QString& line)
return true;
}
- if (checkForErrorMessage(line, WrongPasswordPatterns)) {
+ if (m_cliProps->isWrongPasswordMsg(line)) {
qCWarning(ARK) << "Wrong password!";
setPassword(QString());
emit error(i18n("Incorrect password."));
return false;
}
- if (checkForErrorMessage(line, ExtractionFailedPatterns)) {
+ if (m_cliProps->isExtractionFailedMsg(line)) {
qCWarning(ARK) << "Error in extraction!!";
emit error(i18n("Extraction failed because of an unexpected error."));
return false;
}
- if (checkForErrorMessage(line, CorruptArchivePatterns)) {
+ if (m_cliProps->isCorruptArchiveMsg(line)) {
qCWarning(ARK) << "Archive corrupt";
setCorrupt(true);
// Special case: corrupt is not a "fatal" error so we return true here.
@@ -1332,14 +956,14 @@ bool CliInterface::handleLine(const QString& line)
if (m_operationMode == Test) {
- if (checkForPasswordPromptMessage(line)) {
+ if (m_cliProps->isPasswordPrompt(line)) {
qCDebug(ARK) << "Found a password prompt";
emit error(i18n("Ark does not currently support testing this archive."));
return false;
}
- if (checkForTestSuccessMessage(line)) {
+ if (m_cliProps->isTestPassedMsg(line)) {
qCDebug(ARK) << "Test successful";
emit testSuccess();
return true;
@@ -1349,28 +973,10 @@ bool CliInterface::handleLine(const QString& line)
return true;
}
-bool CliInterface::checkForPasswordPromptMessage(const QString& line)
-{
- const QString passwordPromptPattern(m_param.value(PasswordPromptPattern).toString());
-
- if (passwordPromptPattern.isEmpty())
- return false;
-
- if (m_passwordPromptPattern.pattern().isEmpty()) {
- m_passwordPromptPattern.setPattern(m_param.value(PasswordPromptPattern).toString());
- }
-
- if (m_passwordPromptPattern.match(line).hasMatch()) {
- return true;
- }
-
- return false;
-}
-
bool CliInterface::handleFileExistsMessage(const QString& line)
{
// Check for a filename and store it.
- foreach (const QString &pattern, m_param.value(FileExistsFileName).toStringList()) {
+ foreach (const QString &pattern, m_cliProps->property("fileExistsFileName").toStringList()) {
const QRegularExpression rxFileNamePattern(pattern);
const QRegularExpressionMatch rxMatch = rxFileNamePattern.match(line);
@@ -1380,7 +986,7 @@ bool CliInterface::handleFileExistsMessage(const QString& line)
}
}
- if (!checkForErrorMessage(line, FileExistsExpression)) {
+ if (!m_cliProps->isfileExistsMsg(line)) {
return false;
}
@@ -1393,7 +999,7 @@ bool CliInterface::handleFileExistsMessage(const QString& line)
qCDebug(ARK) << "Finished response";
QString responseToProcess;
- const QStringList choices = m_param.value(FileExistsInput).toStringList();
+ const QStringList choices = m_cliProps->property("fileExistsInput").toStringList();
if (query.responseOverwrite()) {
responseToProcess = choices.at(0);
@@ -1419,41 +1025,6 @@ bool CliInterface::handleFileExistsMessage(const QString& line)
return true;
}
-bool CliInterface::checkForErrorMessage(const QString& line, int parameterIndex)
-{
- QList<QRegularExpression> patterns;
-
- if (m_patternCache.contains(parameterIndex)) {
- patterns = m_patternCache.value(parameterIndex);
- } else {
- if (!m_param.contains(parameterIndex)) {
- return false;
- }
-
- foreach(const QString& rawPattern, m_param.value(parameterIndex).toStringList()) {
- patterns << QRegularExpression(rawPattern);
- }
- m_patternCache[parameterIndex] = patterns;
- }
-
- foreach(const QRegularExpression& pattern, patterns) {
- if (pattern.match(line).hasMatch()) {
- return true;
- }
- }
- return false;
-}
-
-bool CliInterface::checkForTestSuccessMessage(const QString& line)
-{
- const QRegularExpression rx(m_param.value(TestPassedPattern).toString());
- const QRegularExpressionMatch rxMatch = rx.match(line);
- if (rxMatch.hasMatch()) {
- return true;
- }
- return false;
-}
-
bool CliInterface::doKill()
{
if (m_process) {
@@ -1508,8 +1079,6 @@ void CliInterface::writeToProcess(const QByteArray& data)
bool CliInterface::addComment(const QString &comment)
{
- cacheParameterList();
-
m_operationMode = Comment;
m_commentTempFile = new QTemporaryFile;
@@ -1523,10 +1092,8 @@ bool CliInterface::addComment(const QString &comment)
stream << comment << endl;
m_commentTempFile->close();
- const auto args = substituteCommentVariables(m_param.value(CommentArgs).toStringList(),
- m_commentTempFile->fileName());
-
- if (!runProcess(m_param.value(AddProgram).toStringList(), args)) {
+ if (!runProcess(m_cliProps->property("addProgram").toString(),
+ m_cliProps->commentArgs(filename(), m_commentTempFile->fileName()))) {
return false;
}
m_comment = comment;
@@ -1538,7 +1105,7 @@ QString CliInterface::multiVolumeName() const
QString oldSuffix = QMimeDatabase().suffixForFileName(filename());
QString name;
- foreach (const QString &multiSuffix, m_param.value(MultiVolumeSuffix).toStringList()) {
+ foreach (const QString &multiSuffix, m_cliProps->property("multiVolumeSuffix").toStringList()) {
QString newSuffix = multiSuffix;
newSuffix.replace(QStringLiteral("$Suffix"), oldSuffix);
name = filename().remove(oldSuffix).append(newSuffix);
@@ -1549,4 +1116,9 @@ QString CliInterface::multiVolumeName() const
return name;
}
+CliProperties *CliInterface::cliProperties() const
+{
+ return m_cliProps;
+}
+
}
diff --git a/kerfuffle/cliinterface.h b/kerfuffle/cliinterface.h
index e74775a..bc7bb64 100644
--- a/kerfuffle/cliinterface.h
+++ b/kerfuffle/cliinterface.h
@@ -31,6 +31,7 @@
#include "archiveinterface.h"
#include "archiveentry.h"
+#include "cliproperties.h"
#include "kerfuffle_export.h"
#include "part/archivemodel.h"
@@ -47,252 +48,6 @@ class QTemporaryFile;
namespace Kerfuffle
{
-enum CliInterfaceParameters {
-
- ///////////////[ COMMON ]/////////////
-
- /**
- * Bool (default false)
- * Will look for the %-sign in the stdout while working, in the form of
- * (2%, 14%, 35%, etc etc), and report progress based upon this
- */
- CaptureProgress = 0,
-
- /**
- * QString
- * Default: empty
- * A regexp pattern that matches the program's password prompt.
- */
- PasswordPromptPattern,
-
- ///////////////[ LIST ]/////////////
-
- /**
- * QStringList
- * The names to the program that will handle listing of this
- * archive (eg "rar"). Will be searched for in PATH
- */
- ListProgram,
- /**
- * QStringList
- * The arguments that are passed to the program above for
- * listing the archive. Special strings that will be
- * substituted:
- * $Archive - the path of the archive
- */
- ListArgs,
- /**
- * QStringList (default empty)
- * List of regexp patterns that indicate a corrupt archive.
- */
- CorruptArchivePatterns,
-
- ///////////////[ EXTRACT ]/////////////
-
- /**
- * QStringList
- * The names to the program that will handle extracting of this
- * archive (eg "rar"). Will be searched for in PATH
- */
- ExtractProgram,
- /**
- * QStringList
- * The arguments that are passed to the program above for
- * extracting the archive. Special strings that will be
- * substituted:
- * $Archive - the path of the archive
- * $Files - the files selected to be extracted, if any
- * $PreservePathSwitch - the flag for extracting with full paths
- * $PasswordSwitch - the switch setting the password. Note that this
- * will not be inserted unless the listing function has emitted an
- * entry with the IsPasswordProtected property set to true.
- */
- ExtractArgs,
- /**
- * Bool (default false)
- * When passing directories to the extract program, do not
- * include trailing slashes
- * e.g. if the user selected "foo/" and "foo/bar" in the gui, the
- * paths "foo" and "foo/bar" will be sent to the program.
- */
- NoTrailingSlashes,
- /**
- * QStringList
- * This should be a qstringlist with either two elements. The first
- * string is what PreservePathSwitch in the ExtractArgs will be replaced
- * with if PreservePath is True/enabled. The second is for the disabled
- * case. An empty string means that the argument will not be used in
- * that case.
- * Example: for rar, "x" means extract with full paths, and "e" means
- * extract without full paths. in this case we will use the stringlist
- * ("x", "e"). Or, for another format that might use the switch
- * "--extractFull" for preservePaths, and nothing otherwise: we use the
- * stringlist ("--extractFull", "")
- */
- PreservePathSwitch,
- /**
- * QStringList (default empty)
- * The format of the root node switch. The variable $Password will be
- * substituted for the password string. NOTE: supplying passwords
- * through a virtual terminal is not supported (yet?), because this
- * is not cross platform compatible. As of KDE 4.3 there are no plans to
- * change this.
- * Example: ("-p$Password)
- * or ("--password", "$Password")
- */
- PasswordSwitch,
- /**
- * QString
- * The format of the compression level switch. The variable $CompressionLevel
- * will be substituted for the level.
- * Example: ("-mx=$CompressionLevel)
- */
- CompressionLevelSwitch,
- /**
- * QStringList
- * This is a stringlist with regexps, defining how to recognize the last
- * line in a "File already exists" prompt when extracting.
- */
- FileExistsExpression,
- /**
- * QStringList
- * This is a stringlist with regexps defining how to recognize the line
- * containing the filename in a "File already exists" prompt when
- * extracting. It should have one captured string, which is the filename
- * of the file/folder that already exists.
- */
- FileExistsFileName,
- /**
- * int
- * This sets on what output channel the FileExistsExpression regex
- * should be applied on, in other words, on what stream the "file
- * exists" output will appear in. Values accepted:
- * 0 - Standard error, stderr (default)
- * 1 - Standard output, stdout
- */
- FileExistsMode,
- /**
- * QStringList
- * The various responses that can be supplied as a response to the
- * "file exists" prompt. The various items are to be supplied in the
- * following order:
- * index 0 - Yes (overwrite)
- * index 1 - No (skip/do not overwrite)
- * index 2 - All (overwrite all)
- * index 3 - Do not overwrite any files (autoskip)
- * index 4 - Cancel operation
- */
- FileExistsInput,
- /**
- * QStringList
- * Regexp patterns capturing disk is full error messages.
- */
- DiskFullPatterns,
-
- ///////////////[ DELETE ]/////////////
-
- /**
- * QStringList
- * The names to the program that will handle deleting of elements in this
- * archive format (eg "rar"). Will be searched for in PATH
- */
- DeleteProgram,
- /**
- * QStringList
- * The arguments that are passed to the program above for
- * deleting from the archive. Special strings that will be
- * substituted:
- * $Archive - the path of the archive
- * $Files - the files selected to be deleted
- */
- DeleteArgs,
- /**
- * QStringList
- * Default: empty
- * A list of regexp patterns that will cause the extraction to exit
- * with a general fail message
- */
- ExtractionFailedPatterns,
- /**
- * QStringList
- * Default: empty
- * A list of regexp patterns that will alert the user that the password
- * was wrong.
- */
- WrongPasswordPatterns,
-
- ///////////////[ ADD ]/////////////
-
- /**
- * QStringList
- * The names to the program that will handle adding in this
- * archive format (eg "rar"). Will be searched for in PATH
- */
- AddProgram,
- /**
- * QStringList
- * The arguments that are passed to the program above for
- * adding to the archive. Special strings that will be
- * substituted:
- * $Archive - the path of the archive
- * $Files - the files selected to be added
- */
- AddArgs,
-
- ///////////////[ MOVE ]/////////////
-
- /**
- * QStringList
- * The names to the program that will handle adding in this
- * archive format (eg "rar"). Will be searched for in PATH
- */
- MoveProgram,
- /**
- * QStringList
- * The arguments that are passed to the program above for
- * moving inside the archive. Special strings that will be
- * substituted:
- * $Archive - the path of the archive
- * $Files - the files selected to be moved
- * $Destinations - new path of each file selected to be moved
- */
- MoveArgs,
-
- ///////////////[ ENCRYPT ]/////////////
-
- /**
- * QStringList (default empty)
- * The variable $Password will be
- * substituted for the password string used to encrypt the header.
- * Example (rar plugin): ("-hp$Password")
- */
- PasswordHeaderSwitch,
-
- ///////////////[ COMMENT ]/////////////
-
- /**
- * QStringList
- * The arguments that are passed to AddProgram when adding
- * a comment.
- */
- CommentArgs,
- /**
- * QString
- * The variable $CommentFile will be substituted for the file
- * containing the comment.
- * Example (rar plugin): -z$CommentFile
- */
- CommentSwitch,
- TestProgram,
- TestArgs,
- TestPassedPattern,
- MultiVolumeSwitch,
- MultiVolumeSuffix,
- CompressionMethodSwitch
-};
-
-typedef QHash<int, QVariant> ParameterList;
-
class KERFUFFLE_EXPORT CliInterface : public ReadWriteArchiveInterface
{
Q_OBJECT
@@ -315,7 +70,6 @@ public:
virtual bool testArchive() Q_DECL_OVERRIDE;
virtual void resetParsing() = 0;
- virtual ParameterList parameterList() const = 0;
virtual bool readListLine(const QString &line) = 0;
bool doKill() Q_DECL_OVERRIDE;
bool doSuspend() Q_DECL_OVERRIDE;
@@ -334,49 +88,20 @@ public:
*/
bool moveToDestination(const QDir &tempDir, const QDir &destDir, bool preservePaths);
- QStringList substituteListVariables(const QStringList &listArgs, const QString &password);
- QStringList substituteExtractVariables(const QStringList &extractArgs, const QVector<Archive::Entry*> &entries, bool preservePaths, const QString &password);
- QStringList substituteAddVariables(const QStringList &addArgs, const QVector<Archive::Entry*> &entries, const QString &password, bool encryptHeader, int compLevel, ulong volumeSize, QString compMethod);
- QStringList substituteMoveVariables(const QStringList &moveArgs, const QVector<Archive::Entry*> &entriesWithoutChildren, const Archive::Entry *destination, const QString &password);
- QStringList substituteDeleteVariables(const QStringList &deleteArgs, const QVector<Archive::Entry*> &entries, const QString &password);
- QStringList substituteCommentVariables(const QStringList &commentArgs, const QString &commentFile);
- QStringList substituteTestVariables(const QStringList &testArgs, const QString &password);
-
/**
* @see ArchiveModel::entryPathsFromDestination
*/
void setNewMovedFiles(const QVector<Archive::Entry*> &entries, const Archive::Entry *destination, int entriesWithoutChildren);
/**
- * @return The preserve path switch, according to the @p preservePaths extraction option.
- */
- QString preservePathSwitch(bool preservePaths) const;
-
- /**
- * @return The password header-switch with the given @p password.
- */
- virtual QStringList passwordHeaderSwitch(const QString& password) const;
-
- /**
- * @return The password switch with the given @p password.
- */
- QStringList passwordSwitch(const QString& password) const;
-
- /**
- * @return The compression level switch with the given @p level.
- */
- QString compressionLevelSwitch(int level) const;
-
- virtual QString compressionMethodSwitch(const QString &method) const;
- QString multiVolumeSwitch(ulong volumeSize) const;
-
- /**
* @return The list of selected files to extract.
*/
QStringList extractFilesList(const QVector<Archive::Entry*> &files) const;
QString multiVolumeName() const Q_DECL_OVERRIDE;
+ CliProperties *cliProperties() const;
+
protected:
bool setAddedFiles();
@@ -388,23 +113,6 @@ protected:
*/
virtual bool handleLine(const QString& line);
- bool checkForErrorMessage(const QString& line, int parameterIndex);
-
- /**
- * Checks whether a line of the program's output is a password prompt.
- *
- * It uses the regular expression in the @c PasswordPromptPattern parameter
- * for the check.
- *
- * @param line A line of the program's output.
- *
- * @return @c true if the given @p line is a password prompt, @c false
- * otherwise.
- */
- bool checkForPasswordPromptMessage(const QString& line);
-
- virtual void cacheParameterList();
-
/**
* Run @p programName with the given @p arguments.
*
@@ -414,7 +122,7 @@ protected:
* @return @c true if the program was found and the process was started correctly,
* @c false otherwise (in which case finished(false) is emitted).
*/
- bool runProcess(const QStringList& programNames, const QStringList& arguments);
+ bool runProcess(const QString& programName, const QStringList& arguments);
/**
* Kill the running process. The finished signal is emitted according to @p emitFinished.
@@ -429,6 +137,7 @@ protected:
void cleanUp();
+ CliProperties *m_cliProps;
QString m_oldWorkingDir;
QTemporaryDir *m_tempExtractDir;
QTemporaryDir *m_tempAddDir;
@@ -438,8 +147,6 @@ protected:
Archive::Entry *m_passedDestination;
CompressionOptions m_passedOptions;
- ParameterList m_param;
-
#ifdef Q_OS_WIN
KProcess *m_process;
#else
@@ -454,17 +161,6 @@ protected slots:
private:
bool handleFileExistsMessage(const QString& filename);
- bool checkForTestSuccessMessage(const QString& line);
-
- /**
- * Performs any additional escaping and processing on @p fileName
- * before passing it to the underlying process.
- *
- * The default implementation returns @p fileName unchanged.
- *
- * @param fileName String to escape.
- */
- virtual QString escapeFileName(const QString &fileName) const;
/**
* Returns a list of path pairs which will be supplied to rn command.
@@ -489,6 +185,16 @@ private:
*/
bool isEmptyDir(const QDir &dir);
+ /**
+ * Performs any additional escaping and processing on @p fileName
+ * before passing it to the underlying process.
+ *
+ * The default implementation returns @p fileName unchanged.
+ *
+ * @param fileName String to escape.
+ */
+ virtual QString escapeFileName(const QString &fileName) const;
+
void cleanUpExtracting();
void finishCopying(bool result);
diff --git a/kerfuffle/cliproperties.cpp b/kerfuffle/cliproperties.cpp
new file mode 100644
index 0000000..b9afd0f
--- /dev/null
+++ b/kerfuffle/cliproperties.cpp
@@ -0,0 +1,342 @@
+/*
+ * ark -- archiver for the KDE project
+ *
+ * Copyright (C) 2016 Ragnar Thomsen <rthomsen6@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cliproperties.h"
+#include "ark_debug.h"
+#include "archiveformat.h"
+#include "pluginmanager.h"
+
+namespace Kerfuffle
+{
+
+CliProperties::CliProperties(QObject *parent, const KPluginMetaData &metaData, const QMimeType &archiveType)
+ : QObject(parent)
+ , m_mimeType(archiveType)
+ , m_metaData(metaData)
+{
+}
+
+QStringList CliProperties::addArgs(const QString &archive, const QStringList &files, const QString &password, bool headerEncryption, int compressionLevel, const QString &compressionMethod, uint volumeSize)
+{
+ QStringList args;
+ foreach (const QString &s, m_addSwitch) {
+ args << s;
+ }
+ if (!password.isEmpty()) {
+ args << substitutePasswordSwitch(password, headerEncryption);
+ }
+ if (compressionLevel > -1) {
+ args << substituteCompressionLevelSwitch(compressionLevel);
+ }
+ if (!compressionMethod.isEmpty()) {
+ args << substituteCompressionMethodSwitch(compressionMethod);
+ }
+ if (volumeSize > 0) {
+ args << substituteMultiVolumeSwitch(volumeSize);
+ }
+ args << archive;
+ args << files;
+
+ args.removeAll(QString());
+ return args;
+}
+
+QStringList CliProperties::commentArgs(const QString &archive, const QString &commentfile)
+{
+ QStringList args;
+ foreach (const QString &s, substituteCommentSwitch(commentfile)) {
+ args << s;
+ }
+ args << archive;
+
+ args.removeAll(QString());
+ return args;
+}
+
+QStringList CliProperties::deleteArgs(const QString &archive, const QVector<Archive::Entry*> &files, const QString &password)
+{
+ QStringList args;
+ args << m_deleteSwitch;
+ if (!password.isEmpty()) {
+ args << substitutePasswordSwitch(password);
+ }
+ args << archive;
+ foreach (const Archive::Entry *e, files) {
+ args << e->fullPath(NoTrailingSlash);
+ }
+
+ args.removeAll(QString());
+ return args;
+}
+
+QStringList CliProperties::extractArgs(const QString &archive, const QStringList &files, bool preservePaths, const QString &password)
+{
+ QStringList args;
+
+ if (preservePaths && !m_extractSwitch.isEmpty()) {
+ args << m_extractSwitch;
+ } else if (!preservePaths && !m_extractSwitchNoPreserve.isEmpty()) {
+ args << m_extractSwitchNoPreserve;
+ }
+
+ if (!password.isEmpty()) {
+ args << substitutePasswordSwitch(password);
+ }
+ args << archive;
+ args << files;
+
+ args.removeAll(QString());
+ return args;
+}
+
+QStringList CliProperties::listArgs(const QString &archive, const QString &password)
+{
+ QStringList args;
+ foreach (const QString &s, m_listSwitch) {
+ args << s;
+ }
+ if (!password.isEmpty()) {
+ args << substitutePasswordSwitch(password);
+ }
+ args << archive;
+
+ args.removeAll(QString());
+ return args;
+}
+
+QStringList CliProperties::moveArgs(const QString &archive, const QVector<Archive::Entry*> &entries, Archive::Entry *destination, const QString &password)
+{
+ QStringList args;
+ args << m_moveSwitch;
+ if (!password.isEmpty()) {
+ args << substitutePasswordSwitch(password);
+ }
+ args << archive;
+ if (entries.count() > 1) {
+ foreach (const Archive::Entry *file, entries) {
+ args << file->fullPath(NoTrailingSlash) << destination->fullPath() + file->name();
+ }
+ } else {
+ args << entries.at(0)->fullPath(NoTrailingSlash) << destination->fullPath(NoTrailingSlash);
+ }
+
+ args.removeAll(QString());
+ return args;
+}
+
+QStringList CliProperties::testArgs(const QString &archive, const QString &password)
+{
+ QStringList args;
+ foreach (const QString &s, m_testSwitch) {
+ args << s;
+ }
+ if (!password.isEmpty()) {
+ args << substitutePasswordSwitch(password);
+ }
+ args << archive;
+
+ args.removeAll(QString());
+ return args;
+}
+
+QStringList CliProperties::substituteCommentSwitch(const QString &commentfile) const
+{
+ Q_ASSERT(!commentfile.isEmpty());
+
+ Q_ASSERT(ArchiveFormat::fromMetadata(m_mimeType, m_metaData).supportsWriteComment());
+
+ QStringList commentSwitches = m_commentSwitch;
+ Q_ASSERT(!commentSwitches.isEmpty());
+
+ QMutableListIterator<QString> i(commentSwitches);
+ while (i.hasNext()) {
+ i.next();
+ i.value().replace(QLatin1String("$CommentFile"), commentfile);
+ }
+
+ return commentSwitches;
+}
+
+QStringList CliProperties::substitutePasswordSwitch(const QString &password, bool headerEnc) const
+{
+ if (password.isEmpty()) {
+ return QStringList();
+ }
+
+ Archive::EncryptionType encryptionType = ArchiveFormat::fromMetadata(m_mimeType, m_metaData).encryptionType();
+ Q_ASSERT(encryptionType != Archive::EncryptionType::Unencrypted);
+
+ QStringList passwordSwitch;
+ if (headerEnc) {
+ passwordSwitch = m_passwordSwitchHeaderEnc;
+ } else {
+ passwordSwitch = m_passwordSwitch;
+ }
+ Q_ASSERT(!passwordSwitch.isEmpty());
+
+ QMutableListIterator<QString> i(passwordSwitch);
+ while (i.hasNext()) {
+ i.next();
+ i.value().replace(QLatin1String("$Password"), password);
+ }
+
+ return passwordSwitch;
+}
+
+QString CliProperties::substituteCompressionLevelSwitch(int level) const
+{
+ if (level < 0 || level > 9) {
+ return QString();
+ }
+
+ Q_ASSERT(ArchiveFormat::fromMetadata(m_mimeType, m_metaData).maxCompressionLevel() != -1);
+
+ QString compLevelSwitch = m_compressionLevelSwitch;
+ Q_ASSERT(!compLevelSwitch.isEmpty());
+
+ compLevelSwitch.replace(QLatin1String("$CompressionLevel"), QString::number(level));
+
+ return compLevelSwitch;
+}
+
+QString CliProperties::substituteCompressionMethodSwitch(const QString &method) const
+{
+ if (method.isEmpty()) {
+ return QString();
+ }
+
+ Q_ASSERT(!ArchiveFormat::fromMetadata(m_mimeType, m_metaData).compressionMethods().isEmpty());
+
+ QString compMethodSwitch = m_compressionMethodSwitch[m_mimeType.name()].toString();
+ Q_ASSERT(!compMethodSwitch.isEmpty());
+
+ QString cliMethod = ArchiveFormat::fromMetadata(m_mimeType, m_metaData).compressionMethods().value(method).toString();
+
+ compMethodSwitch.replace(QLatin1String("$CompressionMethod"), cliMethod);
+
+ return compMethodSwitch;
+}
+
+QString CliProperties::substituteMultiVolumeSwitch(uint volumeSize) const
+{
+ // The maximum value we allow in the QDoubleSpinBox is 1000MB. Converted to
+ // KB this is 1024000.
+ if (volumeSize <= 0 || volumeSize > 1024000) {
+ return QString();
+ }
+
+ Q_ASSERT(ArchiveFormat::fromMetadata(m_mimeType, m_metaData).supportsMultiVolume());
+
+ QString multiVolumeSwitch = m_multiVolumeSwitch;
+ Q_ASSERT(!multiVolumeSwitch.isEmpty());
+
+ multiVolumeSwitch.replace(QLatin1String("$VolumeSize"), QString::number(volumeSize));
+
+ return multiVolumeSwitch;
+}
+
+bool CliProperties::isPasswordPrompt(const QString &line)
+{
+ foreach(const QString &rx, m_passwordPromptPatterns) {
+ if (QRegularExpression(rx).match(line).hasMatch()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool CliProperties::isWrongPasswordMsg(const QString &line)
+{
+ foreach(const QString &rx, m_wrongPasswordPatterns) {
+ if (QRegularExpression(rx).match(line).hasMatch()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool CliProperties::isTestPassedMsg(const QString &line)
+{
+ foreach(const QString &rx, m_testPassedPatterns) {
+ if (QRegularExpression(rx).match(line).hasMatch()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool CliProperties::isfileExistsMsg(const QString &line)
+{
+ foreach(const QString &rx, m_fileExistsPatterns) {
+ if (QRegularExpression(rx).match(line).hasMatch()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool CliProperties::isFileExistsFileName(const QString &line)
+{
+ foreach(const QString &rx, m_fileExistsFileName) {
+ if (QRegularExpression(rx).match(line).hasMatch()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool CliProperties::isExtractionFailedMsg(const QString &line)
+{
+ foreach(const QString &rx, m_extractionFailedPatterns) {
+ if (QRegularExpression(rx).match(line).hasMatch()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool CliProperties::isCorruptArchiveMsg(const QString &line)
+{
+ foreach(const QString &rx, m_corruptArchivePatterns) {
+ if (QRegularExpression(rx).match(line).hasMatch()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool CliProperties::isDiskFullMsg(const QString &line)
+{
+ foreach(const QString &rx, m_diskFullPatterns) {
+ if (QRegularExpression(rx).match(line).hasMatch()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+}
diff --git a/kerfuffle/cliproperties.h b/kerfuffle/cliproperties.h
new file mode 100644
index 0000000..0716e62
--- /dev/null
+++ b/kerfuffle/cliproperties.h
@@ -0,0 +1,152 @@
+/*
+ * ark -- archiver for the KDE project
+ *
+ * Copyright (C) 2016 Ragnar Thomsen <rthomsen6@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef CLIPROPERTIES_H
+#define CLIPROPERTIES_H
+
+#include "archiveinterface.h"
+#include "kerfuffle_export.h"
+
+#include <QRegularExpression>
+
+namespace Kerfuffle
+{
+
+class KERFUFFLE_EXPORT CliProperties: public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString addProgram MEMBER m_addProgram)
+ Q_PROPERTY(QString deleteProgram MEMBER m_deleteProgram)
+ Q_PROPERTY(QString extractProgram MEMBER m_extractProgram)
+ Q_PROPERTY(QString listProgram MEMBER m_listProgram)
+ Q_PROPERTY(QString moveProgram MEMBER m_moveProgram)
+ Q_PROPERTY(QString testProgram MEMBER m_testProgram)
+
+ Q_PROPERTY(QStringList addSwitch MEMBER m_addSwitch)
+ Q_PROPERTY(QStringList commentSwitch MEMBER m_commentSwitch)
+ Q_PROPERTY(QString deleteSwitch MEMBER m_deleteSwitch)
+ Q_PROPERTY(QStringList extractSwitch MEMBER m_extractSwitch)
+ Q_PROPERTY(QStringList extractSwitchNoPreserve MEMBER m_extractSwitchNoPreserve)
+ Q_PROPERTY(QStringList listSwitch MEMBER m_listSwitch)
+ Q_PROPERTY(QString moveSwitch MEMBER m_moveSwitch)
+ Q_PROPERTY(QStringList testSwitch MEMBER m_testSwitch)
+
+ Q_PROPERTY(QStringList passwordSwitch MEMBER m_passwordSwitch)
+ Q_PROPERTY(QStringList passwordSwitchHeaderEnc MEMBER m_passwordSwitchHeaderEnc)
+ Q_PROPERTY(QString compressionLevelSwitch MEMBER m_compressionLevelSwitch)
+ Q_PROPERTY(QHash<QString,QVariant> compressionMethodSwitch MEMBER m_compressionMethodSwitch)
+ Q_PROPERTY(QString multiVolumeSwitch MEMBER m_multiVolumeSwitch)
+
+ Q_PROPERTY(QStringList passwordPromptPatterns MEMBER m_passwordPromptPatterns)
+ Q_PROPERTY(QStringList wrongPasswordPatterns MEMBER m_wrongPasswordPatterns)
+ Q_PROPERTY(QStringList testPassedPatterns MEMBER m_testPassedPatterns)
+ Q_PROPERTY(QStringList fileExistsPatterns MEMBER m_fileExistsPatterns)
+ Q_PROPERTY(QStringList fileExistsFileName MEMBER m_fileExistsFileName)
+ Q_PROPERTY(QStringList extractionFailedPatterns MEMBER m_extractionFailedPatterns)
+ Q_PROPERTY(QStringList corruptArchivePatterns MEMBER m_corruptArchivePatterns)
+ Q_PROPERTY(QStringList diskFullPatterns MEMBER m_diskFullPatterns)
+
+ Q_PROPERTY(QStringList fileExistsInput MEMBER m_fileExistsInput)
+ Q_PROPERTY(QStringList multiVolumeSuffix MEMBER m_multiVolumeSuffix)
+
+ Q_PROPERTY(bool captureProgress MEMBER m_captureProgress)
+
+public:
+ explicit CliProperties(QObject *parent, const KPluginMetaData &metaData, const QMimeType &archiveType);
+
+ QStringList addArgs(const QString &archive,
+ const QStringList &files,
+ const QString &password,
+ bool headerEncryption,
+ int compressionLevel,
+ const QString &compressionMethod,
+ uint volumeSize);
+ QStringList commentArgs(const QString &archive, const QString &commentfile);
+ QStringList deleteArgs(const QString &archive, const QVector<Archive::Entry*> &files, const QString &password);
+ QStringList extractArgs(const QString &archive, const QStringList &files, bool preservePaths, const QString &password);
+ QStringList listArgs(const QString &archive, const QString &password);
+ QStringList moveArgs(const QString &archive, const QVector<Archive::Entry *> &entries, Archive::Entry *destination, const QString &password);
+ QStringList testArgs(const QString &archive, const QString &password);
+
+ bool isPasswordPrompt(const QString &line);
+ bool isWrongPasswordMsg(const QString &line);
+ bool isTestPassedMsg(const QString &line);
+ bool isfileExistsMsg(const QString &line);
+ bool isFileExistsFileName(const QString &line);
+ bool isExtractionFailedMsg(const QString &line);
+ bool isCorruptArchiveMsg(const QString &line);
+ bool isDiskFullMsg(const QString &line);
+
+private:
+ QStringList substituteCommentSwitch(const QString &commentfile) const;
+ QStringList substitutePasswordSwitch(const QString &password, bool headerEnc = false) const;
+ QString substituteCompressionLevelSwitch(int level) const;
+ QString substituteCompressionMethodSwitch(const QString &method) const;
+ QString substituteMultiVolumeSwitch(uint volumeSize) const;
+
+ QString m_addProgram;
+ QString m_deleteProgram;
+ QString m_extractProgram;
+ QString m_listProgram;
+ QString m_moveProgram;
+ QString m_testProgram;
+
+ QStringList m_addSwitch;
+ QStringList m_commentSwitch;
+ QString m_deleteSwitch;
+ QStringList m_extractSwitch;
+ QStringList m_extractSwitchNoPreserve;
+ QStringList m_listSwitch;
+ QString m_moveSwitch;
+ QStringList m_testSwitch;
+
+ QStringList m_passwordSwitch;
+ QStringList m_passwordSwitchHeaderEnc;
+ QString m_compressionLevelSwitch;
+ QHash<QString,QVariant> m_compressionMethodSwitch;
+ QString m_multiVolumeSwitch;
+
+ QStringList m_passwordPromptPatterns;
+ QStringList m_wrongPasswordPatterns;
+ QStringList m_testPassedPatterns;
+ QStringList m_fileExistsPatterns;
+ QStringList m_fileExistsFileName;
+ QStringList m_extractionFailedPatterns;
+ QStringList m_corruptArchivePatterns;
+ QStringList m_diskFullPatterns;
+
+ QStringList m_fileExistsInput;
+ QStringList m_multiVolumeSuffix;
+
+ bool m_captureProgress;
+
+ QMimeType m_mimeType;
+ KPluginMetaData m_metaData;
+};
+}
+
+#endif /* CLIPROPERTIES_H */
diff --git a/kerfuffle/compressionoptionswidget.cpp b/kerfuffle/compressionoptionswidget.cpp
index 29b5b49..e3189d1 100644
--- a/kerfuffle/compressionoptionswidget.cpp
+++ b/kerfuffle/compressionoptionswidget.cpp
@@ -173,7 +173,7 @@ void CompressionOptionsWidget::updateWidgets()
compMethodComboBox->setEnabled(true);
compMethodComboBox->setToolTip(QString());
compMethodComboBox->clear();
- compMethodComboBox->insertItems(0, archiveFormat.compressionMethods());
+ compMethodComboBox->insertItems(0, archiveFormat.compressionMethods().keys());
if (!m_opts.compressionMethod().isEmpty() &&
compMethodComboBox->findText(m_opts.compressionMethod()) > -1) {
compMethodComboBox->setCurrentText(m_opts.compressionMethod());
diff --git a/plugins/cli7zplugin/cliplugin.cpp b/plugins/cli7zplugin/cliplugin.cpp
index 8ca99a1..4d5d6cb 100644
--- a/plugins/cli7zplugin/cliplugin.cpp
+++ b/plugins/cli7zplugin/cliplugin.cpp
@@ -44,6 +44,8 @@ CliPlugin::CliPlugin(QObject *parent, const QVariantList & args)
, m_isFirstInformationEntry(true)
{
qCDebug(ARK) << "Loaded cli_7z plugin";
+
+ setupCliProperties();
}
CliPlugin::~CliPlugin()
@@ -57,72 +59,60 @@ void CliPlugin::resetParsing()
m_numberOfVolumes = 0;
}
-ParameterList CliPlugin::parameterList() const
+void CliPlugin::setupCliProperties()
{
- static ParameterList p;
-
- if (p.isEmpty()) {
- //p[CaptureProgress] = true;
- p[ListProgram] = p[ExtractProgram] = p[DeleteProgram] = p[MoveProgram] = p[AddProgram] = p[TestProgram] = QStringList() << QStringLiteral("7z");
- p[ListArgs] = QStringList() << QStringLiteral("l")
- << QStringLiteral("-slt")
- << QStringLiteral("$PasswordSwitch")
- << QStringLiteral("$Archive");
- p[ExtractArgs] = QStringList() << QStringLiteral("$PreservePathSwitch")
- << QStringLiteral("$PasswordSwitch")
- << QStringLiteral("$Archive")
- << QStringLiteral("$Files");
- p[PreservePathSwitch] = QStringList() << QStringLiteral("x")
- << QStringLiteral("e");
- p[PasswordSwitch] = QStringList() << QStringLiteral("-p$Password");
- p[PasswordHeaderSwitch] = QStringList { QStringLiteral("-p$Password"), QStringLiteral("-mhe=on") };
- p[WrongPasswordPatterns] = QStringList() << QStringLiteral("Wrong password");
- p[CompressionLevelSwitch] = QStringLiteral("-mx=$CompressionLevel");
- p[AddArgs] = QStringList() << QStringLiteral("a")
- << QStringLiteral("-l")
- << QStringLiteral("$Archive")
- << QStringLiteral("$PasswordSwitch")
- << QStringLiteral("$CompressionLevelSwitch")
- << QStringLiteral("$CompressionMethodSwitch")
- << QStringLiteral("$MultiVolumeSwitch")
- << QStringLiteral("$Files");
- p[MoveArgs] = QStringList() << QStringLiteral("rn")
- << QStringLiteral("$PasswordSwitch")
- << QStringLiteral("$Archive")
- << QStringLiteral("$PathPairs");
- p[DeleteArgs] = QStringList() << QStringLiteral("d")
- << QStringLiteral("$PasswordSwitch")
- << QStringLiteral("$Archive")
- << QStringLiteral("$Files");
- p[TestArgs] = QStringList() << QStringLiteral("t")
- << QStringLiteral("$Archive")
- << QStringLiteral("$PasswordSwitch");
- p[TestPassedPattern] = QStringLiteral("^Everything is Ok$");
-
- p[FileExistsExpression] = QStringList()
- << QStringLiteral("^\\(Y\\)es / \\(N\\)o / \\(A\\)lways / \\(S\\)kip all / A\\(u\\)to rename all / \\(Q\\)uit\\? $")
- << QStringLiteral("^\\? \\(Y\\)es / \\(N\\)o / \\(A\\)lways / \\(S\\)kip all / A\\(u\\)to rename all / \\(Q\\)uit\\? $");
- p[FileExistsFileName] = QStringList() << QStringLiteral("^file \\./(.*)$")
- << QStringLiteral("^ Path: \\./(.*)$");
- p[FileExistsInput] = QStringList() << QStringLiteral("Y") //overwrite
- << QStringLiteral("N") //skip
- << QStringLiteral("A") //overwrite all
- << QStringLiteral("S") //autoskip
- << QStringLiteral("Q"); //cancel
- p[PasswordPromptPattern] = QStringLiteral("Enter password \\(will not be echoed\\)");
- p[ExtractionFailedPatterns] = QStringList() << QStringLiteral("ERROR: E_FAIL") << QStringLiteral("Open ERROR: Can not open the file as \\[7z\\] archive");
- p[CorruptArchivePatterns] = QStringList() << QStringLiteral("Unexpected end of archive")
- << QStringLiteral("Headers Error");
- p[DiskFullPatterns] = QStringList() << QStringLiteral("No space left on device");
- p[MultiVolumeSwitch] = QStringLiteral("-v$VolumeSizek");
- p[MultiVolumeSuffix] = QStringList() << QStringLiteral("$Suffix.001");
- QMap<QString,QVariant> compMethodMap;
- compMethodMap[QStringLiteral("zip")] = QStringLiteral("-mm=$CompressionMethod");
- compMethodMap[QStringLiteral("7z")] = QStringLiteral("-m0=$CompressionMethod");
- p[CompressionMethodSwitch] = compMethodMap;
- }
-
- return p;
+ qCDebug(ARK) << "Setting up parameters...";
+
+ m_cliProps->setProperty("captureProgress", false);
+
+ m_cliProps->setProperty("addProgram", QStringLiteral("7z"));
+ m_cliProps->setProperty("addSwitch", QStringList{QStringLiteral("a"),
+ QStringLiteral("-l")});
+
+ m_cliProps->setProperty("deleteProgram", QStringLiteral("7z"));
+ m_cliProps->setProperty("deleteSwitch", QStringLiteral("d"));
+
+ m_cliProps->setProperty("extractProgram", QStringLiteral("7z"));
+ m_cliProps->setProperty("extractSwitch", QStringList{QStringLiteral("x")});
+ m_cliProps->setProperty("extractSwitchNoPreserve", QStringList{QStringLiteral("e")});
+
+ m_cliProps->setProperty("listProgram", QStringLiteral("7z"));
+ m_cliProps->setProperty("listSwitch", QStringList{QStringLiteral("l"),
+ QStringLiteral("-slt")});
+
+ m_cliProps->setProperty("moveProgram", QStringLiteral("7z"));
+ m_cliProps->setProperty("moveSwitch", QStringLiteral("rn"));
+
+ m_cliProps->setProperty("testProgram", QStringLiteral("7z"));
+ m_cliProps->setProperty("testSwitch", QStringLiteral("t"));
+
+ m_cliProps->setProperty("passwordSwitch", QStringList{QStringLiteral("-p$Password")});
+ m_cliProps->setProperty("passwordSwitchHeaderEnc", QStringList{QStringLiteral("-p$Password"),
+ QStringLiteral("-mhe=on")});
+ m_cliProps->setProperty("compressionLevelSwitch", QStringLiteral("-mx=$CompressionLevel"));
+ m_cliProps->setProperty("compressionMethodSwitch", QHash<QString,QVariant>{{QStringLiteral("application/x-7z-compressed"), QStringLiteral("-m0=$CompressionMethod")},
+ {QStringLiteral("application/zip"), QStringLiteral("-mm=$CompressionMethod")}});
+ m_cliProps->setProperty("multiVolumeSwitch", QStringLiteral("-v$VolumeSizek"));
+
+
+ m_cliProps->setProperty("passwordPromptPatterns", QStringList{QStringLiteral("Enter password \\(will not be echoed\\)")});
+ m_cliProps->setProperty("wrongPasswordPatterns", QStringList{QStringLiteral("Wrong password")});
+ m_cliProps->setProperty("testPassedPatterns", QStringList{QStringLiteral("^Everything is Ok$")});
+ m_cliProps->setProperty("fileExistsPatterns", QStringList{QStringLiteral("^\\(Y\\)es / \\(N\\)o / \\(A\\)lways / \\(S\\)kip all / A\\(u\\)to rename all / \\(Q\\)uit\\? $"),
+ QStringLiteral("^\\? \\(Y\\)es / \\(N\\)o / \\(A\\)lways / \\(S\\)kip all / A\\(u\\)to rename all / \\(Q\\)uit\\? $")});
+ m_cliProps->setProperty("fileExistsFileName", QStringList{QStringLiteral("^file \\./(.*)$"),
+ QStringLiteral("^ Path: \\./(.*)$")});
+ m_cliProps->setProperty("fileExistsInput", QStringList{QStringLiteral("Y"), //Overwrite
+ QStringLiteral("N"), //Skip
+ QStringLiteral("A"), //Overwrite all
+ QStringLiteral("S"), //Autoskip
+ QStringLiteral("Q")}); //Cancel
+ m_cliProps->setProperty("extractionFailedPatterns", QStringList{QStringLiteral("ERROR: E_FAIL"),
+ QStringLiteral("Open ERROR: Can not open the file as \\[7z\\] archive")});
+ m_cliProps->setProperty("corruptArchivePatterns", QStringList{QStringLiteral("Unexpected end of archive"),
+ QStringLiteral("Headers Error")});
+ m_cliProps->setProperty("diskFullPatterns", QStringList{QStringLiteral("No space left on device")});
+ m_cliProps->setProperty("multiVolumeSuffix", QStringList{QStringLiteral("$Suffix.001")});
}
bool CliPlugin::readListLine(const QString& line)
@@ -295,40 +285,4 @@ bool CliPlugin::readListLine(const QString& line)
return true;
}
-QStringList CliPlugin::passwordHeaderSwitch(const QString& password) const
-{
- if (password.isEmpty()) {
- return QStringList();
- }
-
- Q_ASSERT(m_param.contains(PasswordHeaderSwitch));
-
- QStringList passwordHeaderSwitch = m_param.value(PasswordHeaderSwitch).toStringList();
- Q_ASSERT(!passwordHeaderSwitch.isEmpty() && passwordHeaderSwitch.size() == 2);
-
- passwordHeaderSwitch[0].replace(QLatin1String("$Password"), password);
-
- return passwordHeaderSwitch;
-}
-
-QString CliPlugin::compressionMethodSwitch(const QString &method) const
-{
- if (method.isEmpty()) {
- return QString();
- }
-
- Q_ASSERT(!filename().isEmpty());
- Q_ASSERT(m_param.contains(CompressionMethodSwitch));
-
- QMap<QString,QVariant> switches = m_param.value(CompressionMethodSwitch).toMap();
- Q_ASSERT(!switches.isEmpty());
-
- QString compMethodSwitch;
-
- compMethodSwitch = switches[QFileInfo(filename()).suffix().toLower()].toString();
- compMethodSwitch.replace(QLatin1String("$CompressionMethod"), method);
-
- return compMethodSwitch;
-}
-
#include "cliplugin.moc"
diff --git a/plugins/cli7zplugin/cliplugin.h b/plugins/cli7zplugin/cliplugin.h
index c2b8920..08ea8a8 100644
--- a/plugins/cli7zplugin/cliplugin.h
+++ b/plugins/cli7zplugin/cliplugin.h
@@ -37,15 +37,8 @@ public:
virtual ~CliPlugin();
virtual void resetParsing() Q_DECL_OVERRIDE;
- virtual Kerfuffle::ParameterList parameterList() const Q_DECL_OVERRIDE;
virtual bool readListLine(const QString &line) Q_DECL_OVERRIDE;
- /**
- * @return The password header-switch with the given @p password.
- */
- virtual QStringList passwordHeaderSwitch(const QString& password) const Q_DECL_OVERRIDE;
- virtual QString compressionMethodSwitch(const QString &method) const Q_DECL_OVERRIDE;
-
private:
enum ArchiveType {
ArchiveType7z = 0,
@@ -65,6 +58,8 @@ private:
ParseStateEntryInformation
} m_parseState;
+ void setupCliProperties();
+
int m_linesComment;
Kerfuffle::Archive::Entry *m_currentArchiveEntry;
bool m_isFirstInformationEntry;
diff --git a/plugins/cli7zplugin/kerfuffle_cli7z.json.cmake b/plugins/cli7zplugin/kerfuffle_cli7z.json.cmake
index 2e34a9d..546dfec 100644
--- a/plugins/cli7zplugin/kerfuffle_cli7z.json.cmake
+++ b/plugins/cli7zplugin/kerfuffle_cli7z.json.cmake
@@ -12,7 +12,7 @@
"Name[es]": "Complemento de archivo 7zip",
"Name[et]": "7zip arhiivi plugin",
"Name[fi]": "7zip-pakkaustuki",
- "Name[fr]": "Module externe d'archive « 7zip »",
+ "Name[fr]": "Module externe d'archive « 7zip »",
"Name[gl]": "Complemento de arquivo de 7zip",
"Name[he]": "תוסף ארכיוני 7zip",
"Name[it]": "Estensione per archivi 7zip",
@@ -51,14 +51,14 @@
"CompressionLevelMax": 9,
"CompressionLevelMin": 0,
"CompressionMethodDefault": "LZMA2",
- "CompressionMethods": [
- "BZip2",
- "Copy",
- "Deflate",
- "LZMA",
- "LZMA2",
- "PPMd"
- ],
+ "CompressionMethods": {
+ "BZip2" : "BZip2",
+ "Copy" : "Copy",
+ "Deflate" : "Deflate",
+ "LZMA" : "LZMA",
+ "LZMA2" : "LZMA2",
+ "PPMd" : "PPMd"
+ },
"HeaderEncryption": true,
"SupportsMultiVolume": true,
"SupportsTesting": true
@@ -68,16 +68,16 @@
"CompressionLevelMax": 9,
"CompressionLevelMin": 0,
"CompressionMethodDefault": "Deflate",
- "CompressionMethods": [
- "BZip2",
- "Copy",
- "Deflate",
- "Deflate64",
- "LZMA",
- "PPMd"
- ],
+ "CompressionMethods": {
+ "BZip2" : "BZip2",
+ "Copy" : "Copy",
+ "Deflate" : "Deflate",
+ "Deflate64" : "Deflate64",
+ "LZMA" : "LZMA",
+ "PPMd": "PPMd"
+ },
"Encryption": true,
"SupportsMultiVolume": true,
"SupportsTesting": true
}
-} \ No newline at end of file
+}
diff --git a/plugins/clirarplugin/cliplugin.cpp b/plugins/clirarplugin/cliplugin.cpp
index eb29459..407ec23 100644
--- a/plugins/clirarplugin/cliplugin.cpp
+++ b/plugins/clirarplugin/cliplugin.cpp
@@ -48,6 +48,8 @@ CliPlugin::CliPlugin(QObject *parent, const QVariantList& args)
// Empty lines are needed for parsing output of unrar.
setListEmptyLines(true);
+
+ setupCliProperties();
}
CliPlugin::~CliPlugin()
@@ -63,78 +65,70 @@ void CliPlugin::resetParsing()
m_numberOfVolumes = 0;
}
-ParameterList CliPlugin::parameterList() const
+void CliPlugin::setupCliProperties()
{
- static ParameterList p;
-
- if (p.isEmpty()) {
- p[CaptureProgress] = true;
- p[ListProgram] = p[ExtractProgram] = p[TestProgram] = QStringList() << QStringLiteral("unrar");
- p[DeleteProgram] = p[MoveProgram] = p[AddProgram] = QStringList() << QStringLiteral("rar");
-
- p[ListArgs] = QStringList() << QStringLiteral("vt")
- << QStringLiteral("-v")
- << QStringLiteral("$PasswordSwitch")
- << QStringLiteral("$Archive");
- p[ExtractArgs] = QStringList() << QStringLiteral("-kb")
- << QStringLiteral("-p-")
- << QStringLiteral("$PreservePathSwitch")
- << QStringLiteral("$PasswordSwitch")
- << QStringLiteral("$Archive")
- << QStringLiteral("$Files");
- p[PreservePathSwitch] = QStringList() << QStringLiteral("x")
- << QStringLiteral("e");
- p[PasswordSwitch] = QStringList() << QStringLiteral("-p$Password");
- p[PasswordHeaderSwitch] = QStringList() << QStringLiteral("-hp$Password");
- p[CompressionLevelSwitch] = QStringLiteral("-m$CompressionLevel");
- p[MultiVolumeSwitch] = QStringLiteral("-v$VolumeSizek");
- p[DeleteArgs] = QStringList() << QStringLiteral("d")
- << QStringLiteral("$PasswordSwitch")
- << QStringLiteral("$Archive")
- << QStringLiteral("$Files");
- p[FileExistsExpression] = QStringList()
- << QStringLiteral("^\\[Y\\]es, \\[N\\]o, \\[A\\]ll, n\\[E\\]ver, \\[R\\]ename, \\[Q\\]uit $");
- p[FileExistsFileName] = QStringList() << QStringLiteral("^(.+) already exists. Overwrite it") // unrar 3 & 4
- << QStringLiteral("^Would you like to replace the existing file (.+)$"); // unrar 5
- p[FileExistsInput] = QStringList() << QStringLiteral("Y") //overwrite
- << QStringLiteral("N") //skip
- << QStringLiteral("A") //overwrite all
- << QStringLiteral("E") //autoskip
- << QStringLiteral("Q"); //cancel
- p[AddArgs] = QStringList() << QStringLiteral("a")
- << QStringLiteral("$Archive")
- << QStringLiteral("$PasswordSwitch")
- << QStringLiteral("$CompressionLevelSwitch")
- << QStringLiteral("$CompressionMethodSwitch")
- << QStringLiteral("$MultiVolumeSwitch")
- << QStringLiteral("$Files");
- p[MoveArgs] = QStringList() << QStringLiteral("rn")
- << QStringLiteral("$PasswordSwitch")
- << QStringLiteral("$Archive")
- << QStringLiteral("$PathPairs");
- p[PasswordPromptPattern] = QLatin1String("Enter password \\(will not be echoed\\) for");
- p[WrongPasswordPatterns] = QStringList() << QStringLiteral("password incorrect") << QStringLiteral("wrong password");
- p[ExtractionFailedPatterns] = QStringList() << QStringLiteral("CRC failed")
- << QStringLiteral("Cannot find volume");
- p[CorruptArchivePatterns] = QStringList() << QStringLiteral("Unexpected end of archive")
- << QStringLiteral("the file header is corrupt");
- p[DiskFullPatterns] = QStringList() << QStringLiteral("No space left on device");
- p[CommentArgs] = QStringList() << QStringLiteral("c")
- << QStringLiteral("$CommentSwitch")
- << QStringLiteral("$Archive");
- p[CommentSwitch] = QStringLiteral("-z$CommentFile");
- p[TestArgs] = QStringList() << QStringLiteral("t")
- << QStringLiteral("$Archive")
- << QStringLiteral("$PasswordSwitch");
- p[TestPassedPattern] = QStringLiteral("^All OK$");
- // rar will sometimes create multi-volume archives where first volume is
- // called name.part1.rar and other times name.part01.rar.
- p[MultiVolumeSuffix] = QStringList() << QStringLiteral("part01.$Suffix")
- << QStringLiteral("part1.$Suffix");
- p[CompressionMethodSwitch] = QStringLiteral("-ma$CompressionMethod");
- }
-
- return p;
+ qCDebug(ARK) << "Setting up parameters...";
+
+ m_cliProps->setProperty("captureProgress", true);
+
+ m_cliProps->setProperty("addProgram", QStringLiteral("rar"));
+ m_cliProps->setProperty("addSwitch", QStringList({QStringLiteral("a")}));
+
+ m_cliProps->setProperty("deleteProgram", QStringLiteral("rar"));
+ m_cliProps->setProperty("deleteSwitch", QStringLiteral("d"));
+
+ m_cliProps->setProperty("extractProgram", QStringLiteral("unrar"));
+ m_cliProps->setProperty("extractSwitch", QStringList{QStringLiteral("x"),
+ QStringLiteral("-kb"),
+ QStringLiteral("-p-")});
+ m_cliProps->setProperty("extractSwitchNoPreserve", QStringList{QStringLiteral("e"),
+ QStringLiteral("-kb"),
+ QStringLiteral("-p-")});
+
+ m_cliProps->setProperty("listProgram", QStringLiteral("unrar"));
+ m_cliProps->setProperty("listSwitch", QStringList{QStringLiteral("vt"),
+ QStringLiteral("-v")});
+
+ m_cliProps->setProperty("moveProgram", QStringLiteral("rar"));
+ m_cliProps->setProperty("moveSwitch", QStringLiteral("rn"));
+
+ m_cliProps->setProperty("testProgram", QStringLiteral("unrar"));
+ m_cliProps->setProperty("testSwitch", QStringLiteral("t"));
+
+ m_cliProps->setProperty("commentSwitch", QStringList{QStringLiteral("c"),
+ QStringLiteral("-z$CommentFile")});
+
+ m_cliProps->setProperty("passwordSwitch", QStringList{QStringLiteral("-p$Password")});
+ m_cliProps->setProperty("passwordSwitchHeaderEnc", QStringList{QStringLiteral("-hp$Password")});
+
+ m_cliProps->setProperty("compressionLevelSwitch", QStringLiteral("-m$CompressionLevel"));
+ m_cliProps->setProperty("compressionMethodSwitch", QHash<QString,QVariant>{{QStringLiteral("application/vnd.rar"), QStringLiteral("-ma$CompressionMethod")},
+ {QStringLiteral("application/x-rar"), QStringLiteral("-ma$CompressionMethod")}});
+ m_cliProps->setProperty("multiVolumeSwitch", QStringLiteral("-v$VolumeSizek"));
+
+
+ m_cliProps->setProperty("passwordPromptPatterns", QStringList{QStringLiteral("Enter password \\(will not be echoed\\) for")});
+ m_cliProps->setProperty("wrongPasswordPatterns", QStringList{QStringLiteral("password incorrect"),
+ QStringLiteral("wrong password")});
+ m_cliProps->setProperty("testPassedPatterns", QStringList{QStringLiteral("^All OK$")});
+ m_cliProps->setProperty("fileExistsPatterns", QStringList{QStringLiteral("^\\[Y\\]es, \\[N\\]o, \\[A\\]ll, n\\[E\\]ver, \\[R\\]ename, \\[Q\\]uit $")});
+ m_cliProps->setProperty("fileExistsFileName", QStringList{QStringLiteral("^(.+) already exists. Overwrite it"), // unrar 3 & 4
+ QStringLiteral("^Would you like to replace the existing file (.+)$")}); // unrar 5
+ m_cliProps->setProperty("fileExistsInput", QStringList{QStringLiteral("Y"), //Overwrite
+ QStringLiteral("N"), //Skip
+ QStringLiteral("A"), //Overwrite all
+ QStringLiteral("E"), //Autoskip
+ QStringLiteral("Q")}); //Cancel
+ m_cliProps->setProperty("extractionFailedPatterns", QStringList{QStringLiteral("CRC failed"),
+ QStringLiteral("Cannot find volume")});
+ m_cliProps->setProperty("corruptArchivePatterns", QStringList{QStringLiteral("Unexpected end of archive"),
+ QStringLiteral("the file header is corrupt")});
+ m_cliProps->setProperty("diskFullPatterns", QStringList{QStringLiteral("No space left on device")});
+
+ // rar will sometimes create multi-volume archives where first volume is
+ // called name.part1.rar and other times name.part01.rar.
+ m_cliProps->setProperty("multiVolumeSuffix", QStringList{QStringLiteral("part01.$Suffix"),
+ QStringLiteral("part1.$Suffix")});
}
bool CliPlugin::readListLine(const QString &line)
@@ -549,22 +543,4 @@ void CliPlugin::ignoreLines(int lines, ParseState nextState)
m_parseState = nextState;
}
-QString CliPlugin::compressionMethodSwitch(const QString &method) const
-{
- if (method.isEmpty()) {
- return QString();
- }
-
- Q_ASSERT(m_param.contains(CompressionMethodSwitch));
- QString compMethodSwitch = m_param.value(CompressionMethodSwitch).toString();
- Q_ASSERT(!compMethodSwitch.isEmpty());
- compMethodSwitch.replace(QLatin1String("$CompressionMethod"), method);
-
- // This is needed for because the user-visible strings are different from the
- // ones needed by the switch (e.g. RAR4 vs 4).
- compMethodSwitch.remove(QLatin1String("RAR"));
-
- return compMethodSwitch;
-}
-
#include "cliplugin.moc"
diff --git a/plugins/clirarplugin/cliplugin.h b/plugins/clirarplugin/cliplugin.h
index bb11f9a..072d507 100644
--- a/plugins/clirarplugin/cliplugin.h
+++ b/plugins/clirarplugin/cliplugin.h
@@ -36,11 +36,8 @@ public:
virtual ~CliPlugin();
virtual void resetParsing() Q_DECL_OVERRIDE;
- virtual Kerfuffle::ParameterList parameterList() const Q_DECL_OVERRIDE;
virtual bool readListLine(const QString &line) Q_DECL_OVERRIDE;
- virtual QString compressionMethodSwitch(const QString &method) const Q_DECL_OVERRIDE;
-
private:
enum ParseState {
@@ -52,6 +49,8 @@ private:
ParseStateLinkTarget
} m_parseState;
+ void setupCliProperties();
+
bool handleUnrar5Line(const QString &line);
void handleUnrar5Entry();
bool handleUnrar4Line(const QString &line);
diff --git a/plugins/clirarplugin/kerfuffle_clirar.json.cmake b/plugins/clirarplugin/kerfuffle_clirar.json.cmake
index a0b7e6f..18f9f3b 100644
--- a/plugins/clirarplugin/kerfuffle_clirar.json.cmake
+++ b/plugins/clirarplugin/kerfuffle_clirar.json.cmake
@@ -12,7 +12,7 @@
"Name[es]": "Complemento de archivo RAR",
"Name[et]": "RAR-arhiivi plugin",
"Name[fi]": "RAR-pakkaustuki",
- "Name[fr]": "Module externe d'archive « RAR »",
+ "Name[fr]": "Module externe d'archive « RAR »",
"Name[gl]": "Complemento de arquivo RAR",
"Name[he]": "תוסף ארכיוני RAR",
"Name[it]": "Estensione per archivi RAR",
@@ -52,10 +52,10 @@
"CompressionLevelMax": 5,
"CompressionLevelMin": 0,
"CompressionMethodDefault": "RAR4",
- "CompressionMethods": [
- "RAR4",
- "RAR5"
- ],
+ "CompressionMethods": {
+ "RAR4" : "4",
+ "RAR5" : "5"
+ },
"HeaderEncryption": true,
"SupportsMultiVolume": true,
"SupportsTesting": true,
@@ -66,13 +66,13 @@
"CompressionLevelMax": 5,
"CompressionLevelMin": 0,
"CompressionMethodDefault": "RAR4",
- "CompressionMethods": [
- "RAR4",
- "RAR5"
- ],
+ "CompressionMethods": {
+ "RAR4" : "4",
+ "RAR5" : "5"
+ },
"HeaderEncryption": true,
"SupportsMultiVolume": true,
"SupportsTesting": true,
"SupportsWriteComment": true
}
-} \ No newline at end of file
+}
diff --git a/plugins/cliunarchiverplugin/cliplugin.cpp b/plugins/cliunarchiverplugin/cliplugin.cpp
index 7451255..bdcc2a9 100644
--- a/plugins/cliunarchiverplugin/cliplugin.cpp
+++ b/plugins/cliunarchiverplugin/cliplugin.cpp
@@ -38,6 +38,7 @@ CliPlugin::CliPlugin(QObject *parent, const QVariantList &args)
: CliInterface(parent, args)
{
qCDebug(ARK) << "Loaded cli_unarchiver plugin";
+ setupCliProperties();
}
CliPlugin::~CliPlugin()
@@ -47,11 +48,9 @@ CliPlugin::~CliPlugin()
bool CliPlugin::list()
{
resetParsing();
- cacheParameterList();
m_operationMode = List;
- const auto args = substituteListVariables(m_param.value(ListArgs).toStringList(), password());
- return runProcess(m_param.value(ListProgram).toStringList(), args);
+ return runProcess(m_cliProps->property("listProgram").toString(), m_cliProps->listArgs(filename(), password()));
}
bool CliPlugin::extractFiles(const QVector<Archive::Entry*> &files, const QString &destinationDirectory, const ExtractionOptions &options)
@@ -77,36 +76,24 @@ void CliPlugin::resetParsing()
m_numberOfVolumes = 0;
}
-ParameterList CliPlugin::parameterList() const
+void CliPlugin::setupCliProperties()
{
- static ParameterList p;
- if (p.isEmpty()) {
+ m_cliProps->setProperty("captureProgress", false);
- ///////////////[ COMMON ]/////////////
+ m_cliProps->setProperty("extractProgram", QStringLiteral("unar"));
+ m_cliProps->setProperty("extractSwitch", QStringList{QStringLiteral("-D")});
+ m_cliProps->setProperty("extractSwitchNoPreserve", QStringList{QStringLiteral("-D")});
- p[CaptureProgress] = false;
- // Displayed when running lsar -json with header-encrypted archives.
- p[PasswordPromptPattern] = QStringLiteral("This archive requires a password to unpack. Use the -p option to provide one.");
+ m_cliProps->setProperty("listProgram", QStringLiteral("lsar"));
+ m_cliProps->setProperty("listSwitch", QStringList{QStringLiteral("-json")});
- ///////////////[ LIST ]/////////////
+ m_cliProps->setProperty("passwordSwitch", QStringList{QStringLiteral("-password"),
+ QStringLiteral("$Password")});
- p[ListProgram] = QStringLiteral("lsar");
- p[ListArgs] = QStringList() << QStringLiteral("-json") << QStringLiteral("$Archive") << QStringLiteral("$PasswordSwitch");
+ m_cliProps->setProperty("passwordPromptPatterns", QStringList{QStringLiteral("This archive requires a password to unpack. Use the -p option to provide one.")});
- ///////////////[ EXTRACT ]/////////////
-
- p[ExtractProgram] = QStringLiteral("unar");
- p[ExtractArgs] = QStringList() << QStringLiteral("-D") << QStringLiteral("$Archive") << QStringLiteral("$Files") << QStringLiteral("$PasswordSwitch");
- p[NoTrailingSlashes] = true;
- p[PasswordSwitch] = QStringList() << QStringLiteral("-password") << QStringLiteral("$Password");
-
- ///////////////[ ERRORS ]/////////////
-
- p[ExtractionFailedPatterns] = QStringList()
- << QStringLiteral("Failed! \\((.+)\\)$")
- << QStringLiteral("Segmentation fault$");
- }
- return p;
+ m_cliProps->setProperty("extractionFailedPatterns", QStringList{QStringLiteral("Failed! \\((.+)\\)$"),
+ QStringLiteral("Segmentation fault$")});
}
bool CliPlugin::readListLine(const QString &line)
@@ -133,13 +120,6 @@ void CliPlugin::readStdout(bool handleAll)
readJsonOutput();
}
-void CliPlugin::cacheParameterList()
-{
- m_param = parameterList();
- Q_ASSERT(m_param.contains(ExtractProgram));
- Q_ASSERT(m_param.contains(ListProgram));
-}
-
bool CliPlugin::handleLine(const QString& line)
{
// Collect the json output line by line.
@@ -149,7 +129,7 @@ bool CliPlugin::handleLine(const QString& line)
// TODO: is this check really needed?
if (m_operationMode == Copy) {
- if (checkForErrorMessage(line, ExtractionFailedPatterns)) {
+ if (m_cliProps->isExtractionFailedMsg(line)) {
qCWarning(ARK) << "Error in extraction:" << line;
emit error(i18n("Extraction failed because of an unexpected error."));
return false;
@@ -158,7 +138,7 @@ bool CliPlugin::handleLine(const QString& line)
if (m_operationMode == List) {
// This can only be an header-encrypted archive.
- if (checkForPasswordPromptMessage(line)) {
+ if (m_cliProps->isPasswordPrompt(line)) {
qCDebug(ARK) << "Detected header-encrypted RAR archive";
Kerfuffle::PasswordNeededQuery query(filename());
diff --git a/plugins/cliunarchiverplugin/cliplugin.h b/plugins/cliunarchiverplugin/cliplugin.h
index e703d8b..5e8c8f8 100644
--- a/plugins/cliunarchiverplugin/cliplugin.h
+++ b/plugins/cliunarchiverplugin/cliplugin.h
@@ -37,7 +37,6 @@ public:
virtual bool list() Q_DECL_OVERRIDE;
virtual bool extractFiles(const QVector<Kerfuffle::Archive::Entry*> &files, const QString &destinationDirectory, const Kerfuffle::ExtractionOptions &options) Q_DECL_OVERRIDE;
virtual void resetParsing() Q_DECL_OVERRIDE;
- virtual Kerfuffle::ParameterList parameterList() const Q_DECL_OVERRIDE;
virtual bool readListLine(const QString &line) Q_DECL_OVERRIDE;
/**
@@ -50,14 +49,13 @@ protected slots:
protected:
- void cacheParameterList() Q_DECL_OVERRIDE;
bool handleLine(const QString& line) Q_DECL_OVERRIDE;
private slots:
void processFinished(int exitCode, QProcess::ExitStatus exitStatus) Q_DECL_OVERRIDE;
private:
-
+ void setupCliProperties();
void readJsonOutput();
QString m_jsonOutput;
diff --git a/plugins/cliunarchiverplugin/kerfuffle_cliunarchiver.json.cmake b/plugins/cliunarchiverplugin/kerfuffle_cliunarchiver.json.cmake
index 5f22771..7d09bc8 100644
--- a/plugins/cliunarchiverplugin/kerfuffle_cliunarchiver.json.cmake
+++ b/plugins/cliunarchiverplugin/kerfuffle_cliunarchiver.json.cmake
@@ -41,5 +41,11 @@
"unar"
],
"X-KDE-Kerfuffle-ReadWrite": false,
- "X-KDE-Priority": 100
-} \ No newline at end of file
+ "X-KDE-Priority": 100,
+ "application/vnd.rar": {
+ "HeaderEncryption": true
+ },
+ "application/x-rar": {
+ "HeaderEncryption": true
+ }
+}
diff --git a/plugins/clizipplugin/cliplugin.cpp b/plugins/clizipplugin/cliplugin.cpp
index 9158510..1a8b9bc 100644
--- a/plugins/clizipplugin/cliplugin.cpp
+++ b/plugins/clizipplugin/cliplugin.cpp
@@ -42,6 +42,7 @@ CliPlugin::CliPlugin(QObject *parent, const QVariantList & args)
, m_linesComment(0)
{
qCDebug(ARK) << "Loaded cli_zip plugin";
+ setupCliProperties();
}
CliPlugin::~CliPlugin()
@@ -78,60 +79,49 @@ QString CliPlugin::escapeFileName(const QString &fileName) const
return quoted;
}
-ParameterList CliPlugin::parameterList() const
+void CliPlugin::setupCliProperties()
{
- static ParameterList p;
-
- if (p.isEmpty()) {
- p[CaptureProgress] = false;
- p[ListProgram] = QStringList() << QStringLiteral("zipinfo");
- p[ExtractProgram] = p[TestProgram] = QStringList() << QStringLiteral("unzip");
- p[DeleteProgram] = p[AddProgram] = QStringList() << QStringLiteral("zip");
-
- p[ListArgs] = QStringList() << QStringLiteral("-l")
- << QStringLiteral("-T")
- << QStringLiteral("-z")
- << QStringLiteral("$Archive");
- p[ExtractArgs] = QStringList() << QStringLiteral("$PreservePathSwitch")
- << QStringLiteral("$PasswordSwitch")
- << QStringLiteral("$Archive")
- << QStringLiteral("$Files");
- p[PreservePathSwitch] = QStringList() << QStringLiteral("")
- << QStringLiteral("-j");
- p[PasswordSwitch] = QStringList() << QStringLiteral("-P$Password");
- p[CompressionLevelSwitch] = QStringLiteral("-$CompressionLevel");
- p[DeleteArgs] = QStringList() << QStringLiteral("-d")
- << QStringLiteral("$Archive")
- << QStringLiteral("$Files");
-
- p[FileExistsExpression] = QStringList()
- << QStringLiteral("^replace (.+)\\? \\[y\\]es, \\[n\\]o, \\[A\\]ll, \\[N\\]one, \\[r\\]ename: $");
- p[FileExistsFileName] = QStringList() << p[FileExistsExpression].toString();
- p[FileExistsInput] = QStringList() << QStringLiteral("y") //overwrite
- << QStringLiteral("n") //skip
- << QStringLiteral("A") //overwrite all
- << QStringLiteral("N"); //autoskip
-
- p[AddArgs] = QStringList() << QStringLiteral("-r")
- << QStringLiteral("$Archive")
- << QStringLiteral("$PasswordSwitch")
- << QStringLiteral("$CompressionLevelSwitch")
- << QStringLiteral("$CompressionMethodSwitch")
- << QStringLiteral("$Files");
-
- p[PasswordPromptPattern] = QStringLiteral(" password: ");
- p[WrongPasswordPatterns] = QStringList() << QStringLiteral("incorrect password");
- p[ExtractionFailedPatterns] = QStringList() << QStringLiteral("unsupported compression method");
- p[CorruptArchivePatterns] = QStringList() << QStringLiteral("End-of-central-directory signature not found");
- p[DiskFullPatterns] = QStringList() << QStringLiteral("write error \\(disk full\\?\\)")
- << QStringLiteral("No space left on device");
- p[TestArgs] = QStringList() << QStringLiteral("-t")
- << QStringLiteral("$Archive")
- << QStringLiteral("$PasswordSwitch");
- p[TestPassedPattern] = QStringLiteral("^No errors detected in compressed data of ");
- p[CompressionMethodSwitch] = QStringLiteral("-Z$CompressionMethod");
- }
- return p;
+ qCDebug(ARK) << "Setting up parameters...";
+
+ m_cliProps->setProperty("captureProgress", false);
+
+ m_cliProps->setProperty("addProgram", QStringLiteral("zip"));
+ m_cliProps->setProperty("addSwitch", QStringList({QStringLiteral("-r")}));
+
+ m_cliProps->setProperty("deleteProgram", QStringLiteral("zip"));
+ m_cliProps->setProperty("deleteSwitch", QStringLiteral("-d"));
+
+ m_cliProps->setProperty("extractProgram", QStringLiteral("unzip"));
+ m_cliProps->setProperty("extractSwitchNoPreserve", QStringList{QStringLiteral("-j")});
+
+ m_cliProps->setProperty("listProgram", QStringLiteral("zipinfo"));
+ m_cliProps->setProperty("listSwitch", QStringList{QStringLiteral("-l"),
+ QStringLiteral("-T"),
+ QStringLiteral("-z")});
+
+ m_cliProps->setProperty("testProgram", QStringLiteral("unzip"));
+ m_cliProps->setProperty("testSwitch", QStringLiteral("-t"));
+
+ m_cliProps->setProperty("passwordSwitch", QStringList{QStringLiteral("-P$Password")});
+
+ m_cliProps->setProperty("compressionLevelSwitch", QStringLiteral("-$CompressionLevel"));
+ m_cliProps->setProperty("compressionMethodSwitch", QHash<QString,QVariant>{{QStringLiteral("application/zip"), QStringLiteral("-Z$CompressionMethod")},
+ {QStringLiteral("application/x-java-archive"), QStringLiteral("-Z$CompressionMethod")}});
+ m_cliProps->setProperty("multiVolumeSwitch", QStringLiteral("-v$VolumeSizek"));
+
+ m_cliProps->setProperty("passwordPromptPatterns", QStringList{QStringLiteral(" password: ")});
+ m_cliProps->setProperty("wrongPasswordPatterns", QStringList{QStringLiteral("incorrect password")});
+ m_cliProps->setProperty("testPassedPatterns", QStringList{QStringLiteral("^No errors detected in compressed data of ")});
+ m_cliProps->setProperty("fileExistsPatterns", QStringList{QStringLiteral("^replace (.+)\\? \\[y\\]es, \\[n\\]o, \\[A\\]ll, \\[N\\]one, \\[r\\]ename: $")});
+ m_cliProps->setProperty("fileExistsFileName", QStringList{QStringLiteral("^replace (.+)\\? \\[y\\]es, \\[n\\]o, \\[A\\]ll, \\[N\\]one, \\[r\\]ename: $")});
+ m_cliProps->setProperty("fileExistsInput", QStringList{QStringLiteral("y"), //Overwrite
+ QStringLiteral("n"), //Skip
+ QStringLiteral("A"), //Overwrite all
+ QStringLiteral("N")}); //Autoskip
+ m_cliProps->setProperty("extractionFailedPatterns", QStringList{QStringLiteral("unsupported compression method")});
+ m_cliProps->setProperty("corruptArchivePatterns", QStringList{QStringLiteral("End-of-central-directory signature not found")});
+ m_cliProps->setProperty("diskFullPatterns", QStringList{QStringLiteral("write error \\(disk full\\?\\)"),
+ QStringLiteral("No space left on device")});
}
bool CliPlugin::readListLine(const QString &line)
@@ -297,22 +287,6 @@ void CliPlugin::finishMoving(bool result)
cleanUp();
}
-QString CliPlugin::compressionMethodSwitch(const QString &method) const
-{
- if (method.isEmpty()) {
- return QString();
- }
-
- Q_ASSERT(m_param.contains(CompressionMethodSwitch));
- QString compMethodSwitch = m_param.value(CompressionMethodSwitch).toString();
- Q_ASSERT(!compMethodSwitch.isEmpty());
-
- // We use capitalization of methods in UI, but CLI requires lowercase.
- compMethodSwitch.replace(QLatin1String("$CompressionMethod"), method.toLower());
-
- return compMethodSwitch;
-}
-
QString CliPlugin::convertCompressionMethod(const QString &method)
{
if (method == QLatin1String("stor")) {
diff --git a/plugins/clizipplugin/cliplugin.h b/plugins/clizipplugin/cliplugin.h
index 4a789ee..beca40e 100644
--- a/plugins/clizipplugin/cliplugin.h
+++ b/plugins/clizipplugin/cliplugin.h
@@ -38,18 +38,16 @@ public:
virtual void resetParsing() Q_DECL_OVERRIDE;
virtual QString escapeFileName(const QString &fileName) const Q_DECL_OVERRIDE;
- virtual Kerfuffle::ParameterList parameterList() const Q_DECL_OVERRIDE;
virtual bool readListLine(const QString &line) Q_DECL_OVERRIDE;
virtual bool moveFiles(const QVector<Archive::Entry*> &files, Archive::Entry *destination, const CompressionOptions& options) Q_DECL_OVERRIDE;
virtual int moveRequiredSignals() const Q_DECL_OVERRIDE;
- virtual QString compressionMethodSwitch(const QString &method) const Q_DECL_OVERRIDE;
-
private slots:
void continueMoving(bool result);
private:
+ void setupCliProperties();
bool setMovingAddedFiles();
void finishMoving(bool result);
QString convertCompressionMethod(const QString &method);
diff --git a/plugins/clizipplugin/kerfuffle_clizip.json.cmake b/plugins/clizipplugin/kerfuffle_clizip.json.cmake
index d4a852d..0fce0a7 100644
--- a/plugins/clizipplugin/kerfuffle_clizip.json.cmake
+++ b/plugins/clizipplugin/kerfuffle_clizip.json.cmake
@@ -12,7 +12,7 @@
"Name[es]": "Complemento de archivo ZIP",
"Name[et]": "ZIP-arhiivi plugin",
"Name[fi]": "ZIP-pakkaustuki",
- "Name[fr]": "Module externe d'archive « zip »",
+ "Name[fr]": "Module externe d'archive « zip »",
"Name[gl]": "Complemento de arquivo ZIP",
"Name[he]": "תוסף ארכיוני ZIP",
"Name[it]": "Estensione per archivi ZIP",
@@ -58,13 +58,13 @@
"CompressionLevelDefault": 6,
"CompressionLevelMax": 9,
"CompressionLevelMin": 0,
- "CompressionMethodDefault": "deflate",
- "CompressionMethods": [
- "BZip2",
- "Deflate",
- "Store"
- ],
+ "CompressionMethodDefault": "Deflate",
+ "CompressionMethods": {
+ "BZip2" : "bzip2",
+ "Deflate" : "deflate",
+ "Store" : "store"
+ },
"Encryption": true,
"SupportsTesting": true
}
-} \ No newline at end of file
+}