File indexing completed on 2024-05-05 16:09:02

0001 /*
0002     This file is part of the KFileMetaData project
0003     SPDX-FileCopyrightText: 2016 Varun Joshi <varunj.1011@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #include "externalwriter.h"
0009 #include "properties.h"
0010 #include "propertyinfo.h"
0011 #include "kfilemetadata_debug.h"
0012 
0013 #include <QDir>
0014 #include <QProcess>
0015 #include <QJsonDocument>
0016 #include <QJsonObject>
0017 #include <QJsonArray>
0018 
0019 #define WRITER_TIMEOUT_MS 30000
0020 
0021 using namespace KFileMetaData;
0022 
0023 class KFileMetaData::ExternalWriterPrivate
0024 {
0025 public:
0026     QString path;
0027     QStringList writeMimetypes;
0028     QString mainPath;
0029 };
0030 
0031 
0032 ExternalWriter::ExternalWriter(QObject* parent)
0033     : WriterPlugin(parent),
0034       d_ptr(new ExternalWriterPrivate)
0035 {
0036 }
0037 
0038 ExternalWriter::ExternalWriter(const QString& pluginPath)
0039     : WriterPlugin(nullptr),
0040       d_ptr(new ExternalWriterPrivate)
0041 {
0042     Q_D(ExternalWriter);
0043     d->path = pluginPath;
0044 
0045     QDir pluginDir(pluginPath);
0046     QStringList pluginDirContents = pluginDir.entryList();
0047 
0048     if (!pluginDirContents.contains(QStringLiteral("manifest.json"))) {
0049         qCDebug(KFILEMETADATA_LOG) << "Path does not seem to contain a valid plugin";
0050         return;
0051     }
0052 
0053     QFile manifest(pluginDir.filePath(QStringLiteral("manifest.json")));
0054     manifest.open(QIODevice::ReadOnly);
0055     QJsonDocument manifestDoc = QJsonDocument::fromJson(manifest.readAll());
0056     if (!manifestDoc.isObject()) {
0057         qCDebug(KFILEMETADATA_LOG) << "Manifest does not seem to be a valid JSON Object";
0058         return;
0059     }
0060 
0061     QJsonObject rootObject = manifestDoc.object();
0062     const QJsonArray mimetypesArray = rootObject.value(QStringLiteral("mimetypes")).toArray();
0063     QStringList mimetypes;
0064     for (const QJsonValue &mimetype : mimetypesArray) {
0065         mimetypes << mimetype.toString();
0066     }
0067 
0068     d->writeMimetypes.append(mimetypes);
0069     d->mainPath = pluginDir.absoluteFilePath(rootObject[QStringLiteral("main")].toString());
0070 }
0071 
0072 ExternalWriter::~ExternalWriter() = default;
0073 
0074 QStringList ExternalWriter::writeMimetypes() const
0075 {
0076     Q_D(const ExternalWriter);
0077     return d->writeMimetypes;
0078 }
0079 
0080 void ExternalWriter::write(const WriteData& data)
0081 {
0082     Q_D(ExternalWriter);
0083     QJsonDocument writeData;
0084     QJsonObject rootObject;
0085     QJsonObject propertiesObject;
0086     QByteArray output;
0087     QByteArray errorOutput;
0088 
0089     const PropertyMultiMap properties = data.properties();
0090 
0091     for (auto i = properties.constBegin(); i != properties.constEnd(); ++i) {
0092         PropertyInfo propertyInfo(i.key());
0093         propertiesObject[propertyInfo.name()] = QJsonValue::fromVariant(i.value());
0094     }
0095 
0096     rootObject[QStringLiteral("path")] = QJsonValue(data.inputUrl());
0097     rootObject[QStringLiteral("mimetype")] = data.inputMimetype();
0098     rootObject[QStringLiteral("properties")] = propertiesObject;
0099     writeData.setObject(rootObject);
0100 
0101     QProcess writerProcess;
0102     writerProcess.start(d->mainPath, QStringList(), QIODevice::ReadWrite);
0103     writerProcess.write(writeData.toJson());
0104     writerProcess.closeWriteChannel();
0105     writerProcess.waitForFinished(WRITER_TIMEOUT_MS);
0106 
0107     errorOutput = writerProcess.readAllStandardError();
0108 
0109     if (writerProcess.exitStatus()) {
0110         qCDebug(KFILEMETADATA_LOG) << "Something went wrong while trying to write data";
0111         qCDebug(KFILEMETADATA_LOG) << errorOutput;
0112         return;
0113     }
0114 
0115     output = writerProcess.readAll();
0116 
0117     QJsonDocument writerExitData = QJsonDocument::fromJson(output);
0118     if (!writerExitData.isObject()) {
0119         return;
0120     }
0121     QJsonObject outputRootObject = writerExitData.object();
0122 
0123     if (outputRootObject[QStringLiteral("status")].toString() != QStringLiteral("OK")) {
0124         qCDebug(KFILEMETADATA_LOG) << outputRootObject[QStringLiteral("error")].toString();
0125         qCDebug(KFILEMETADATA_LOG) << errorOutput;
0126     }
0127 
0128 }
0129 
0130 #include "moc_externalwriter.cpp"