Logo Search packages:      
Sourcecode: kboincspy version File versions  Download package

kbsdatamonitor.cpp

/***************************************************************************
 *   Copyright (C) 2004 by Roberto Virga                                   *
 *   rvirga@users.sf.net                                                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <qfile.h>
#include <qfileinfo.h>
#include <qtextstream.h>

#include <kio/job.h>
#include <krfcdate.h>

#include "kbsdatamonitor.h"

KBSDataMonitor::KBSDataMonitor(const KURL &url, QObject *parent, const char *name)
              : QObject(parent, name), m_url(url), m_interval(0), m_job(NULL), m_tmp(NULL)
{
  m_url.adjustPath(+1);
  
  m_files.setAutoDelete(true);
}

KURL KBSDataMonitor::url() const
{
  return m_url;
}

int KBSDataMonitor::interval() const
{
  return m_interval;
}

void KBSDataMonitor::setInterval(int interval)
{
  if(interval > 0)
  {
    m_interval = interval;
    m_timer = startTimer(interval * 1000);
  }
  else if(interval <= 0)
  {
    m_interval = 0;
    killTimer(m_timer);
  }

  emit intervalChanged(interval);
}

void KBSDataMonitor::checkFiles()
{
  for(QDictIterator<KBSFileInfo> it(m_files); NULL != it.current(); ++it)
    checkFile(it.current());
}

void KBSDataMonitor::timerEvent(QTimerEvent *e)
{
  if(e->timerId() != m_timer) return;
  
  checkFiles();
}

void KBSDataMonitor::addFile(const QString &fileName)
{
  KBSFileInfo *file = new KBSFileInfo();

  file->fileName = fileName;
  file->initialized = false;
  file->monitored = true;
  file->exists = false;
  file->ok = false;
  
  m_files.insert(fileName, file);
  
  KURL fileURL(m_url, fileName);
  
  checkFile(file);
}

void KBSDataMonitor::removeFile(const QString &fileName)
{
  m_files.remove(fileName);
  m_stat.remove(fileName);
  m_copy.remove(fileName);
}

void KBSDataMonitor::setMonitoring(const QString &fileName, bool monitored)
{
  KBSFileInfo *file = m_files.find(fileName);
  if(NULL == file) return;
  
  file->monitored = monitored;
}

const KBSFileInfo *KBSDataMonitor::file(const QString &fileName) const
{
  return m_files.find(fileName);
}

bool KBSDataMonitor::readFile(const QString &fileName, QString &content)
{
  QFile file(fileName);
  
  bool isOK = file.open(IO_ReadOnly);
  if(isOK) {
    isOK = readDevice(&file, content);    
    file.close();
  }

  return isOK;
}

bool KBSDataMonitor::readFile(const QString &fileName, QDomDocument &content)
{
  QFile file(fileName);
  
  bool isOK = file.open(IO_ReadOnly);
  if(isOK) {
    isOK = readDevice(&file, content);
    file.close();
  }

  return isOK;
}

bool KBSDataMonitor::readFile(const QString &fileName, QStringList &content, const QString &delimiter)
{
  QFile file(fileName);
  
  bool isOK = file.open(IO_ReadOnly);
  if(isOK) {
    isOK = readDevice(&file, content, delimiter);
    file.close();
  }

  return isOK;
}

bool KBSDataMonitor::readDevice(QIODevice *device, QString &content)
{
  content = QTextStream(device).read();
  
  return true;
}

bool KBSDataMonitor::readDevice(QIODevice *device, QDomDocument &content)
{
  return content.setContent(device);
}

bool KBSDataMonitor::readDevice(QIODevice *device, QStringList &content, const QString &delimiter)
{
  QTextStream text(device);

  content.clear();
  QString line = text.readLine();
  while(!line.isNull() && delimiter != line) {
    if(!line.isEmpty()) content << line;
    line = text.readLine();
  }
  
  return true;
}

void KBSDataMonitor::checkFile(KBSFileInfo *file)
{
  if(NULL == file) return;
  
  if(file->initialized && !file->monitored) return;
  
  KURL fileURL(m_url, file->fileName);

  if(fileURL.isLocalFile())
    updateLocalFileInfo(fileURL.path(-1), file);
  else
    queueStatJob(file->fileName);
}

void KBSDataMonitor::checkFile(const QString &fileName)
{
  if(m_url.path(-1) == fileName || m_url.path(+1) == fileName)
    checkFiles();
  else
    checkFile(m_files.find(QFileInfo(fileName).fileName()));
}

bool KBSDataMonitor::parseFile(KBSFileInfo *, const QString &)
{
  return false;
}

void KBSDataMonitor::updateLocalFileInfo(const QString &fileName, KBSFileInfo *info)
{
  KBSFileInfo update;
  QFileInfo fileInfo(fileName);
  
  update.fileName = info->fileName;
  update.initialized = info->initialized;
  update.monitored = info->monitored;
  update.exists = fileInfo.exists();
  if(update.exists) {
    update.timestamp = fileInfo.lastModified();
    update.size = fileInfo.size();
  }
  update.ok = info->ok;
  
  bool modified = false; 
  if(update.exists != info->exists) modified = true;
  if(update.exists && update.timestamp != info->timestamp) modified = true;
  
  *info = update;
  
  if(modified) {
    info->ok = info->exists ? parseFile(info, fileName) : false;
    emit fileUpdated(info->fileName);
  }
}

void KBSDataMonitor::queueStatJob(const QString &fileName)
{
  if(!m_stat.contains(fileName)) m_stat << fileName;
  
  if(NULL == m_job) commenceStatJob(m_stat.first());
}

void KBSDataMonitor::queueCopyJob(const QString &fileName)
{
  if(!m_copy.contains(fileName)) m_copy << fileName;
  
  if(NULL == m_job) commenceCopyJob(m_copy.first());
}

void KBSDataMonitor::commenceStatJob(const QString &fileName)
{
  m_stat.remove(fileName);
  
  KURL fileURL(m_url, fileName);
  
  m_job = KIO::stat(fileURL, true, 4, false);
  
  connect(m_job, SIGNAL(result(KIO::Job *)), this, SLOT(statResult(KIO::Job *)));
}
  
void KBSDataMonitor::commenceCopyJob(const QString &fileName)
{
  m_copy.remove(fileName);
  
  KURL fileURL(m_url, fileName);
  
  m_tmp = new KTempFile();
  m_tmp->setAutoDelete(true);
    
  m_job = KIO::file_copy(fileURL, m_tmp->name(), -1, true, false, false);
  
  connect(m_job, SIGNAL(result(KIO::Job *)), this, SLOT(copyResult(KIO::Job *)));
}
  
void KBSDataMonitor::statResult(KIO::Job *job)
{
  if(job != m_job) return;
  
  KIO::StatJob *statJob = static_cast<KIO::StatJob*>(job);
  const QString fileName = statJob->url().fileName();
  KBSFileInfo *info = m_files.find(fileName);
  
  if(NULL != info && !job->error())
  {
    KBSFileInfo update;
    
    update.fileName = info->fileName;
    update.initialized = info->initialized;
    update.monitored = info->monitored;
    update.exists = true;
    update.size = 0L;
    update.timestamp = QDateTime::currentDateTime();
    update.ok = info->ok;
    
    KIO::UDSEntry entry = statJob->statResult();    
    for(KIO::UDSEntry::iterator it = entry.begin(); it != entry.end(); ++it)
      switch((*it).m_uds) {
        case KIO::UDS_SIZE:
          update.size = (*it).m_long;
          break;
        case KIO::UDS_MODIFICATION_TIME:
          update.timestamp.setTime_t((*it).m_long);
          break;
        default:
          break;
      }
      
    bool modified = false; 
    if(update.exists != info->exists) modified = true;
    if(update.exists && update.timestamp != info->timestamp) modified = true;
  
    *info = update;
  
    if(modified)
      if(info->exists)
        queueCopyJob(info->fileName);
      else
        info->ok = false;
  }
  
  if(!m_copy.isEmpty())
    commenceCopyJob(m_copy.first());
  else if(!m_stat.isEmpty())
    commenceStatJob(m_stat.first());
  else
    m_job = NULL;
}

void KBSDataMonitor::copyResult(KIO::Job *job)
{
  if(job != m_job) return;
  
  KIO::FileCopyJob *copyJob = static_cast<KIO::FileCopyJob*>(job);
  const QString fileName = copyJob->srcURL().fileName();
  KBSFileInfo *info = m_files.find(fileName);
  
  if(NULL != info && !job->error())
  {
    if(!job->error() && parseFile(info, m_tmp->name()))
      info->initialized = info->ok = true;
    else
      info->ok = false;
    
    emit fileUpdated(fileName);
  }

  delete m_tmp;
  m_tmp = NULL;

  if(!m_stat.isEmpty())
    commenceStatJob(m_stat.first());
  else if(!m_copy.isEmpty())
    commenceCopyJob(m_copy.first());
  else
    m_job = NULL;
}

#include "kbsdatamonitor.moc"

Generated by  Doxygen 1.6.0   Back to index