File indexing completed on 2025-01-19 03:56:03

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2020-11-28
0007  * Description : ExifTool process stream parser - private container.
0008  *
0009  * SPDX-FileCopyrightText: 2020-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "exiftoolparser_p.h"
0016 
0017 namespace Digikam
0018 {
0019 
0020 ExifToolParser::Private::Private(ExifToolParser* const q)
0021     : pp          (q),
0022       proc        (nullptr),
0023       async       (false)
0024 {
0025     argsFile.setAutoRemove(false);
0026 }
0027 
0028 ExifToolParser::Private::~Private()
0029 {
0030     if (argsFile.exists())
0031     {
0032         argsFile.remove();
0033     }
0034 }
0035 
0036 void ExifToolParser::Private::prepareProcess()
0037 {
0038     currentPath.clear();
0039     errorString.clear();
0040     exifToolData.clear();
0041 }
0042 
0043 bool ExifToolParser::Private::startProcess(const QByteArrayList& cmdArgs,
0044                                            ExifToolProcess::Action cmdAction)
0045 {
0046     // Send command to ExifToolProcess
0047 
0048     int cmdId = proc->command(cmdArgs, cmdAction);
0049 
0050     if (cmdId == 0)
0051     {
0052         qCWarning(DIGIKAM_METAENGINE_LOG) << "ExifTool cannot be sent:"
0053                                           << actionString(cmdAction);
0054 
0055         return false;
0056     }
0057 
0058     qCDebug(DIGIKAM_METAENGINE_LOG) << "ExifTool" << actionString(cmdAction)
0059                                     << cmdArgs.join(QByteArray(" "));
0060 
0061     if (async)
0062     {
0063         QMutexLocker locker(&mutex);
0064 
0065         asyncRunning << cmdId;
0066 
0067         return true;
0068     }
0069 
0070     ExifToolProcess::Result result = proc->getExifToolResult(cmdId);
0071 
0072     while ((result.cmdNumber != cmdId) &&
0073            (result.cmdStatus != ExifToolProcess::FINISH_RESULT))
0074     {
0075         result = proc->waitForExifToolResult(cmdId);
0076 
0077         if ((result.cmdNumber == cmdId) && result.waitError)
0078         {
0079             qCWarning(DIGIKAM_METAENGINE_LOG) << "ExifTool timed out:"
0080                                               << actionString(cmdAction);
0081 
0082             return false;
0083         }
0084     }
0085 
0086     jumpToResultCommand(result, cmdId);
0087 
0088     return true;
0089 }
0090 
0091 QByteArray ExifToolParser::Private::filePathEncoding(const QFileInfo& fi) const
0092 {
0093     return (QDir::toNativeSeparators(fi.filePath()).toUtf8());
0094 }
0095 
0096 void ExifToolParser::Private::jumpToResultCommand(const ExifToolProcess::Result& result, int cmdId)
0097 {
0098     if (result.cmdNumber != cmdId)
0099     {
0100         return;
0101     }
0102 
0103     switch (result.cmdStatus)
0104     {
0105         case ExifToolProcess::COMMAND_RESULT:
0106         {
0107             pp->cmdCompleted(result);
0108             break;
0109         }
0110 
0111         case ExifToolProcess::ERROR_RESULT:
0112         {
0113             pp->errorOccurred(result,
0114                               proc->exifToolError(),
0115                               proc->exifToolErrorString());
0116             break;
0117         }
0118 
0119         case ExifToolProcess::FINISH_RESULT:
0120         {
0121             pp->finished();
0122             break;
0123         }
0124     }
0125 
0126     if (currentPath.isEmpty())
0127     {
0128         qCDebug(DIGIKAM_METAENGINE_LOG) << "ExifTool complete"
0129                                         << actionString(result.cmdAction);
0130     }
0131     else
0132     {
0133         qCDebug(DIGIKAM_METAENGINE_LOG) << "ExifTool complete"
0134                                         << actionString(result.cmdAction) << "for" << currentPath;
0135     }
0136 }
0137 
0138 QString ExifToolParser::Private::actionString(int cmdAction) const
0139 {
0140     switch (cmdAction)
0141     {
0142         case ExifToolProcess::LOAD_METADATA:
0143         {
0144             return QLatin1String("Load Metadata");
0145         }
0146 
0147         case ExifToolProcess::LOAD_CHUNKS:
0148         {
0149             return QLatin1String("Load Chunks");
0150         }
0151 
0152         case ExifToolProcess::APPLY_CHANGES:
0153         {
0154             return QLatin1String("Apply Changes");
0155         }
0156 
0157         case ExifToolProcess::APPLY_CHANGES_EXV:
0158         {
0159             return QLatin1String("Apply Changes EXV");
0160         }
0161 
0162         case ExifToolProcess::APPLY_METADATA_FILE:
0163         {
0164             return QLatin1String("Apply Metadata File");
0165         }
0166 
0167         case ExifToolProcess::READ_FORMATS:
0168         {
0169             return QLatin1String("Readable Formats");
0170         }
0171 
0172         case ExifToolProcess::WRITE_FORMATS:
0173         {
0174             return QLatin1String("Writable Formats");
0175         }
0176 
0177         case ExifToolProcess::TRANSLATIONS_LIST:
0178         {
0179             return QLatin1String("Translations List");
0180         }
0181 
0182         case ExifToolProcess::TAGS_DATABASE:
0183         {
0184             return QLatin1String("Tags Database");
0185         }
0186 
0187         case ExifToolProcess::VERSION_STRING:
0188         {
0189             return QLatin1String("Version String");
0190         }
0191 
0192         case ExifToolProcess::COPY_TAGS:
0193         {
0194             return QLatin1String("Copy Tags");
0195         }
0196 
0197         case ExifToolProcess::TRANS_TAGS:
0198         {
0199             return QLatin1String("Translate Tags");
0200         }
0201 
0202         default: // ExifToolProcess::NO_ACTION
0203         {
0204             break;
0205         }
0206     }
0207 
0208     return QString();
0209 }
0210 
0211 } // namespace Digikam