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

kbscpdnmonitor.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 <kbsboincmonitor.h>
#include <kbsrpcmonitor.h>

#include "kbscpdnmonitor.h"

const QString CPDNGraphicsFileName = "viz";

KBSCPDNMonitor::KBSCPDNMonitor(const QString &project, KBSBOINCMonitor *parent, const char *name)
                    : KBSProjectMonitor(project, parent, name)
{
  m_results.setAutoDelete(true);
  
  connect(parent, SIGNAL(workunitsAdded(const QStringList &)),
          this, SLOT(addWorkunits(const QStringList &)));
  connect(parent, SIGNAL(workunitsRemoved(const QStringList &)),
          this, SLOT(removeWorkunits(const QStringList &)));
  connect(parent, SIGNAL(workunitActivated(unsigned, const QString &, bool)),
          this, SLOT(activateWorkunit(unsigned, const QString &, bool)));
  
  connect(this, SIGNAL(fileUpdated(const QString &)), this, SLOT(updateFile(const QString &)));

  const BOINCClientState *state = parent->state();
  if(NULL != state)
  {
    addWorkunits(state->workunit.keys());
    for(QMap<unsigned,BOINCActiveTask>::const_iterator task = state->active_task_set.active_task.begin();
        task != state->active_task_set.active_task.end(); ++task)
    {
      const QString result = (*task).result_name;
      activateWorkunit(task.key(), state->result[result].wu_name, true);
    }
  }
}

KBSCPDNMonitor::~KBSCPDNMonitor()
{
  for(QDictIterator<KProcess> it(m_processes); it.current() != NULL; ++it)
    it.current()->kill();
}

const CPDNUMID *KBSCPDNMonitor::result(const QString &workunit) const
{
  const KBSFileInfo *file = this->file(formatFileName(workunit));
  if(NULL == file) return NULL;
  
  return file->ok ? m_results.find(workunit) : NULL;
}

KBSLogManager *KBSCPDNMonitor::logManager() const
{
  return NULL;
}

KURL KBSCPDNMonitor::graphicsURL() const
{
  return KURL(url(), CPDNGraphicsFileName);
}

bool KBSCPDNMonitor::canShowGraphics(const QString &workunit) const
{
  // if we have a process for it, obviously we can show graphics
  if(m_processes.find(workunit) != NULL) return true;
  
  // can't show graphics if the URL is not local
  if(!boincMonitor()->isLocal()) return false;
  KURL graphicsURL = this->graphicsURL();
  if(!graphicsURL.isLocalFile()) return false;
  
  // if called without an argument, do not perform further tests
  if(workunit.isEmpty()) return true;
  
  // can't show graphics if the viz application doesn't exists
  if(!QFile(graphicsURL.path()).exists()) return false;
  
  // can't show graphics if the workunit is not active
  const BOINCClientState *state = boincMonitor()->state();
  if(NULL == state) return false;
  
  const QString result = state->workunit[workunit].result_name;
  if(result.isEmpty()) return false;
  
  const int task = state->active_task_set.index(result);
  if(task < 0) return false;
  
  return(state->active_task_set.active_task[task].scheduler_state > 1);
}

void KBSCPDNMonitor::showGraphics(const QString &workunit)
{
  if(!canShowGraphics(workunit)) return;
  
  if(m_processes.find(workunit) != NULL) return;
  
  KProcess *process = new KProcess(this);
  m_processes.insert(workunit, process);
  
  process->setWorkingDirectory(url().path());
  *process << graphicsURL().path() << workunit;
  
  connect(process, SIGNAL(processExited(KProcess *)), this, SLOT(slotProcessExited(KProcess *)));
  
  process->start();
}  
  
bool KBSCPDNMonitor::parseFile(KBSFileInfo *file, const QString &fileName)
{  
  qDebug("Parsing file %s...", file->fileName.latin1());
  
  const QString workunit = parseFileName(file->fileName);
  
  CPDNUMID *umid = m_results.find(workunit);
  if(NULL == umid) {
    umid = new CPDNUMID();
    m_results.insert(workunit, umid);
  }
  
  QDomDocument document(file->fileName);
  if(!readFile(fileName, document)) return false;
    
  return parseResultDocument(document, *umid);
}

QString KBSCPDNMonitor::parseFileName(const QString &fileName)
{
  return fileName.endsWith(".xml") ? fileName.left(fileName.length() - 4) : fileName;
}

QString KBSCPDNMonitor::formatFileName(const QString &workunit)
{
  return QString("%1.xml").arg(workunit);
}

void KBSCPDNMonitor::addWorkunits(const QStringList &workunits)
{
  const BOINCClientState *state = boincMonitor()->state();
  if(NULL == state) return;
  
  for(QStringList::const_iterator workunit = workunits.constBegin();
      workunit != workunits.constEnd(); ++workunit)
  {
    if(boincMonitor()->project(state->workunit[*workunit]) != project()) continue;
    
    const QString fileName = formatFileName(*workunit);
    
    addFile(fileName);
    setMonitoring(fileName, false);
  }        
}

void KBSCPDNMonitor::removeWorkunits(const QStringList &workunits)
{
  for(QStringList::const_iterator workunit = workunits.constBegin();
      workunit != workunits.constEnd(); ++workunit)
    if(m_results.find(*workunit) != NULL) {
      removeFile(formatFileName(*workunit));
      m_results.remove(*workunit);
    }
}

void KBSCPDNMonitor::activateWorkunit(unsigned, const QString &workunit, bool active)
{
  if(m_results.find(workunit) == NULL) return;
  
  setMonitoring(formatFileName(workunit), active);
}

bool KBSCPDNMonitor::parseResultDocument(const QDomDocument &document, CPDNUMID &umid)
{
  for(QDomNode child = document.firstChild(); !child.isNull(); child = child.nextSibling())
    if(child.isElement()) {
      QDomElement element = child.toElement();
      const QString elementName = element.nodeName().lower(); 
      
      if(elementName == "umid") {
        if(!umid.parse(element)) return false;
      }
    }
  
  qDebug("... parse OK");
  
  return true;
}

void KBSCPDNMonitor::updateFile(const QString &fileName)
{
  emit updatedResult(parseFileName(fileName));
}

void KBSCPDNMonitor::slotProcessExited(KProcess *process)
{
  QString workunit;
  for(QDictIterator<KProcess> it(m_processes); it.current() != NULL; ++it)
    if(it.current() == process) {
      workunit = it.currentKey();
      break;
    }
  if(workunit.isNull()) return;
  
  m_processes.remove(workunit);
  delete process;
}

#include "kbscpdnmonitor.moc"

Generated by  Doxygen 1.6.0   Back to index