File indexing completed on 2024-04-28 03:43:17

0001 /*
0002     SPDX-FileCopyrightText: 2021 Kwon-Young Choi <kwon-young.choi@hotmail.fr>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include <lilxml.h>
0010 #include "indi/indistd.h"
0011 #include <QDebug>
0012 #include <QFileInfo>
0013 
0014 class QString;
0015 class SchedulerJob;
0016 
0017 namespace Ekos
0018 {
0019 
0020 class SequenceJob;
0021 
0022 class PlaceholderPath
0023 {
0024     public:
0025         typedef enum
0026         {
0027             PP_FORMAT,     // QString
0028             PP_SUFFIX,     // uint
0029             PP_DIRECTORY,  // QString
0030             PP_TARGETNAME, // QString
0031             PP_FRAMETYPE,  // CCDFrameType (uint)
0032             PP_DARKFLAT,   // bool
0033             PP_EXPOSURE,   // double
0034             PP_FILTER,     // QString
0035             PP_BIN,        // Point
0036             PP_GAIN,       // double
0037             PP_ISO,        // uint
0038             PP_OFFSET,     // double
0039             PP_PIERSIDE,   // ISD::Mount::PierSide (int)
0040             PP_TEMPERATURE // double
0041         } PathProperty;
0042 
0043         typedef enum
0044         {
0045             PP_TYPE_NONE,
0046             PP_TYPE_STRING,
0047             PP_TYPE_BOOL,
0048             PP_TYPE_UINT,
0049             PP_TYPE_DOUBLE,
0050             PP_TYPE_POINT
0051         } PathPropertyType;
0052 
0053         PlaceholderPath(const QString &seqFilename);
0054         PlaceholderPath();
0055         ~PlaceholderPath();
0056 
0057         /**
0058          * @brief processJobInfo loads the placeHolderPath with properties from the SequenceJob
0059          * @param sequence job to be processed
0060          */
0061         void processJobInfo(SequenceJob *job);
0062 
0063         /**
0064          * @brief addjob creates the directory suffix for the SequenceJob
0065          * @param sequence job to be processed
0066          * @param targetname name of the celestial target
0067          */
0068         void addJob(SequenceJob *job, const QString &targetName);
0069 
0070         /**
0071          * @brief constructPrefix creates the prefix for the SequenceJob
0072          * @param sequence job to be processed
0073          * @param imagePrefix sequence job prefix string
0074          * @return QString containing the processed prefix string
0075          */
0076         QString constructPrefix(const SequenceJob *job, const QString &imagePrefix);
0077 
0078         /**
0079          * @brief generateFilename performs the data for tag substituion in the filename
0080          * @param sequence job to be processed
0081          * @param targetName name of the celestial target
0082          * @param local Generate local filename, otherwise, generate remote filename
0083          * @param batch_mode if true dateTime tag is returned with placeholders
0084          * @param nextSequenceID file sequence number count
0085          * @param extension filename extension
0086          * @param filename passed in with tags
0087          * @param glob used in batch mode
0088          * @return QString containing formatted filename
0089          *
0090          * This overload of the function supports calls from the capture class
0091          */
0092         QString generateSequenceFilename(const SequenceJob &job, bool local, const bool batch_mode,
0093                                  const int nextSequenceID, const QString &extension, const QString &filename,
0094                                  const bool glob = false, const bool gettingSignature = false);
0095 
0096         /**
0097          * @brief generateFilename performs the data for tag substituion in the filename
0098          * @param sequence job to be processed
0099          * @param local Generate local filename, otherwise, generate remote filename
0100          * @param batch_mode if true dateTime tag is returned with placeholders
0101          * @param nextSequenceID file sequence number count
0102          * @param extension filename extension
0103          * @param filename passed in with tags
0104          * @param glob used in batch mode
0105          * @return QString containing formatted filename
0106          *
0107          * This overload of the function supports calls from the indicamera class
0108          */
0109         QString generateOutputFilename(const bool local, const bool batch_mode, const int nextSequenceID, const QString &extension, const QString &filename,
0110                                  const bool glob = false, const bool gettingSignature = false) const;
0111 
0112         /**
0113          * @brief setGenerateFilenameSettings loads the placeHolderPath with settings from the passed job
0114          * @param sequence job to be processed
0115          */
0116         void setGenerateFilenameSettings(const SequenceJob &job)
0117         {
0118             setGenerateFilenameSettings(job, m_PathPropertyMap, true, false);
0119         }
0120 
0121         /**
0122          * @brief remainingPlaceholders finds placeholder tags in filename
0123          * @param filename string to be processed
0124          * @return a QStringList of the remaining placeholders
0125          */
0126         static QStringList remainingPlaceholders(const QString &filename);
0127 
0128         /**
0129          * @brief remainingPlaceholders provides a list of already existing fileIDs from passed sequence job
0130          * @param sequence job to be processed
0131          * @return a QStringList of the existing fileIDs
0132          */
0133         QList<int> getCompletedFileIds(const SequenceJob &job);
0134 
0135         /**
0136          * @brief getCompletedFiles provides the number of existing fileIDs
0137          * @param sequence job to be processed
0138          * @return number of existing fileIDs
0139          */
0140         int getCompletedFiles(const SequenceJob &job);
0141 
0142         /**
0143          * @brief getCompletedFiles determines the number of files matching the given path pattern
0144          */
0145         static int getCompletedFiles(const QString &path);
0146 
0147         /**
0148          * @brief checkSeqBoundary provides the ID to use for the next file
0149          * @param sequence job to be processed
0150          * @return number for the next fileIDs
0151          */
0152         int checkSeqBoundary(const SequenceJob &job);
0153 
0154         /**
0155          * @brief Property type definitions
0156          */
0157         static PathPropertyType propertyType(PathProperty property);
0158 
0159         /**
0160          * @brief defaultFormat provides a default format string
0161          * @param useFilter whether to include the filter in the format string
0162          * @param useExposure whether to include the exposure in the format string
0163          * @param useTimestamp whether to include the timestamp in the format string
0164          * @return the format string
0165          */
0166         static QString defaultFormat(bool useFilter, bool useExposure, bool useTimestamp);
0167 
0168         /**
0169          * @brief repairFilename is an emergency method used when an unexpected filename collision is detected.
0170          * @param filename the filename which already exists on disk.
0171          * @return Returns the repaired filename. If it was unable to repair, it returns the filename passed in.
0172          */
0173         static QString repairFilename(const QString &filename);
0174 
0175         // shortcuts
0176         static bool isFilterEnabled(const QString format)
0177         {
0178             return format.contains("%F");
0179         }
0180         static bool isExpEnabled(const QString format)
0181         {
0182             return format.contains("%e");
0183         }
0184         static bool isTsEnabled(const QString format)
0185         {
0186             return format.contains("%D");
0187         }
0188 
0189 private:
0190         // TODO use QVariantMap or QVariantList instead of passing this many args.
0191         QString generateFilenameInternal(const QMap<PathProperty, QVariant> &pathPropertyMap, const bool local, const bool batch_mode, const int nextSequenceID, const QString &extension,
0192                                  const QString &filename, const bool glob = false, const bool gettingSignature = false) const;
0193 
0194         /**
0195          * @brief setGenerateFilenameSettings Generate property map from job settings. In case that gettingSignature is set to true,
0196          * only explicitly defined parameters from the job's core properties are filled. This is necessary for a proper cooperation with the
0197          * scheduler, that generates signatures for captured files without proper knowledge of the involved camera and therefore has no ability
0198          * to fill core properties from camera values. In all other cases, missing properties are filled from current camera values.
0199          * @param job sequence job holding the attributes
0200          * @param pathPropertyMap property map to be filled
0201          * @param local set true if local file directory should be used
0202          * @param is this parameter setting for generating a signature?
0203          */
0204         void setGenerateFilenameSettings(const SequenceJob &job, QMap<PathProperty, QVariant> &pathPropertyMap, const bool local, const bool gettingSignature = false);
0205 
0206         /**
0207          * @brief generateReplacement Generate the replacement for the given property. if usePattern
0208          * is true, a pattern for the given type is used instead of a fixed value.
0209          */
0210         QString generateReplacement(const QMap<PathProperty, QVariant> &pathPropertyMap, PathProperty property, bool usePattern = false) const;
0211 
0212         QString getFrameType(CCDFrameType frameType) const
0213         {
0214             if (m_frameTypes.contains(frameType))
0215                 return m_frameTypes[frameType];
0216 
0217             qWarning() << frameType << " not in " << m_frameTypes.keys();
0218             return "";
0219         }
0220 
0221         // properties that will be used for substitutions
0222         QMap<PathProperty, QVariant> m_PathPropertyMap;
0223         const QVariant getPathProperty(PathProperty prop) const
0224         {
0225             return m_PathPropertyMap[prop];
0226         }
0227         void setPathProperty(QMap<PathProperty, QVariant> &pathPropertyMap, PathProperty prop, QVariant value)
0228         {
0229             pathPropertyMap[prop] = value;
0230         }
0231 
0232         QMap<CCDFrameType, QString> m_frameTypes;
0233         QFileInfo m_seqFilename;
0234 };
0235 
0236 }
0237