summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRagnar Thomsen <rthomsen6@gmail.com>2016-10-09 16:38:25 (GMT)
committerRagnar Thomsen <rthomsen6@gmail.com>2016-10-09 16:38:25 (GMT)
commit50a9f590bd2d0a32ac3fe3e4d129637864c977de (patch)
treebb9cd9f6b6189ecf0448ab7c5b0c19786f4947b5
parenta3921c6ceced49499ac024d0ae67563275eaadb6 (diff)
Detect compression method
A new property was added to Archive to store detected compression method(s). Currently, it's only displayed in PropertiesDialog, but the plan is to also use it to select a sane default compression method when adding files to an existing archive. Code was added to all plugins for detecting the compression method(s) when opening an archive and a signal added to ReadOnlyArchiveInterface to set the property. Many archive types support multiple compression methods in same archive, so the property is a QStringList. Differential Revision: D2987
-rw-r--r--kerfuffle/archive_kerfuffle.cpp11
-rw-r--r--kerfuffle/archive_kerfuffle.h4
-rw-r--r--kerfuffle/archiveinterface.h1
-rw-r--r--kerfuffle/propertiesdialog.cpp1
-rw-r--r--kerfuffle/propertiesdialog.ui64
-rw-r--r--plugins/cli7zplugin/cliplugin.cpp30
-rw-r--r--plugins/cli7zplugin/cliplugin.h1
-rw-r--r--plugins/clirarplugin/cliplugin.cpp5
-rw-r--r--plugins/cliunarchiverplugin/cliplugin.cpp6
-rw-r--r--plugins/clizipplugin/cliplugin.cpp18
-rw-r--r--plugins/clizipplugin/cliplugin.h2
-rw-r--r--plugins/libarchive/libarchiveplugin.cpp28
-rw-r--r--plugins/libarchive/libarchiveplugin.h1
13 files changed, 146 insertions, 26 deletions
diff --git a/kerfuffle/archive_kerfuffle.cpp b/kerfuffle/archive_kerfuffle.cpp
index 7256418..b105869 100644
--- a/kerfuffle/archive_kerfuffle.cpp
+++ b/kerfuffle/archive_kerfuffle.cpp
@@ -172,8 +172,19 @@ Archive::Archive(ReadOnlyArchiveInterface *archiveInterface, bool isReadOnly, QO
m_iface->setParent(this);
connect(m_iface, &ReadOnlyArchiveInterface::entry, this, &Archive::onNewEntry);
+ connect(m_iface, &ReadOnlyArchiveInterface::compressionMethodFound, this, &Archive::onCompressionMethodFound);
}
+void Archive::onCompressionMethodFound(const QStringList &methods)
+{
+ // If other methods are found, we dont report "Store" method.
+ QStringList processedMethods = methods;
+ if (processedMethods.size() > 1 &&
+ processedMethods.contains(QStringLiteral("Store"))) {
+ processedMethods.removeOne(QStringLiteral("Store"));
+ }
+ setProperty("compressionMethods", processedMethods);
+}
Archive::~Archive()
{
diff --git a/kerfuffle/archive_kerfuffle.h b/kerfuffle/archive_kerfuffle.h
index 2f17d73..8ec2d1e 100644
--- a/kerfuffle/archive_kerfuffle.h
+++ b/kerfuffle/archive_kerfuffle.h
@@ -93,6 +93,7 @@ class KERFUFFLE_EXPORT Archive : public QObject
Q_PROPERTY(qulonglong packedSize READ packedSize)
Q_PROPERTY(QString subfolderName MEMBER m_subfolderName READ subfolderName)
Q_PROPERTY(QString password READ password)
+ Q_PROPERTY(QStringList compressionMethods MEMBER m_compressionMethods)
public:
@@ -221,6 +222,7 @@ private slots:
void onAddFinished(KJob*);
void onUserQuery(Kerfuffle::Query*);
void onNewEntry(const Archive::Entry *entry);
+ void onCompressionMethodFound(const QStringList &methods);
private:
Archive(ReadOnlyArchiveInterface *archiveInterface, bool isReadOnly, QObject *parent = 0);
@@ -235,7 +237,6 @@ private:
* @return A valid archive if the plugin could be loaded, an invalid one otherwise (with the FailedPlugin error set).
*/
static Archive *create(const QString &fileName, Plugin *plugin, QObject *parent = Q_NULLPTR);
-
ReadOnlyArchiveInterface *m_iface;
bool m_isReadOnly;
bool m_isSingleFolder;
@@ -249,6 +250,7 @@ private:
qulonglong m_numberOfFolders;
CompressionOptions m_compOptions;
QMimeType m_mimeType;
+ QStringList m_compressionMethods;
};
} // namespace Kerfuffle
diff --git a/kerfuffle/archiveinterface.h b/kerfuffle/archiveinterface.h
index 901864f..f67f6bd 100644
--- a/kerfuffle/archiveinterface.h
+++ b/kerfuffle/archiveinterface.h
@@ -167,6 +167,7 @@ signals:
void finished(bool result);
void userQuery(Query *query);
void testSuccess();
+ void compressionMethodFound(const QStringList);
protected:
diff --git a/kerfuffle/propertiesdialog.cpp b/kerfuffle/propertiesdialog.cpp
index d8e81b6..41021ed 100644
--- a/kerfuffle/propertiesdialog.cpp
+++ b/kerfuffle/propertiesdialog.cpp
@@ -63,6 +63,7 @@ PropertiesDialog::PropertiesDialog(QWidget *parent, Archive *archive, qulonglong
m_ui->lblArchiveName->setText(archive->fileName());
m_ui->lblArchiveType->setText(archive->mimeType().comment());
m_ui->lblMimetype->setText(archive->mimeType().name());
+ m_ui->lblCompressionMethods->setText(archive->property("compressionMethods").toStringList().join(QStringLiteral(", ")));
m_ui->lblReadOnly->setText(archive->isReadOnly() ? i18n("yes") : i18n("no"));
m_ui->lblMultiVolume->setText(archive->isMultiVolume() ? i18n("yes (%1 volumes)", archive->numberOfVolumes()) : i18n("no"));
m_ui->lblHasComment->setText(archive->hasComment() ? i18n("yes") : i18n("no"));
diff --git a/kerfuffle/propertiesdialog.ui b/kerfuffle/propertiesdialog.ui
index c5b8e69..ce6c012 100644
--- a/kerfuffle/propertiesdialog.ui
+++ b/kerfuffle/propertiesdialog.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>730</width>
- <height>412</height>
+ <height>436</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@@ -73,126 +73,126 @@
</property>
</widget>
</item>
- <item row="3" column="0">
+ <item row="4" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Opened read-only:</string>
</property>
</widget>
</item>
- <item row="3" column="1">
+ <item row="4" column="1">
<widget class="QLabel" name="lblReadOnly">
<property name="text">
<string/>
</property>
</widget>
</item>
- <item row="4" column="0">
+ <item row="5" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Password-protected:</string>
</property>
</widget>
</item>
- <item row="4" column="1">
+ <item row="5" column="1">
<widget class="QLabel" name="lblPasswordProtected">
<property name="text">
<string/>
</property>
</widget>
</item>
- <item row="6" column="0">
+ <item row="7" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Has comment:</string>
</property>
</widget>
</item>
- <item row="6" column="1">
+ <item row="7" column="1">
<widget class="QLabel" name="lblHasComment">
<property name="text">
<string/>
</property>
</widget>
</item>
- <item row="7" column="0">
+ <item row="8" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Number of entries:</string>
</property>
</widget>
</item>
- <item row="7" column="1">
+ <item row="8" column="1">
<widget class="QLabel" name="lblNumberOfEntries">
<property name="text">
<string/>
</property>
</widget>
</item>
- <item row="8" column="0">
+ <item row="9" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Unpacked size:</string>
</property>
</widget>
</item>
- <item row="8" column="1">
+ <item row="9" column="1">
<widget class="QLabel" name="lblUnpackedSize">
<property name="text">
<string/>
</property>
</widget>
</item>
- <item row="9" column="0">
+ <item row="10" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Packed size:</string>
</property>
</widget>
</item>
- <item row="9" column="1">
+ <item row="10" column="1">
<widget class="QLabel" name="lblPackedSize">
<property name="text">
<string/>
</property>
</widget>
</item>
- <item row="10" column="0">
+ <item row="11" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Compression ratio:</string>
</property>
</widget>
</item>
- <item row="10" column="1">
+ <item row="11" column="1">
<widget class="QLabel" name="lblCompressionRatio">
<property name="text">
<string/>
</property>
</widget>
</item>
- <item row="11" column="0">
+ <item row="12" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Last modified:</string>
</property>
</widget>
</item>
- <item row="11" column="1">
+ <item row="12" column="1">
<widget class="QLabel" name="lblLastModified">
<property name="text">
<string/>
</property>
</widget>
</item>
- <item row="12" column="0">
+ <item row="13" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>MD5 hash:</string>
</property>
</widget>
</item>
- <item row="12" column="1">
+ <item row="13" column="1">
<widget class="QLabel" name="lblMD5">
<property name="text">
<string/>
@@ -205,14 +205,14 @@
</property>
</widget>
</item>
- <item row="13" column="0">
+ <item row="14" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>SHA-1 hash:</string>
</property>
</widget>
</item>
- <item row="13" column="1">
+ <item row="14" column="1">
<widget class="QLabel" name="lblSHA1">
<property name="text">
<string/>
@@ -222,14 +222,14 @@
</property>
</widget>
</item>
- <item row="14" column="0">
+ <item row="15" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>SHA-256 hash:</string>
</property>
</widget>
</item>
- <item row="14" column="1">
+ <item row="15" column="1">
<widget class="QLabel" name="lblSHA256">
<property name="text">
<string notr="true">nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn</string>
@@ -239,20 +239,34 @@
</property>
</widget>
</item>
- <item row="5" column="0">
+ <item row="6" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Multi-volume:</string>
</property>
</widget>
</item>
- <item row="5" column="1">
+ <item row="6" column="1">
<widget class="QLabel" name="lblMultiVolume">
<property name="text">
<string/>
</property>
</widget>
</item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_16">
+ <property name="text">
+ <string>Compression method(s):</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="lblCompressionMethods">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
</layout>
</item>
<item>
diff --git a/plugins/cli7zplugin/cliplugin.cpp b/plugins/cli7zplugin/cliplugin.cpp
index ae385ac..1d41973 100644
--- a/plugins/cli7zplugin/cliplugin.cpp
+++ b/plugins/cli7zplugin/cliplugin.cpp
@@ -180,6 +180,23 @@ bool CliPlugin::readListLine(const QString& line)
}
} else if (line.startsWith(QStringLiteral("Volumes = "))) {
m_numberOfVolumes = line.section(QLatin1Char('='), 1).trimmed().toInt();
+
+ } else if (line.startsWith(QStringLiteral("Method = "))) {
+ QStringList methods = line.section(QLatin1Char('='), 1).trimmed().split(QLatin1Char(' '), QString::SkipEmptyParts);
+ // LZMA methods are output with some trailing numbers by 7z representing dictionary/block sizes.
+ // We are not interested in these, so remove them.
+ QMutableListIterator<QString> i(methods);
+ while (i.hasNext()) {
+ QString m = i.next();
+ if (m.startsWith(QLatin1String("LZMA2"))) {
+ m = m.left(5);
+ } else if (m.startsWith(QLatin1String("LZMA"))) {
+ m = m.left(4);
+ }
+ i.setValue(m);
+ }
+ emit compressionMethodFound(methods);
+
} else if (rxComment.match(line).hasMatch()) {
m_parseState = ParseStateComment;
m_comment.append(line.section(QLatin1Char('='), 1) + QLatin1Char('\n'));
@@ -241,6 +258,19 @@ bool CliPlugin::readListLine(const QString& line)
m_currentArchiveEntry->setProperty("CRC", line.mid(6).trimmed());
} else if (line.startsWith(QStringLiteral("Method = "))) {
m_currentArchiveEntry->setProperty("method", line.mid(9).trimmed());
+
+ // For zip archives we need to check method for each entry.
+ if (m_archiveType == ArchiveTypeZip) {
+ QString method = line.mid(9).trimmed();
+ if (method == QLatin1String("xz")) {
+ method = QStringLiteral("XZ");
+ }
+ if (!m_compressionMethods.contains(method)) {
+ m_compressionMethods.append(method);
+ emit compressionMethodFound(m_compressionMethods);
+ }
+ }
+
} else if (line.startsWith(QStringLiteral("Encrypted = ")) &&
line.size() >= 13) {
m_currentArchiveEntry->setProperty("isPasswordProtected", line.at(12) == QLatin1Char('+'));
diff --git a/plugins/cli7zplugin/cliplugin.h b/plugins/cli7zplugin/cliplugin.h
index c60a62d..27c33c5 100644
--- a/plugins/cli7zplugin/cliplugin.h
+++ b/plugins/cli7zplugin/cliplugin.h
@@ -67,6 +67,7 @@ private:
int m_linesComment;
Kerfuffle::Archive::Entry *m_currentArchiveEntry;
bool m_isFirstInformationEntry;
+ QStringList m_compressionMethods;
};
#endif // CLIPLUGIN_H
diff --git a/plugins/clirarplugin/cliplugin.cpp b/plugins/clirarplugin/cliplugin.cpp
index a4cad4c..6e08d20 100644
--- a/plugins/clirarplugin/cliplugin.cpp
+++ b/plugins/clirarplugin/cliplugin.cpp
@@ -217,6 +217,11 @@ bool CliPlugin::handleUnrar5Line(const QString &line)
m_isSolid = true;
qCDebug(ARK) << "Solid archive detected";
}
+ if (line.contains(QLatin1String("RAR 4"))) {
+ emit compressionMethodFound(QStringList{QStringLiteral("RAR4")});
+ } else if (line.contains(QLatin1String("RAR 5"))) {
+ emit compressionMethodFound(QStringList{QStringLiteral("RAR5")});
+ }
}
return true;
}
diff --git a/plugins/cliunarchiverplugin/cliplugin.cpp b/plugins/cliunarchiverplugin/cliplugin.cpp
index 3f45eaa..a64c391 100644
--- a/plugins/cliunarchiverplugin/cliplugin.cpp
+++ b/plugins/cliunarchiverplugin/cliplugin.cpp
@@ -240,6 +240,12 @@ void CliPlugin::readJsonOutput()
setMultiVolume(true);
}
+ QString formatName = json.value(QStringLiteral("lsarFormatName")).toString();
+ if (formatName == QLatin1String("RAR")) {
+ emit compressionMethodFound(QStringList{QStringLiteral("RAR4")});
+ } else if (formatName == QLatin1String("RAR 5")) {
+ emit compressionMethodFound(QStringList{QStringLiteral("RAR5")});
+ }
const QJsonArray entries = json.value(QStringLiteral("lsarContents")).toArray();
foreach (const QJsonValue& value, entries) {
diff --git a/plugins/clizipplugin/cliplugin.cpp b/plugins/clizipplugin/cliplugin.cpp
index 1da5677..29bc81d 100644
--- a/plugins/clizipplugin/cliplugin.cpp
+++ b/plugins/clizipplugin/cliplugin.cpp
@@ -179,6 +179,12 @@ bool CliPlugin::readListLine(const QString &line)
e->setProperty("compressedSize", rxMatch.captured(6).toInt());
e->setProperty("method", rxMatch.captured(7));
+ QString method = convertCompressionMethod(rxMatch.captured(7));
+ if (!m_compressionMethods.contains(method)) {
+ m_compressionMethods.append(method);
+ emit compressionMethodFound(m_compressionMethods);
+ }
+
const QDateTime ts(QDate::fromString(rxMatch.captured(8), QStringLiteral("yyyyMMdd")),
QTime::fromString(rxMatch.captured(9), QStringLiteral("hhmmss")));
e->setProperty("timestamp", ts);
@@ -284,4 +290,16 @@ void CliPlugin::finishMoving(bool result)
cleanUp();
}
+QString CliPlugin::convertCompressionMethod(const QString &method)
+{
+ if (method == QLatin1String("stor")) {
+ return QStringLiteral("Store");
+ } else if (method.startsWith(QLatin1String("def"))) {
+ return QStringLiteral("Deflate");
+ } else if (method == QLatin1String("bzp2")) {
+ return QStringLiteral("BZip2");
+ }
+ return method;
+}
+
#include "cliplugin.moc"
diff --git a/plugins/clizipplugin/cliplugin.h b/plugins/clizipplugin/cliplugin.h
index c85f73a..2d44b07 100644
--- a/plugins/clizipplugin/cliplugin.h
+++ b/plugins/clizipplugin/cliplugin.h
@@ -50,6 +50,7 @@ private slots:
private:
bool setMovingAddedFiles();
void finishMoving(bool result);
+ QString convertCompressionMethod(const QString &method);
enum ParseState {
ParseStateHeader = 0,
@@ -59,6 +60,7 @@ private:
int m_linesComment;
QString m_tempComment;
+ QStringList m_compressionMethods;
};
#endif // CLIPLUGIN_H
diff --git a/plugins/libarchive/libarchiveplugin.cpp b/plugins/libarchive/libarchiveplugin.cpp
index a7ce255..6f2c6ad 100644
--- a/plugins/libarchive/libarchiveplugin.cpp
+++ b/plugins/libarchive/libarchiveplugin.cpp
@@ -58,6 +58,10 @@ bool LibarchivePlugin::list()
}
qDebug(ARK) << "Detected compression filter:" << archive_filter_name(m_archiveReader.data(), 0);
+ QString compMethod = convertCompressionName(QString::fromUtf8(archive_filter_name(m_archiveReader.data(), 0)));
+ if (!compMethod.isEmpty()) {
+ emit compressionMethodFound(QStringList{compMethod});
+ }
m_cachedArchiveEntryCount = 0;
m_extractedFilesSize = 0;
@@ -531,4 +535,28 @@ void LibarchivePlugin::copyData(const QString& filename, struct archive *source,
}
}
+QString LibarchivePlugin::convertCompressionName(const QString &method)
+{
+ if (method == QLatin1String("gzip")) {
+ return QStringLiteral("GZip");
+ } else if (method == QLatin1String("bzip2")) {
+ return QStringLiteral("BZip2");
+ } else if (method == QLatin1String("xz")) {
+ return QStringLiteral("XZ");
+ } else if (method == QLatin1String("compress (.Z)")) {
+ return QStringLiteral("Compress");
+ } else if (method == QLatin1String("lrzip")) {
+ return QStringLiteral("LRZip");
+ } else if (method == QLatin1String("lzip")) {
+ return QStringLiteral("LZip");
+ } else if (method == QLatin1String("lz4")) {
+ return QStringLiteral("LZ4");
+ } else if (method == QLatin1String("lzop")) {
+ return QStringLiteral("lzop");
+ } else if (method == QLatin1String("lzma")) {
+ return QStringLiteral("LZMA");
+ }
+ return QString();
+}
+
#include "libarchiveplugin.moc"
diff --git a/plugins/libarchive/libarchiveplugin.h b/plugins/libarchive/libarchiveplugin.h
index 93a3a12..8eb0a20 100644
--- a/plugins/libarchive/libarchiveplugin.h
+++ b/plugins/libarchive/libarchiveplugin.h
@@ -90,6 +90,7 @@ protected:
private:
int extractionFlags() const;
+ QString convertCompressionName(const QString &method);
int m_cachedArchiveEntryCount;
qlonglong m_currentExtractedFilesSize;