| diff --git a/plugins/cliunarchiverplugin/kerfuffle_cliunarchiver.desktop b/plugins/cliunarchiverplugin/kerfuffle_cliunarchiver.desktop |
| new file mode 100644 |
| index 0000000..2b5bd9e |
| |
| |
| @@ -0,0 +1,15 @@ |
| +[Desktop Entry] |
| +Type=Service |
| +X-KDE-ServiceTypes=Kerfuffle/Plugin |
| +X-KDE-Library=kerfuffle_cliunarchiver |
| +X-KDE-PluginInfo-Author=Luke Shumaker |
| +X-KDE-PluginInfo-Email=lukeshu@sbcglobal.net |
| +X-KDE-PluginInfo-Name= kerfuffle_cliunarchiver |
| +X-KDE-PluginInfo-Version=0.0.1 |
| +X-KDE-PluginInfo-Website=http://www.kde.org |
| +X-KDE-PluginInfo-License=GPLv2+ |
| +X-KDE-Priority=150 |
| +X-KDE-Kerfuffle-APIRevision=1 |
| +X-KDE-Kerfuffle-ReadWrite=false |
| +Name=The Unarchiver plugin |
| +MimeType=application/x-rar; |
| diff --git a/plugins/cliunarchiverplugin/cliplugin.cpp b/plugins/cliunarchiverplugin/cliplugin.cpp |
| new file mode 100644 |
| index 0000000..e0adcf7 |
| |
| |
| @@ -0,0 +1,174 @@ |
| + /* |
| + * ark -- archiver for the KDE project |
| + * |
| + * Copyright (C) 2011 Luke Shumaker <lukeshu@sbcglobal.net> |
| + * |
| + * This program is free software; you can redistribute it and/or |
| + * modify it under the terms of the GNU General Public License |
| + * as published by the Free Software Foundation; either version 2 |
| + * of the License, or (at your option) any later version. |
| + * |
| + * This program is distributed in the hope that it will be useful, |
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| + * GNU General Public License for more details. |
| + * |
| + * You should have received a copy of the GNU General Public License |
| + * along with this program; if not, write to the Free Software |
| + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| + * |
| + */ |
| + |
| +//#include "app/logging.h" |
| +#include "kerfuffle/cliinterface.h" |
| +#include "kerfuffle/kerfuffle_export.h" |
| + |
| +#include <QLoggingCategory> |
| + |
| +#include <QDateTime> |
| +#include <QDir> |
| +#include <QRegExp> |
| +#include <QString> |
| +#include <QStringList> |
| +#include <KPluginFactory> |
| + |
| +using namespace Kerfuffle; |
| +Q_LOGGING_CATEGORY(KERFUFFLE_PLUGIN, "ark.kerfuffle.cliunar", QtWarningMsg) |
| + |
| +class CliPlugin: public CliInterface |
| +{ |
| +public: |
| + explicit CliPlugin(QObject *parent, const QVariantList & args) |
| + : CliInterface(parent, args) { |
| + m_indentLevel = 0; |
| + } |
| + |
| + virtual ~CliPlugin() { |
| + } |
| + |
| + virtual ParameterList parameterList() const { |
| + static ParameterList p; |
| + if (p.isEmpty()) { |
| + /* Limitations: |
| + * 01 - creates an empty file upon entering wrong password |
| + * 02 - unar detects if output is being redirected and then does not accept any input |
| + */ |
| + |
| + ///////////////[ COMMON ]///////////// |
| + |
| + p[CaptureProgress] = false; |
| + p[PasswordPromptPattern] = QLatin1String("Password (will not be shown): "); |
| + |
| + ///////////////[ LIST ]///////////// |
| + |
| + p[ListProgram] = QLatin1String("lsar"); |
| + p[ListArgs] = QStringList() << QLatin1String("-json") << QLatin1String("$Archive"); |
| + |
| + ///////////////[ EXTRACT ]///////////// |
| + |
| + p[ExtractProgram] = QLatin1String("unar"); |
| + p[ExtractArgs] = QStringList() << QLatin1String("$Archive") << QLatin1String("$Files") << QLatin1String("$PasswordSwitch") << QLatin1String("$RootNodeSwitch"); |
| + p[NoTrailingSlashes] = true; |
| + p[PasswordSwitch] = QStringList() << QLatin1String("-password") << QLatin1String("$Password"); |
| + p[RootNodeSwitch] = QStringList() << QLatin1String("-output-directory") << QLatin1String("$Path"); |
| + p[FileExistsExpression] = QLatin1String("^\\\"(.+)\\\" already exists."); |
| + p[FileExistsInput] = QStringList() |
| + << QLatin1String("o") //overwrite |
| + << QLatin1String("s") //skip |
| + << QLatin1String("O") //overwrite all |
| + << QLatin1String("S") //autoskip |
| + << QLatin1String("q") //cancel |
| + ; |
| + |
| + ///////////////[ DELETE ]///////////// |
| + |
| + p[DeleteProgram] = QLatin1String("x-fakeprogram"); |
| + //p[DeleteArgs] = |
| + |
| + ///////////////[ ADD ]///////////// |
| + |
| + p[AddProgram] = QLatin1String("x-fakeprogram"); |
| + //p[AddArgs] = |
| + |
| + ///////////////[ ERRORS ]///////////// |
| + |
| + p[ExtractionFailedPatterns] = QStringList() |
| + << QLatin1String("Failed! \\((.+)\\)$") |
| + << QLatin1String("Segmentation fault$"); |
| + |
| + p[WrongPasswordPatterns] = QStringList() |
| + << QLatin1String("Failed! \\((.+)\\)$"); |
| + } |
| + return p; |
| + } |
| + |
| + QString m_entryFilename, m_internalId; |
| + ArchiveEntry m_currentEntry; |
| + int m_indentLevel; |
| + |
| + bool readListLine(const QString &line) { |
| + /* lsar will give us JSON output. However, we actually parse based on |
| + * the indentation. Ugly, I know, but |
| + * 1. It's easier |
| + * 2. lsar's JSON is invalid JSON, so actual parsers bork. |
| + */ |
| + |
| + int spaces; |
| + for(spaces=0;(spaces<line.size())&&(line[spaces]==QLatin1Char(' '));spaces++){} |
| + // Since this is so ugly anyway, I'm not even going to check to |
| + // make sure that spaces is even. I mean, what would I do about it? |
| + int m_newIndentLevel = spaces/2; |
| + |
| + if (m_newIndentLevel>m_indentLevel) { |
| + if (m_newIndentLevel==3) { |
| + m_currentEntry.clear(); |
| + m_currentEntry[IsDirectory] = false; |
| + } |
| + } else if (m_newIndentLevel<m_indentLevel) { |
| + if ( (m_newIndentLevel<3) && (m_indentLevel>=3) ) { |
| + EntryMetaDataType index = IsDirectory; |
| + if (m_currentEntry[index].toBool()) { |
| + m_currentEntry[FileName].toString().append(QLatin1String("/")); |
| + } |
| + qCDebug(KERFUFFLE_PLUGIN) << "Added entry:" << m_currentEntry; |
| + entry(m_currentEntry); |
| + } |
| + } |
| + m_indentLevel = m_newIndentLevel; |
| + |
| + QRegExp rx(QLatin1String("^\\s*\"([^\"]*)\": (.*),$")); |
| + if (rx.indexIn(line) >= 0) { |
| + QRegExp rx_unquote(QLatin1String("^\"(.*)\"$")); |
| + QString key = rx.cap(1); |
| + QString value = rx.cap(2); |
| + |
| + if (false) { |
| + } else if (key==QLatin1String("XADFileName")) { |
| + rx_unquote.indexIn(value); |
| + m_currentEntry[FileName] = m_currentEntry[InternalID] = rx_unquote.cap(1); |
| + } else if (key==QLatin1String("XADFileSize")) { |
| + m_currentEntry[Size] = value.toInt(); |
| + } else if (key==QLatin1String("XADCompressedSize")) { |
| + m_currentEntry[CompressedSize] = value.toInt(); |
| + } else if (key==QLatin1String("XADLastModificationDate")) { |
| + QDateTime ts(QDate::fromString(value, QLatin1String("\"YYYY-MM-DD hh:mm:ss"))); |
| + m_currentEntry[Timestamp] = ts; |
| + } else if (key==QLatin1String("XADIsDirectory")) { |
| + m_currentEntry[IsDirectory] = (value==QLatin1String("1")); |
| + } else if (key==QLatin1String("RARCRC32")) { |
| + m_currentEntry[CRC] = value.toInt(); |
| + } else if (key==QLatin1String("RARCompressionMethod")) { |
| + m_currentEntry[Method] = value.toInt(); |
| + } else if (key==QLatin1String("Encrypted")) { |
| + m_currentEntry[IsPasswordProtected] = (value.toInt() != 0); |
| + } |
| + // TODO: add RAR version. ([Version]) |
| + } |
| + |
| + return true; |
| + } |
| +}; |
| + |
| +K_PLUGIN_FACTORY(CliPluginFactory, registerPlugin<CliPlugin>(); ) |
| + |
| +#include "cliplugin.moc" |
| + |
| diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt |
| index 3619412..6368839 100644 |
| |
| |
| @@ -1,5 +1,6 @@ |
| add_subdirectory( libarchive ) |
| add_subdirectory( clirarplugin ) |
| +add_subdirectory( cliunarchiverplugin ) |
| add_subdirectory( cli7zplugin ) |
| add_subdirectory( clizipplugin ) |
| add_subdirectory( libsinglefileplugin ) |
| diff --git a/plugins/cliunarchiverplugin/CMakeLists.txt b/plugins/cliunarchiverplugin/CMakeLists.txt |
| new file mode 100644 |
| index 0000000..ccd52e7 |
| |
| |
| @@ -0,0 +1,21 @@ |
| + |
| +include_directories( |
| + ${CMAKE_CURRENT_SOURCE_DIR}/../.. |
| + ${CMAKE_CURRENT_BINARY_DIR}/../.. |
| + ) |
| + |
| +########### next target ############### |
| + |
| +set(kerfuffle_cliunarchiver_SRCS cliplugin.cpp) |
| + |
| +add_library(kerfuffle_cliunarchiver MODULE ${kerfuffle_cliunarchiver_SRCS}) |
| + |
| +target_link_libraries(kerfuffle_cliunarchiver KF5::KIOCore kerfuffle ) |
| + |
| + |
| + |
| +########### install files ############### |
| + |
| +install(TARGETS kerfuffle_cliunarchiver DESTINATION ${PLUGIN_INSTALL_DIR} ) |
| +install( FILES kerfuffle_cliunarchiver.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) |
| + |