Index: denali.pro.user =================================================================== diff -u -r7777127f3b60d5f884cd07adc9d586353d914f69 -ra3030123e885fb9f22dea5839c4e988896a257e4 --- denali.pro.user (.../denali.pro.user) (revision 7777127f3b60d5f884cd07adc9d586353d914f69) +++ denali.pro.user (.../denali.pro.user) (revision a3030123e885fb9f22dea5839c4e988896a257e4) @@ -1,6 +1,6 @@ - + EnvironmentId Index: sources/ApplicationController.cpp =================================================================== diff -u -rcc1e9d6d55c816f3fcd626dc6948cca24da283b3 -ra3030123e885fb9f22dea5839c4e988896a257e4 --- sources/ApplicationController.cpp (.../ApplicationController.cpp) (revision cc1e9d6d55c816f3fcd626dc6948cca24da283b3) +++ sources/ApplicationController.cpp (.../ApplicationController.cpp) (revision a3030123e885fb9f22dea5839c4e988896a257e4) @@ -112,6 +112,8 @@ // SD Card connect(&_DriveWatcher , SIGNAL(didSDCardStateChange(bool, bool)), this , SLOT( onSDCardStateChange(bool, bool))); + connect(&_DriveWatcher , SIGNAL(didSDCardSpaceTooLow(quint8)), + this , SLOT( onSDCardSpaceTooLow(quint8))); connect(&_GuiController , SIGNAL(didExportLog()), this , SLOT( onExportLog())); @@ -257,6 +259,19 @@ // coco end /*! + * \brief ApplicationController::onSDCardSpaceTooLow + * \details The handler slot for the didSDCardSpaceTooLow signal comes form DriveWatcher + * \param vAvailablePercent - the minimum limit of available storage space + */ +void ApplicationController::onSDCardSpaceTooLow(quint8 vAvailablePercent) +{ + // coco begin validated: This needs user interaction to plug-in SD Card + // has been tested manually + emit didSDCardSpaceTooLow(vAvailablePercent); +} +// coco end + +/*! * \brief ApplicationController::onExportLog * \details the slot which will be called by UI to so the log export. */ Index: sources/ApplicationController.h =================================================================== diff -u -r9d8a60eb984003d3f7814cbe507b1b37f519bc80 -ra3030123e885fb9f22dea5839c4e988896a257e4 --- sources/ApplicationController.h (.../ApplicationController.h) (revision 9d8a60eb984003d3f7814cbe507b1b37f519bc80) +++ sources/ApplicationController.h (.../ApplicationController.h) (revision a3030123e885fb9f22dea5839c4e988896a257e4) @@ -85,6 +85,7 @@ void onUSBDriveRemove(); void onSDCardStateChange(bool vIsReady, bool vIsReadOnly); + void onSDCardSpaceTooLow(quint8 vAvailablePercent); void onExportLog (); void onExport (); @@ -101,6 +102,7 @@ void didUSBDriveRemove(); void didSDCardStateChange(bool vIsReady, bool vIsReadOnly); + void didSDCardSpaceTooLow(quint8 vAvailablePercent); void didExport (); Index: sources/gui/GuiController.cpp =================================================================== diff -u -r741b1c70f851810f2c265cdd38dfa158b7ee0c37 -ra3030123e885fb9f22dea5839c4e988896a257e4 --- sources/gui/GuiController.cpp (.../GuiController.cpp) (revision 741b1c70f851810f2c265cdd38dfa158b7ee0c37) +++ sources/gui/GuiController.cpp (.../GuiController.cpp) (revision a3030123e885fb9f22dea5839c4e988896a257e4) @@ -84,6 +84,8 @@ // SD card connect(&_ApplicationController, SIGNAL(didSDCardStateChange(bool,bool)), this , SLOT( onSDCardStateChange(bool,bool))); + connect(&_ApplicationController, SIGNAL(didSDCardSpaceTooLow(quint8)), + this , SLOT( onSDCardSpaceTooLow(quint8))); // Export connect(&_ApplicationController, SIGNAL(didExport()), @@ -279,7 +281,21 @@ } // coco end + /*! + * \brief GuiController::onSDCardSpaceTooLow + * \details The handler slot for the didSDCardSpaceTooLow signal comes form ApplicationController. + * \param vAvailablePercent - the minimum limit of available storage space + */ +void GuiController::onSDCardSpaceTooLow(quint8 vAvailablePercent) +{ + // coco begin validated: This needs to fill up the SD-Card and test with human interactions. + // has been tested manually + emit didSDCardSpaceTooLow(vAvailablePercent); +} +// coco end + +/*! * \brief GuiController::onExport * \details The slot which will be called to notify the export is done * by emitting the didExport signal. Index: sources/gui/GuiController.h =================================================================== diff -u -rb61d8a3e01fef66eee8095c9cddf835d9bb32b66 -ra3030123e885fb9f22dea5839c4e988896a257e4 --- sources/gui/GuiController.h (.../GuiController.h) (revision b61d8a3e01fef66eee8095c9cddf835d9bb32b66) +++ sources/gui/GuiController.h (.../GuiController.h) (revision a3030123e885fb9f22dea5839c4e988896a257e4) @@ -81,6 +81,7 @@ void onUSBDriveRemove(); // OS => UI void onSDCardStateChange(bool vIsReady, bool vIsReadOnly); // OS => UI + void onSDCardSpaceTooLow(quint8 vAvailablePercent); // OS => UI void onExport (); // OS => UI void onFailedTransmit(Sequence seq); @@ -94,6 +95,7 @@ void didUSBDriveRemove(); void didSDCardStateChange(bool vIsReady, bool vIsReadOnly); + void didSDCardSpaceTooLow(quint8 vAvailablePercent); void didExportLog(); void didExport (); Index: sources/gui/GuiView.cpp =================================================================== diff -u -r64d87d540594252e8039ab2595016d98f1e3cc28 -ra3030123e885fb9f22dea5839c4e988896a257e4 --- sources/gui/GuiView.cpp (.../GuiView.cpp) (revision 64d87d540594252e8039ab2595016d98f1e3cc28) +++ sources/gui/GuiView.cpp (.../GuiView.cpp) (revision a3030123e885fb9f22dea5839c4e988896a257e4) @@ -53,16 +53,18 @@ &_GuiController, SLOT( doUSBDriveUmount())); // From OS : USB drive removed connect(&_GuiController, SIGNAL(didUSBDriveMount ()), - this , SLOT( doUSBDriveMount ())); + this , SLOT( onUSBDriveMount ())); connect(&_GuiController, SIGNAL(didUSBDriveRemove()), - this , SLOT( doUSBDriveRemove())); + this , SLOT( onUSBDriveRemove())); // SD Card connect(&_GuiController, SIGNAL(didSDCardStateChange(bool,bool)), - this , SLOT( doSDCardStateChange(bool,bool))); + this , SLOT( onSDCardStateChange(bool,bool))); + connect(&_GuiController, SIGNAL(didSDCardStateChange(bool,bool)), + this , SLOT( onSDCardStateChange(bool,bool))); connect(&_GuiController, SIGNAL(didExport()), - this , SLOT( doExport())); + this , SLOT( onExport())); // From UI : Export Log connect(this , SIGNAL(didExportLog()), @@ -123,7 +125,7 @@ * \details emits didUSBDriveMount signal to notify other classes (UI) * , the USB drive has been mounted. */ -void GuiView::doUSBDriveMount () +void GuiView::onUSBDriveMount () { // coco begin validated: This needs user interaction to plug-in USB device // has been tested manually @@ -149,7 +151,7 @@ * \details emits didUSBDriveRemove signal to notify other classes (UI) * , the USB drive has been removed. */ -void GuiView::doUSBDriveRemove() +void GuiView::onUSBDriveRemove() { // coco begin validated: This needs user interaction to plug-in USB device // has been tested manually @@ -158,13 +160,13 @@ // coco end /*! - * \brief GuiView::doSDCardStateChange + * \brief GuiView::onSDCardStateChange * \details emits didSDCardStateChange signal to notify other classes (UI) * , the SD Card Stte has been changed. * \param vIsReady - SdCard is Ready * \param vIsReadOnly - SdCard is ReadOnly */ -void GuiView::doSDCardStateChange(bool vIsReady, bool vIsReadOnly) +void GuiView::onSDCardStateChange(bool vIsReady, bool vIsReadOnly) { // coco begin validated: This needs user interaction to plug-in USB device // has been tested manually @@ -174,11 +176,24 @@ // coco end /*! + * \brief GuiController::doSDCardSpaceTooLow + * \details The handler slot for the didSDCardSpaceTooLow signal comes form GuiController. + * \param vAvailablePercent - the minimum limit of available storage space + */ +void GuiView::onSDCardSpaceTooLow(quint8 vAvailablePercent) +{ + // coco begin validated: This needs to fill up the SD-Card and test with human interactions. + // has been tested manually + sdTooLowPecent(vAvailablePercent); +} +// coco end + +/*! * \brief GuiView::onExport * \details The slot which will be called to notify the export is done * by emitting the didExport signal. */ -void GuiView::doExport() +void GuiView::onExport() { // coco begin validated: This needs user interaction to plug-in USB device // has been tested manually Index: sources/gui/GuiView.h =================================================================== diff -u -r64d87d540594252e8039ab2595016d98f1e3cc28 -ra3030123e885fb9f22dea5839c4e988896a257e4 --- sources/gui/GuiView.h (.../GuiView.h) (revision 64d87d540594252e8039ab2595016d98f1e3cc28) +++ sources/gui/GuiView.h (.../GuiView.h) (revision a3030123e885fb9f22dea5839c4e988896a257e4) @@ -45,6 +45,9 @@ // has been tested manually PROPERTY(bool, sdIsReady , false) PROPERTY(bool, sdIsReadOnly, false) + + // this property will be set if the sd-card space gets lower than required amount in percent that has been defined in DriveWatcher. + PROPERTY(qint8, sdTooLowPecent, -1) // -1 means the event never happened // coco end public: @@ -56,18 +59,18 @@ private slots: void onActionReceive (GuiActionType vAction, const QVariantList &vData); // UI <= HD/DG - void doUSBDriveMount (); - void doUSBDriveRemove(); + void onUSBDriveMount (); + void onUSBDriveRemove(); - void doExport (); + void onExport (); + void onSDCardStateChange(bool vIsReady, bool vIsReadOnly); + void onSDCardSpaceTooLow(quint8 vAvailablePercent); + public slots: // is public since will be used in the UI and is in the same thread. void doActionTransmit(GuiActionType vAction, const QVariantList &vData); // UI => HD/DG void doActionTransmit(GuiActionType vAction, const QVariant &vData); // UI => HD/DG void doUSBDriveUmount(); - - void doSDCardStateChange(bool vIsReady, bool vIsReadOnly); - void doExportLog (); signals: Index: sources/storage/DriveWatcher.cpp =================================================================== diff -u -r6cad9b004e904200b71de7431c745795256080df -ra3030123e885fb9f22dea5839c4e988896a257e4 --- sources/storage/DriveWatcher.cpp (.../DriveWatcher.cpp) (revision 6cad9b004e904200b71de7431c745795256080df) +++ sources/storage/DriveWatcher.cpp (.../DriveWatcher.cpp) (revision a3030123e885fb9f22dea5839c4e988896a257e4) @@ -85,6 +85,14 @@ } // coco end +void DriveWatcher::onRemoveLogs(bool vInProgress) +{ + // coco begin validated: The log in progress requires user interaction + // it has been tested and works fine in normal run. + _pauseSpaceCheck = vInProgress; +} +// coco end + /*! * \brief DriveWatcher::initConnections * \details Initializes the required signal/slot connection between this class and other objects @@ -94,6 +102,8 @@ { connect(&_ApplicationController, SIGNAL(didUSBDriveUmount()), this , SLOT( onUSBDriveUmount())); + connect(&_Logger , SIGNAL(didRemoveLogs(bool)), + this , SLOT( onRemoveLogs(bool))); } /*! @@ -238,18 +248,27 @@ } if (! mCIsReady ) { - mOIsReady = mCIsReady; + mOIsReady = mCIsReady; + mOTotal = 0; + mOAvailable = 0; return; } quint8 mPercent = mCTotal ? ((100 * mCAvailable) / mCTotal) : 0; + if (mPercent < _minRequiredAvailableSpacePercent) { + LOG_EVENT(QString("SD-CARD space lower than %1%").arg(_minRequiredAvailableSpacePercent)); + emit didSDCardSpaceTooLow(_minRequiredAvailableSpacePercent); + } + if (mOTotal == mCTotal && - mOAvailable == mCAvailable && - mPercent >= _minRequiredAvailableSpacePercent ) return; + mOAvailable == mCAvailable) { + return; + } mOIsReady = mCIsReady ; mOTotal = mCTotal ; mOAvailable = mCAvailable ; + if (_pauseSpaceCheck) return; emit didSDCardSpaceChange(mCIsReady, mCTotal, mCAvailable, mPercent); } // coco end @@ -303,7 +322,7 @@ * \brief DriveWatcher::usbMount * \details Mounts the USB device vDevice * \note Emits didUSBDriveMount signal - * \param vDevice - USB device to be mounted (eg. /dev/sda1) + * \param vDevice - USB device to be mounted (e.g. /dev/sda1) * \return true on successful mount */ bool DriveWatcher::usbMount(const QString &vDevice) @@ -329,7 +348,7 @@ * \brief DriveWatcher::usbUmount * \details Unmounts the USB device vDevice * \note Emits didUSBDriveUmount signal - * \param vDevice - USB device to be unmounted (eg. /dev/sda1) + * \param vDevice - USB device to be unmounted (e.g. /dev/sda1) * \return true on successful unmount */ bool DriveWatcher::usbUmount(const QString &vDevice) Index: sources/storage/DriveWatcher.h =================================================================== diff -u -r6cad9b004e904200b71de7431c745795256080df -ra3030123e885fb9f22dea5839c4e988896a257e4 --- sources/storage/DriveWatcher.h (.../DriveWatcher.h) (revision 6cad9b004e904200b71de7431c745795256080df) +++ sources/storage/DriveWatcher.h (.../DriveWatcher.h) (revision a3030123e885fb9f22dea5839c4e988896a257e4) @@ -58,17 +58,21 @@ const char *_usbDrive = ""; const int _interval = 1000; // in ms - const qint8 _minRequiredAvailableSpacePercent = 15; + const qint8 _minRequiredAvailableSpacePercent = 10; QThread *_thread = nullptr; bool _init = false; + bool _pauseSpaceCheck = false; + public slots: bool init(); bool init(QThread &vThread); + private slots: void quit(); + void onRemoveLogs(bool vInProgress); protected: void timerEvent(QTimerEvent *) override; @@ -123,6 +127,14 @@ */ void didSDCardStateChange(bool vIsReady, bool vIsReadOnly); + /*! + * \brief didSDCardSpaceTooLow + * \details this signal will emit ones the available space left on the SD-Card + * is less than minimum required percentage defined in _minRequiredAvailableSpacePercent. + * \param vAvailablePercent + */ + void didSDCardSpaceTooLow(quint8 vAvailablePercent); + private slots: // ----- USB void usbCheck(); Index: sources/storage/FileHandler.cpp =================================================================== diff -u -r14c541d2b780b0a244bc84860aa565cf8dd7fe4b -ra3030123e885fb9f22dea5839c4e988896a257e4 --- sources/storage/FileHandler.cpp (.../FileHandler.cpp) (revision 14c541d2b780b0a244bc84860aa565cf8dd7fe4b) +++ sources/storage/FileHandler.cpp (.../FileHandler.cpp) (revision a3030123e885fb9f22dea5839c4e988896a257e4) @@ -23,6 +23,7 @@ #include #include + // Project #include "Logger.h" @@ -107,13 +108,13 @@ } /*! - * \brief FileHandler::readCSV + * \brief FileHandler::read * \details reads the provided filename's JSON content into the vContent variable. * \param vFileName - Source file name * \param vContent - The content of the file which will be written to when done. - * \return false if file can't be read + * \return false if file can't be read or parsed */ -bool FileHandler::readJSON(const QString &vFileName, QJsonObject &vContent) +bool FileHandler::read(const QString &vFileName, QJsonObject &vContent, QJsonParseError *error) { QFile file(vFileName); if (! file.open(QFile::Text | QFile::ReadOnly)) { @@ -122,8 +123,12 @@ } QTextStream in(&file); QString content = in.readAll(); - - QJsonDocument doc = QJsonDocument::fromJson(content.toUtf8()); + QJsonParseError jsonParseError; + QJsonDocument doc = QJsonDocument::fromJson(content.toUtf8(), &jsonParseError); + if (jsonParseError.error) { + if (error) *error = jsonParseError; + return false; + } vContent = doc.object(); return true; } @@ -238,3 +243,123 @@ return mounted; } // coco end + +/*! + * \brief FileHandler::find + * \details The function to find files. + * It mainly been implemented to find the files are using some amount of total storage in the vPath by percentage, + * and are the oldest. + * \param vPath - the path to search for the files + * \param vNameFilters - the files filter to search for. + * \param vRetainPercent - It means how many percentage of the space these file are able to retain. + * e.g. 90% retains means older files which use 10% of storage will be listed. + * e.g. 80% retains means older files which use 20% of storage will be listed. + * e.g. 0% retains means no file shall be retained, therefore all the files listed. + * e.g. 100% retains means all file shall be retained, therefore the list shall be empty. + * By default set t0 0 so don't have any size constraint + * \return list of the files found by their information. + * if vRetainPercent is used then it contains list of the file(s) to be removed. + */ +QFileInfoList FileHandler::find(const QString &vPath, QStringList vNameFilters, quint8 vRetainPercent) { + // coco begin validated: Manually tested. Needs to fill up the storage to test some functionalities like vRetainPercent + + QFileInfoList fileInfoList; + // if all the files need to retain then no file shall be listed in the remove list. + if ( vRetainPercent == 100 ) return fileInfoList; + + // if the path is incorrect return with empty list + QDir dir(vPath); + if (!dir.exists()) return fileInfoList; + + // get the storage total + QStorageInfo storage(dir); + quint64 totalSizeStorage = storage.bytesTotal(); + + // get list of all the files in the path by the filter + QFileInfoList fileInfoListAll = find(vPath, vNameFilters); + + // if there is no file in the path with that filter then return empty list. + if (fileInfoListAll.count() == 0) return fileInfoList; + + // if vRetainPercent is 0 means all needs to be removed. + if (vRetainPercent == 0) return fileInfoListAll; + + // get the files total + quint64 totalSizeFiles = totalSize(fileInfoListAll); + + // the total size that all the + quint64 totalSizeRetain = totalSizeStorage * (vRetainPercent / 100.0); + + // if already totalSizeFiles <= totalSizeRetain, don't go any further and return empty list. + if (totalSizeFiles <= totalSizeRetain) return fileInfoList; + + // gets each file size from oldest to newest + // checks if the total files size subtracted by the current file size will be less that limit + // if it is breaks + // else adds the file to the list and continues. + qDebug() << "%" << totalSizeStorage << totalSizeFiles << totalSizeRetain << totalSizeFiles - totalSizeRetain << vRetainPercent; + quint64 totalSizeRemoved = 0; + for (auto it = fileInfoListAll.crbegin(); it != fileInfoListAll.crend(); ++it) { + // (totalSizeFiles <= totalSizeRetain) has been checked above and didn't return; , + // so at least one file should be checked and then check again in the loop. + quint64 size = it->size(); + totalSizeRemoved += size; + totalSizeFiles -= size; + fileInfoList += *it; + /// DEBUG: since it has been manually tested this will help next time for test. + /// debugging the find function + // qDebug() << QString("%1 , %2 , %3 , %4 , %5") + // .arg(totalSizeFiles , 12) + // .arg(size , 12) + // .arg(totalSizeRemoved , 12) + // .arg(it->lastModified().toString("yyyy-MM-dd-HH:mm")) + // .arg(it->fileName()) + // ; + if (totalSizeFiles <= totalSizeRetain) break; + } + /// DEBUG: since it has been manually tested this will help next time for test. + /// the total size & count removed. + // qDebug() << QString("%1 , %2") + // .arg(totalSizeRemoved , 12) + // .arg(fileInfoList.count(), 3) + // ; + return fileInfoList; +} +// coco end + +/*! + * \brief FileHandler::find + * \details The function to find files. + * \param vPath - the path to search for the files + * \param vNameFilters - the files filter to search for. + * \return list of the files found by their information. + * if vRetainPercent is used then it contains list of the file(s) to be removed. + */ +QFileInfoList FileHandler::find(const QString &vPath, QStringList vNameFilters) { + // coco begin validated: Needs to manually create specific folder with specific files to check the functionality + // manually tested + + QFileInfoList fileInfoList; + QDir dir(vPath); + if (!dir.exists()) return fileInfoList; + fileInfoList = dir.entryInfoList( + vNameFilters, + QDir::NoDotAndDotDot | QDir::Files, + // the sorting may require to change from QDir::Time to QDir::Name + // since the birthTime always returns invalid + // and as part of our log naming we have the birthTime in file name. + QDir::Time + ); + return fileInfoList; +} +// coco end + +quint64 FileHandler::totalSize(const QFileInfoList &vFileInfoList) { + // coco begin validation: Manually tested. requires list of files on file system to test and requires manual specific files for test. + quint64 total = 0; + for (auto it = vFileInfoList.crbegin(); it != vFileInfoList.crend(); ++it) { + total += it->size(); + } + return total; +} +// coco end Index: sources/storage/FileHandler.h =================================================================== diff -u -r14c541d2b780b0a244bc84860aa565cf8dd7fe4b -ra3030123e885fb9f22dea5839c4e988896a257e4 --- sources/storage/FileHandler.h (.../FileHandler.h) (revision 14c541d2b780b0a244bc84860aa565cf8dd7fe4b) +++ sources/storage/FileHandler.h (.../FileHandler.h) (revision a3030123e885fb9f22dea5839c4e988896a257e4) @@ -16,8 +16,11 @@ // Qt #include +#include #include #include +#include + class QDate; namespace Storage { @@ -36,11 +39,15 @@ public: static bool write (const QString &vFileName, const QString &vContent, bool vAppend = true); static bool read (const QString &vFileName, QString &vContent); - static bool readJSON (const QString &vFileName, QJsonObject &vContent); + static bool read (const QString &vFileName, QJsonObject &vContent, QJsonParseError *error = nullptr); static int copyFolder (const QString &vSource , const QString &vDestination); static int removeFiles(const QStringList &vFolders, const QStringList &vNameFilter, const QDate &vDateOlderThan); static bool makeFolder (const QString &vFolder); static bool isMounted (const QString &vPath, bool *vIsReadOnly = nullptr); + + static QFileInfoList find(const QString &vPath, QStringList vNameFilter, quint8 vRetainPercent); + static QFileInfoList find(const QString &vPath, QStringList vNameFilter); + static quint64 totalSize(const QFileInfoList &vFileInfoList); }; } Index: sources/storage/Logger.cpp =================================================================== diff -u -rc8b2c06141831ba2908323138d94dec0ccc0d402 -ra3030123e885fb9f22dea5839c4e988896a257e4 --- sources/storage/Logger.cpp (.../Logger.cpp) (revision c8b2c06141831ba2908323138d94dec0ccc0d402) +++ sources/storage/Logger.cpp (.../Logger.cpp) (revision a3030123e885fb9f22dea5839c4e988896a257e4) @@ -21,6 +21,7 @@ #include #include #include +#include // Project #include "DriveWatcher.h" @@ -201,9 +202,9 @@ { bool ok = true; // coco begin validated: Has been tested manually, this needs user interaction to check the file system - if ( ok && ! setLogPath(LogType::eLogDebug) ) ok = false; if ( ok && ! setLogPath(LogType::eLogEvent) ) ok = false; if ( ok && ! setLogPath(LogType::eLogDatum) ) ok = false; + if ( ok && ! setLogPath(LogType::eLogDebug) ) ok = false; return ok; } // coco end @@ -289,8 +290,9 @@ int result = 0; static QString mOSource; QString mDestination = USB_Mount_Point; - for ( const auto &iType : { eLogEvent , eLogDatum } ) { + for ( const auto &iType : { eLogEvent, eLogDatum } ) { QString mCSource = _logPathNames[iType]; + // if the event and datum are mixed (mOSource == mCSource) in one file then no need to go over the same files in same folder and do it again. if (mOSource != mCSource) { mOSource = mCSource; // Copy Folder @@ -340,29 +342,50 @@ int Logger::removeLogs() { // coco begin validated: This needs user interaction to check the old files deleted + // Storage::FileHandler::find("/media/denali/0CAA-40C1/log/", {"*.err"}, 15); return 0; // has been tested manually + qDebug() << "int Logger::removeLogs()"; static QString mOSource; - int countRemoved = 0; - QStringList mLogFileFilter; - QDate mOlderThan ; + static QString mOExtension; + int removeCount = 0; + QString mLogFileFilter; for ( const auto &iType : { eLogEvent , eLogDatum , eLogDebug } ) { - QString mCSource = _logPathNames[iType]; - if (mOSource != mCSource) { - mOSource = mCSource; + QString mCSource = _logPathNames [iType]; + QString mCExtension = _logFileNameExt[iType]; + // if the event and datum are mixed (mOSource == mCSource && mCExtension == mOExtension) in one file then no need to go over the same files in same folder and do it again. + if (mOSource != mCSource || mCExtension != mOExtension) { + mOSource = mCSource; + mOExtension = mCExtension; // Remove Logs - if (_logTypeExpiryDay.value(iType)) { - mOlderThan = QDate().currentDate().addDays( _logTypeExpiryDay.value(iType) * -1 /*Please Notice (-1)*/ ); - mLogFileFilter = Format::toStringList(_logFileNameExt .values(iType), true, "*"); - LOG_DEBUG(QString("Removing logs older than %1 from folder %2").arg(mOlderThan.toString("yyyy-MM-dd")).arg(mCSource)); - countRemoved += FileHandler::removeFiles({ mCSource }, mLogFileFilter, mOlderThan); + mLogFileFilter = QString("*%1").arg(mCExtension); + /// DEBUG: since it has been manually tested this will help next time for test. + /// qDebug() << "@" << mCSource << mLogFileFilter << mCExtension << iType << _logTypeMaxUsageLimit[iType]; + QFileInfoList fileInfoList = FileHandler::find(mCSource, {mLogFileFilter}, _logTypeMaxUsageLimit[iType]); + removeCount = fileInfoList.count(); + if (removeCount) { + LOG_DEBUG(QString("Removing %1 logs of type (%2) more than %3% limit from folder %4") + .arg(removeCount) + .arg(mCExtension) + .arg(_logTypeMaxUsageLimit[iType]) + .arg(mCSource)); + for (const auto &info: fileInfoList) { + if (info.lastModified().date() == QDate().currentDate()) { + LOG_DEBUG(QString("Current day log %1 cannot be deleted").arg(info.fileName())); + } + else { + /// DEBUG: since it has been manually tested this will help next time for test. + /// qDebug() << "#" << mCSource + info.fileName(); + QFile::remove(info.fileName()); + } + } } else { - LOG_DEBUG("Current day logs cannot be deleted"); + LOG_DEBUG("No log file is deleted for " + mCExtension); } } } mOSource = ""; - return countRemoved; + return removeCount; } // coco end @@ -377,7 +400,8 @@ // coco begin validated: This needs user interaction to check the old files deleted // has been tested manually LOG_DEBUG("Remove Logs Start"); - QFuture mFuture = QtConcurrent::run(this,&Logger::removeLogs); + emit didRemoveLogs(true); + QFuture mFuture = QtConcurrent::run(this, &Logger::removeLogs); _removeLogsWatcher.setFuture(mFuture); return true; } @@ -392,7 +416,7 @@ // coco begin validated: This needs user interaction to export to USB device // has been tested manually LOG_DEBUG(QString("Remove Logs Ended: %1").arg(_removeLogsWatcher.result())); - emit didRemoveLogs(); + emit didRemoveLogs(false); } // coco end Index: sources/storage/Logger.h =================================================================== diff -u -rae1042a0c14d6d27556730183cc2cbe1a00bc0a7 -ra3030123e885fb9f22dea5839c4e988896a257e4 --- sources/storage/Logger.h (.../Logger.h) (revision ae1042a0c14d6d27556730183cc2cbe1a00bc0a7) +++ sources/storage/Logger.h (.../Logger.h) (revision a3030123e885fb9f22dea5839c4e988896a257e4) @@ -33,6 +33,8 @@ #define LOG_EVENT(vCONTENT) emit Storage::Logger::I().didLog(vCONTENT, Storage::Logger::LogType::eLogEvent) #define LOG_DATUM(vCONTENT) emit Storage::Logger::I().didLog(vCONTENT, Storage::Logger::LogType::eLogDatum) +#define MIXED_EVENT_DATUM + // forward declarations class tst_logging; @@ -99,25 +101,33 @@ { LogType::eLogDebug, "" }, // it has its own file and all the content is Error }; - const QHash _logTypeName { // Will be used for for information - { LogType::eLogEvent, "Event" }, - { LogType::eLogDatum, "Datum" }, - { LogType::eLogDebug, "Error" }, // it has its own file and all the content is Error - }; - const QHash _logFileNameExt { { LogType::eLogEvent, ".log" }, +#ifdef MIXED_EVENT_DATUM { LogType::eLogDatum, ".log" }, +#else + { LogType::eLogDatum, ".dat" }, +#endif { LogType::eLogDebug, ".err" }, }; - const QHash _logTypeExpiryDay { - { LogType::eLogEvent, 15 }, // in days - { LogType::eLogDatum, 15 }, // in days - { LogType::eLogDebug, 5 }, // in days + // be careful when defining these percentages + // 1 - Since now both the Log and Datum are in the same place and file they have same percentage. + // if separated then the percentage has to be separated + // 2 - the total in _logTypeExpiryDay in not 100 and it has to be summed up with _availableSpacePercent. + // so it is 70% for Event/Datum + 15% Service + 15% free = 100% total + const QHash _logTypeMaxUsageLimit { +#ifdef MIXED_EVENT_DATUM + { LogType::eLogEvent, 70 }, // in days + { LogType::eLogDatum, 70 }, // in days +#else + { LogType::eLogEvent, 35 }, // in days + { LogType::eLogDatum, 35 }, // in days +#endif + { LogType::eLogDebug, 15 }, // in days }; - const qint8 _availableSpacePercent = 25; // currently 16G SD-Card so 4G should always be available. + const qint8 _availableSpacePercent = 15; // currently 16G SD-Card so 2.4G should always be available. const char *_dateFormat = "yyyy_MM_dd"; const char *_timeFormat = "HH:mm:ss"; @@ -128,6 +138,7 @@ bool _enableConsoleOut = false; QString _logFileName = ""; + QMutex _logRemoveRunning; QFutureWatcher _exportLogsWatcher; QFutureWatcher _removeLogsWatcher; @@ -174,7 +185,14 @@ bool concurrentRemoveLogs(); void onRemoveLogs(); signals: - void didRemoveLogs(); + /*! + * \brief didRemoveLogs + * \details This signal will be emitted mainly for DriveWatcher to not to emit the signal that Logger is connected to + * , while the logging cleanup is in progress, otherwise if the log cleanup takes more that 1sec (current interval) + * in the DriveWatcher then the cleanup will be called again for no good reason. + * \param vInProgress - true if the log cleanup is in progress, false otherwise. + */ + void didRemoveLogs(bool vInProgress); // ----- Available space is low private slots: @@ -193,6 +211,6 @@ * \param vContent - content as type of string to be logged * \param vLogType - the type of logging of type Storage::Logger::LogType */ - void didLog (const QString &vContent, LogType vLogType); + void didLog (const QString &vContent, LogType vLogType); }; } Index: sources/storage/StorageGlobals.cpp =================================================================== diff -u -rcb5477be624b09e13d5fc4498634ca621722fd0e -ra3030123e885fb9f22dea5839c4e988896a257e4 --- sources/storage/StorageGlobals.cpp (.../StorageGlobals.cpp) (revision cb5477be624b09e13d5fc4498634ca621722fd0e) +++ sources/storage/StorageGlobals.cpp (.../StorageGlobals.cpp) (revision a3030123e885fb9f22dea5839c4e988896a257e4) @@ -29,11 +29,6 @@ const char *USB_Mount_Point = "/media/usb/"; const char *USB_File_System = "vfat"; - // Log - const char *Log_Base_Path_Name = "/media/sd-card/"; - const char *Log_Base_Path_Name_Location = "/media/sd-card/log/"; - const char *Log_File_Name = "denali.log"; - // Treatment const char *Treatment_Base_Dir = "/media/sd-card/treatment/"; const char *Treatment_Profiles_Dir = "/media/sd-card/treatment/profiles/"; Index: sources/view/VTreatmentCreate.cpp =================================================================== diff -u -r28f3f8dd18981262995386d29d3c2ab31418bfc4 -ra3030123e885fb9f22dea5839c4e988896a257e4 --- sources/view/VTreatmentCreate.cpp (.../VTreatmentCreate.cpp) (revision 28f3f8dd18981262995386d29d3c2ab31418bfc4) +++ sources/view/VTreatmentCreate.cpp (.../VTreatmentCreate.cpp) (revision a3030123e885fb9f22dea5839c4e988896a257e4) @@ -59,7 +59,7 @@ QJsonObject VTreatmentCreate::loadTreatmentParameterRanges(const QString &path) { QJsonObject obj; - if (!FileHandler::readJSON(path, obj)) + if (!FileHandler::read(path, obj)) { // TODO: notify user LOG_EVENT(tr("Could not load treatment parameter ranges from %1").arg(path)); Index: unittests/tst_views.cpp =================================================================== diff -u -r14c541d2b780b0a244bc84860aa565cf8dd7fe4b -ra3030123e885fb9f22dea5839c4e988896a257e4 --- unittests/tst_views.cpp (.../tst_views.cpp) (revision 14c541d2b780b0a244bc84860aa565cf8dd7fe4b) +++ unittests/tst_views.cpp (.../tst_views.cpp) (revision a3030123e885fb9f22dea5839c4e988896a257e4) @@ -641,15 +641,15 @@ elapsedSeconds = 0; QJsonObject objectReadTemp; - while (!FileHandler::readJSON(filename, objectReadTemp) || (objectWritten != objectReadTemp)) + while (!FileHandler::read(filename, objectReadTemp) || (objectWritten != objectReadTemp)) { elapsedSeconds = startTime.secsTo(QDateTime::currentDateTime()); } QVERIFY(elapsedSeconds < 0.5); QJsonObject objectRead; - QVERIFY(FileHandler::readJSON(filename, objectRead)); + QVERIFY(FileHandler::read(filename, objectRead)); QCOMPARE(objectWritten, objectRead); }