/** * Helper class to remove outdated telegram files in a directory * $Id$ * $HeadURL$ * $Author$ * Created by Christian Ehrlicher, SLSE, 2016-09-26 */ #include "directory_cleaner.h" #include #include #include #include #include #include #include #include #include #include namespace TetraRadio { // // DirectoryCleaner // DirectoryCleaner::DirectoryCleaner(const QString &directory, unsigned int maxAgeSec, QObject *parent) : QObject(parent) , m_cleanerThread(new QThread(this)) , m_worker(new DirectoryCleanerWorker(directory, maxAgeSec)) , m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("TAB.Plugin.DirectoryCleaner")) { QDir().mkpath(directory); doInitialCleanup(directory); m_worker->moveToThread(m_cleanerThread); m_cleanerThread->start(); QTimer::singleShot(0, m_worker, &DirectoryCleanerWorker::onTimeout); } DirectoryCleaner::~DirectoryCleaner() { m_cleanerThread->quit(); m_cleanerThread->wait(); delete m_worker; } void DirectoryCleaner::doInitialCleanup(const QString &directory) { QDir d(directory); if (!d.exists()) { WARNING_LOG(m_logger) << "Directory " << directory << " does not exist - can not cleanup directory"; return; } QDirIterator it(d.absolutePath(), QDir::Files | QDir::NoDotAndDotDot); while (it.hasNext()) { it.next(); QFile f(it.filePath()); if (!f.open(QIODevice::ReadOnly)) continue; const QByteArray ba = f.readAll(); const QJsonObject obj = QJsonDocument::fromJson(ba).object(); const int teleId = obj[QStringLiteral("typeId")].toInt(); if (teleShouldBeRemoved(teleId)) QFile::remove(it.filePath()); } } bool DirectoryCleaner::teleShouldBeRemoved(int teleId) { switch (teleId) { case TrainingAreaBase::TetraIcd::WIRKFELD_EINZELGESCHOSS: case TrainingAreaBase::TetraIcd::WIRKFELD_FLAECHENDECKENDES_FEUER: case TrainingAreaBase::TetraIcd::WIRKFELD_FLAECHENDECKENDES_FEUER_STOP: case TrainingAreaBase::TetraIcd::WIRKFELD_FLAECHENDECKENDES_FEUER_FORTSETZEN: case TrainingAreaBase::TetraIcd::WIRKFELD_MINENSPERRE: case TrainingAreaBase::TetraIcd::WIRKFELD_STATUS_MINENSPERRE: case TrainingAreaBase::TetraIcd::WIRKFELD_AENDERUNG_BEZEICHNER: case TrainingAreaBase::TetraIcd::REAKTIVIERUNG_DUS_MINE: case TrainingAreaBase::TetraIcd::WIRKFELD_A_KAMPFMITTEL: case TrainingAreaBase::TetraIcd::WIRKFELD_C_KAMPFMITTEL: case TrainingAreaBase::TetraIcd::DEAKTIVIERUNG_WIRKFELD: case TrainingAreaBase::TetraIcd::DEAKTIVIERUNG_EINZELMINE: case TrainingAreaBase::TetraIcd::FUNKTIONSRAUM: case TrainingAreaBase::TetraIcd::DEAKTIVIEREN_FUNKTIONSRAUM: case TrainingAreaBase::TetraIcd::BETRIEBSZUSTANDSMELDUNG: return true; default: break; } return false; } // // DirectoryCleanerWorker // DirectoryCleanerWorker::DirectoryCleanerWorker(const QString &directory, unsigned int maxAgeSec) : m_directory(directory) , m_maxAgeSec(maxAgeSec) , m_bWarnedOnce(false) , m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("TRA.Plugin.DirectoryCleaner")) {} void DirectoryCleanerWorker::onTimeout() { doCleanup(); // search every 5sec QTimer::singleShot(5000, Qt::VeryCoarseTimer, this, &DirectoryCleanerWorker::onTimeout); } void DirectoryCleanerWorker::doCleanup() { QDir d(m_directory); if (!d.exists()) { if (!m_bWarnedOnce) WARNING_LOG(m_logger) << "Directory " << m_directory << " does not exist - can not cleanup directory"; m_bWarnedOnce = true; return; } m_bWarnedOnce = false; const qint64 tRemoveTimeMSec = (time(nullptr) - m_maxAgeSec) * 1000; QDirIterator it(d.absolutePath(), QDir::Files | QDir::NoDotAndDotDot); while (it.hasNext()) { const QString filepath(it.next()); const QString filename(it.fileName()); bool bOk = false; qint64 timestampUSec = filename.toLongLong(&bOk); TRACE_LOG(m_logger) << "File: " << filename << " timestamp: " << timestampUSec << " remove time: " << tRemoveTimeMSec * 1000; if (!bOk) { WARNING_LOG(m_logger) << "Found file with name '" << filepath << " which is not a valid xdr filename" << " - removing this file when mtime older than " << m_maxAgeSec << "seconds"; qint64 modTime = it.fileInfo().lastModified().toMSecsSinceEpoch(); if (modTime < tRemoveTimeMSec) QFile::remove(filepath); } else { const qint64 timestampMSec = timestampUSec / 1000; // usec -> msec if (timestampMSec < tRemoveTimeMSec) { if (!QFile::remove(filepath)) WARNING_LOG(m_logger) << "Could not remove " << filepath; else TRACE_LOG(m_logger) << "Removed " << filepath; } } } } } // namespace TetraRadio