diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,11 @@ include(FindGettext) +# Find KArchive +find_package(KF5Archive) +set_package_properties(KF5Archive PROPERTIES + TYPE OPTIONAL) + # Find taglib set(TAGLIB_MIN_VERSION "1.5") find_package(Taglib ${TAGLIB_MIN_VERSION}) @@ -80,6 +85,7 @@ macro_bool_to_01(TAGLIB_FOUND HAVE_TAGLIB) macro_bool_to_01(EXIV2_FOUND HAVE_EXIV2) macro_bool_to_01(PoDoFo_FOUND HAVE_PODOFO) +macro_bool_to_01(KF5Archive_FOUND HAVE_KARCHIVE) macro_bool_to_01(FREETYPE_FOUND HAVE_FREETYPE) configure_file(config-krename.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-krename.h) diff --git a/config-krename.h.cmake b/config-krename.h.cmake --- a/config-krename.h.cmake +++ b/config-krename.h.cmake @@ -9,6 +9,9 @@ /* have PoDoFo */ #define HAVE_PODOFO ${HAVE_PODOFO} +/* have KArchive */ +#define HAVE_KARCHIVE ${HAVE_KARCHIVE} + /* have Freetype */ #define HAVE_FREETYPE ${HAVE_FREETYPE} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -91,6 +91,12 @@ ) endif() +if(KF5Archive_FOUND) + set(krename_SRCS ${krename_SRCS} + odfplugin.cpp + ) +endif() + ki18n_wrap_ui(krename_SRCS customfilenamedlg.ui @@ -141,6 +147,12 @@ ${PoDoFo_LIBRARIES} ) endif() +if(KF5Archive_FOUND) + target_link_libraries(krename + Qt5::Xml + KF5::Archive + ) +endif() if(FREETYPE_FOUND) target_link_libraries(krename ${FREETYPE_LIBRARIES} diff --git a/src/odfplugin.h b/src/odfplugin.h new file mode 100644 --- /dev/null +++ b/src/odfplugin.h @@ -0,0 +1,49 @@ +/*************************************************************************** + odfplugin.h - description + ------------------- + begin : Wed June 20th 2018 + copyright : (C) 2018 by Friedrich W. H. Kossebau + email : kossebau@kde.org + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef ODF_PLUGIN_H +#define ODF_PLUGIN_H + +#include "fileplugin.h" + +class OdfPlugin : public FilePlugin +{ +public: + explicit OdfPlugin(PluginLoader *loader); + +public: // FilePlugin API + virtual QString processFile(BatchRenamer *b, int index, const QString &filenameOrToken, EPluginType eCurrentType); + +public: // Plugin API + virtual const QStringList &help() const; + +private: + QStringList m_help; + + // tokens are first set to real string, then to lowercase variant for comparison usage in processFile() + // see OdfPlugin constructor + QString m_creatorToken; + QString m_keywordsToken; + QString m_subjectToken; + QString m_titleToken; + QString m_generatorToken; + QString m_languageToken; + QString m_pageCountToken; + QString m_wordCountToken; +}; + +#endif // ODF_PLUGIN_H diff --git a/src/odfplugin.cpp b/src/odfplugin.cpp new file mode 100644 --- /dev/null +++ b/src/odfplugin.cpp @@ -0,0 +1,168 @@ +/*************************************************************************** + odfplugin.cpp - description + ------------------- + begin : Wed June 20th 2018 + copyright : (C) 2018 by Friedrich W. H. Kossebau + email : kossebau@kde.org + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include "odfplugin.h" + +#include "batchrenamer.h" +#include "tokenhelpdialog.h" +// KF +#include +// Qt +#include +#include + +QString createHelpString(const QString& tokenId, const QString& description) +{ + return QLatin1Char('[') + tokenId + QLatin1Char(']') + TokenHelpDialog::getTokenSeparator() + description; +} + +OdfPlugin::OdfPlugin(PluginLoader *loader) + : FilePlugin(loader) + , m_creatorToken("odfCreator") + , m_keywordsToken("odfKeywords") + , m_subjectToken("odfSubject") + , m_titleToken("odfTitle") + , m_generatorToken("odfGenerator") + , m_languageToken("odfLanguage") + , m_pageCountToken("odfPageCount") + , m_wordCountToken("odfWordCount") +{ + m_name = i18n("OpenDocument Fprmat (ODT, ODS, ODP) Plugin"); + m_comment = i18n("This plugin supports reading metadata from " + "files in an OpenDocument format."); + + // there is no generic ODF icon, so use the text one for now + m_icon = "application-vnd.oasis.opendocument.text"; + + addSupportedToken(m_creatorToken); + addSupportedToken(m_keywordsToken); + addSupportedToken(m_subjectToken); + addSupportedToken(m_titleToken); + addSupportedToken(m_generatorToken); + addSupportedToken(m_languageToken); + addSupportedToken(m_pageCountToken); + addSupportedToken(m_wordCountToken); + + m_help = QStringList { + createHelpString(m_creatorToken, i18n("Creator of the ODF file")), + createHelpString(m_keywordsToken, i18n("Keywords of the ODF file")), + createHelpString(m_subjectToken, i18n("Subject of the ODF file")), + createHelpString(m_titleToken, i18n("Title of the ODF file")), + createHelpString(m_generatorToken, i18n("Generator of the ODF file")), + createHelpString(m_languageToken, i18n("Language of the ODF file")), + createHelpString(m_pageCountToken, i18n("Number of pages in the ODF file")), + createHelpString(m_wordCountToken, i18n("Number of words in the ODF file")), + }; + + // prepare for case-insensitive comparison + m_creatorToken = m_creatorToken.toLower(); + m_keywordsToken = m_keywordsToken.toLower(); + m_subjectToken = m_subjectToken.toLower(); + m_titleToken = m_titleToken.toLower(); + m_generatorToken = m_generatorToken.toLower(); + m_languageToken = m_languageToken.toLower(); + m_pageCountToken = m_pageCountToken.toLower(); + m_wordCountToken = m_wordCountToken.toLower(); +} + +QString OdfPlugin::processFile(BatchRenamer *b, int index, const QString &filenameOrToken, EPluginType) +{ + const QString token = filenameOrToken.toLower(); + + if (!supports(token)) { + return QString(""); + } + + const QString filename = (*b->files())[index].srcUrl().path(); + KZip zip(filename); + if (!zip.open(QIODevice::ReadOnly)) { + return QString(""); + } + + const KArchiveDirectory* directory = zip.directory(); + if (!directory) { + return QString(""); + } + + // we need a meta xml file in the archive! + const auto metaXml = directory->entry(QStringLiteral("meta.xml")); + if (!metaXml || !metaXml->isFile()) { + return QString(""); + } + + QDomDocument metaData(QStringLiteral("metaData")); + bool success = metaData.setContent(static_cast(metaXml)->data()); + if (!success) { + return QString(""); + } + + // parse metadata ... + QDomElement docElem = metaData.documentElement(); + QDomNode n = docElem.firstChild().firstChild(); // ... ... content + while (!n.isNull()) { + QDomElement e = n.toElement(); + if (!e.isNull()) { + const QString tagName = e.tagName(); + + // Dublin Core + if (tagName == QLatin1String("dc:subject")) { + if (token == m_subjectToken) { + return e.text(); + } + } else if (tagName == QLatin1String("dc:title")) { + if (token == m_titleToken) { + return e.text(); + } + } else if (tagName == QLatin1String("dc:creator")) { + if (token == m_creatorToken) { + return e.text(); + } + } else if (tagName == QLatin1String("dc:language")) { + if (token == m_languageToken) { + return e.text(); + } + } + + // Meta Properties + else if (tagName == QLatin1String("meta:document-statistic")) { + if (token == m_pageCountToken) { + return e.attribute(QStringLiteral("meta:page-count")); + } + + if (token == m_wordCountToken) { + return e.attribute(QStringLiteral("meta:word-count")); + } + } else if (tagName == QLatin1String("meta:keyword")) { + if (token == m_keywordsToken) { + return e.text(); + } + } else if (tagName == QLatin1String("meta:generator")) { + if (token == m_generatorToken) { + return e.text(); + } + } + } + n = n.nextSibling(); + } + + return QString(""); +} + +const QStringList & OdfPlugin::help() const +{ + return m_help; +} diff --git a/src/pluginloader.cpp b/src/pluginloader.cpp --- a/src/pluginloader.cpp +++ b/src/pluginloader.cpp @@ -45,6 +45,9 @@ #if HAVE_PODOFO # include "podofoplugin.h" #endif // HAVE_PODOFO +#if HAVE_KARCHIVE +# include "odfplugin.h" +#endif // HAVE_KARCHIVE #if HAVE_FREETYPE # include "fontplugin.h" #endif // HAVE_FREETYPE @@ -155,6 +158,9 @@ #if HAVE_PODOFO m_plugins.append(new PodofoPlugin(this)); #endif // HAVE_PODOFO +#if HAVE_KARCHIVE + m_plugins.append(new OdfPlugin(this)); +#endif // HAVE_KARCHIVE m_plugins.append(new TranslitPlugin(this)); m_plugins.append(new SnumPlugin(this)); //this->loadFilePlugins();