8#include "extractorcollection.h"
9#include "extractor_p.h"
10#include "extractorplugin.h"
11#include "externalextractor.h"
12#include "kfilemetadata_debug.h"
13#include "config-kfilemetadata.h"
15#include <KPluginMetaData>
16#include <QCoreApplication>
18#include <QMimeDatabase>
23class KFileMetaData::ExtractorCollectionPrivate
26 QMultiHash<QString, Extractor*> m_mimeExtractors;
28 std::vector<Extractor> m_allExtractors;
30 void findExtractors();
31 QList<Extractor*> getExtractors(
const QString& mimetype);
34ExtractorCollection::ExtractorCollection()
35 : d(new ExtractorCollectionPrivate)
40ExtractorCollection::~ExtractorCollection() =
default;
45 QList<Extractor*> plugins;
46 for (
auto& ex : d->m_allExtractors) {
47 if (ex.d->initPlugin()) {
54void ExtractorCollectionPrivate::findExtractors()
56 const QList<KPluginMetaData> kfilemetadataPlugins =
58 for (
const KPluginMetaData &plugin : kfilemetadataPlugins) {
60 extractor.d->m_pluginPath = plugin.fileName();
61 extractor.setAutoDeletePlugin(Extractor::DoNotDeletePlugin);
63 if (!plugin.rawData().isEmpty()) {
64 const auto metadataMap = plugin.rawData().toVariantMap();
65 if (!metadataMap.contains(QLatin1String(
"Name"))) {
66 qCWarning(KFILEMETADATA_LOG) <<
"Found plugin with invalid metadata (missing Name):" << extractor.d->m_pluginPath;
67 }
else if (!metadataMap.contains(QLatin1String(
"MimeTypes"))) {
68 qCWarning(KFILEMETADATA_LOG) <<
"Found plugin with invalid metadata (missing MimeTypes):" << extractor.d->m_pluginPath;
70 qCWarning(KFILEMETADATA_LOG) <<
"Found plugin with metadata:" << extractor.d->m_pluginPath;
71 extractor.setMetaData(metadataMap);
72 m_allExtractors.push_back(std::move(extractor));
75 qCWarning(KFILEMETADATA_LOG) <<
"Found plugin without metadata (deprecated):" << extractor.d->m_pluginPath;
76 if (extractor.d->initPlugin() && !extractor.mimetypes().
isEmpty()) {
77 m_allExtractors.push_back(std::move(extractor));
82 QStringList externalPlugins;
83 const QDir externalPluginDir(QStringLiteral(LIBEXEC_INSTALL_DIR
"/kfilemetadata/externalextractors"));
84 qCDebug(KFILEMETADATA_LOG) <<
"Searching for external extractors:" << externalPluginDir.path();
87 for (
const QString &externalPlugin : externalPluginEntryList) {
88 if (externalPlugins.
contains(externalPlugin)) {
89 qCDebug(KFILEMETADATA_LOG) <<
"Skipping duplicate - " << externalPluginDir.path() <<
":" << externalPlugin;
93 qCDebug(KFILEMETADATA_LOG) <<
"Adding plugin - " << externalPluginDir.path() <<
":" << externalPlugin;
94 externalPlugins << externalPlugin;
97 auto pluginPath = externalPluginDir.absoluteFilePath(externalPlugin);
98 ExternalExtractor *plugin =
new ExternalExtractor(pluginPath);
99 if (plugin && !plugin->mimetypes().
isEmpty()) {
100 extractor.setExtractorPlugin(plugin);
101 extractor.setAutoDeletePlugin(Extractor::AutoDeletePlugin);
102 m_allExtractors.push_back(std::move(extractor));
105 externalPlugins.
clear();
107 for (Extractor& extractor : m_allExtractors) {
108 auto pluginProperties = extractor.extractorProperties();
109 if (!pluginProperties.isEmpty()) {
110 auto mimetypeProperties = pluginProperties[QLatin1String(
"MimeTypes")];
112 qCWarning(KFILEMETADATA_LOG) <<
"Invalid MimeTypes property in" << pluginProperties;
114 const auto mimetypes = mimetypeProperties.toMap();
115 for (
const auto [mimetype, v] : mimetypes.asKeyValueRange()) {
116 m_mimeExtractors.insert(mimetype, &extractor);
119 }
else if (extractor.d->m_plugin) {
120 const auto mimetypes = extractor.mimetypes();
121 for (
const QString &mimetype : mimetypes) {
122 m_mimeExtractors.insert(mimetype, &extractor);
128QList<Extractor*> ExtractorCollectionPrivate::getExtractors(
const QString& mimetype)
130 QList<Extractor*> extractors = m_mimeExtractors.values(mimetype);
133 qCDebug(KFILEMETADATA_LOG) <<
"No extractor for" <<
mimetype;
137 qCDebug(KFILEMETADATA_LOG) <<
"Fetching extractors for" <<
mimetype;
138 Extractor* failed =
nullptr;
139 for (
auto ex : extractors) {
140 if (!ex->d->initPlugin()) {
150 auto it = m_mimeExtractors.begin();
151 while (it != m_mimeExtractors.end()) {
152 if (it.value() == failed) {
153 it = m_mimeExtractors.erase(it);
158 return getExtractors(mimetype);
173 for (
const auto &ancestor : ancestors) {
179 qCDebug(KFILEMETADATA_LOG) <<
"Using inherited mimetype" << ancestor <<
"for" << mimetype;
KIOCORE_EXPORT MimetypeJob * mimetype(const QUrl &url, JobFlags flags=DefaultFlags)
bool isEmpty() const const
void push_back(parameter_type value)
QMimeType mimeTypeForName(const QString &nameOrAlias) const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const