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

entrezsearcher.cpp

//
// C++ Implementation: entrezsearcher
//
// Description: 
//
//
// Author: Thach Nguyen <thach.nguyen@rmit.edu.au>, (C) 2006
//
// Copyright: See COPYING file that comes with this distribution
//
//

#include "entrezsearcher.h"
#include "searchmanager.h"
#include "bibfile.h"
#include "filters/bibprogs.h"
#include "bibentrytable.h"

#include <klocale.h>
#include <kconfig.h>
#include <kstandarddirs.h>

#include <qdom.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qfile.h>

namespace {
  static const int ENTREZ_MAX_RETURNS_TOTAL = 10;
  static const char* ENTREZ_BASE_URL = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/";
  static const char* ENTREZ_SEARCH_CGI = "esearch.fcgi";
  static const char* ENTREZ_SUMMARY_CGI = "esummary.fcgi";
  static const char* ENTREZ_FETCH_CGI = "efetch.fcgi";
  static const char* ENTREZ_LINK_CGI = "elink.fcgi";
  static const char* ENTREZ_DEFAULT_DATABASE = "pubmed";
}


EntrezSearcher::EntrezSearcher(QObject *parent, const char *name)
      : searcher(parent, name),m_step(Begin), m_started(false)
{
      
}


EntrezSearcher::~EntrezSearcher()
{
}
QString EntrezSearcher::defaultName() {
      return i18n("Entrez Database");
}

QString EntrezSearcher::source() const {
      return m_name.isEmpty() ? defaultName() : m_name;
}

void EntrezSearcher::readConfig(KConfig* config_, const QString& group_) {
      KConfigGroupSaver groupSaver(config_, group_);
      QString s = config_->readEntry("Database", QString::fromLatin1("pubmed")); // default to pubmed
      if(!s.isEmpty()) {
            m_dbname = s;
      }
      
      s = config_->readEntry("Name", defaultName()); // default to pubmed
      if(!s.isEmpty()) {
            m_name = s;
      }
}


void EntrezSearcher::saveConfig(KConfig* config){
      config->writeEntry("Database", m_dbname);
}

void EntrezSearcher::search(SearchKey key1, SearchKey key2, SearchKey key3 , const QString& value1, const QString& value2, const QString& value3, int operator1, int operator2) {

      if(m_dbname.isEmpty()) {
            m_dbname = QString::fromLatin1(ENTREZ_DEFAULT_DATABASE);
      }

      m_started = true;
      m_data.truncate(0);
  m_url = KURL(QString::fromLatin1(ENTREZ_BASE_URL));
  m_url.addPath(QString::fromLatin1(ENTREZ_SEARCH_CGI));
  m_url.addQueryItem(QString::fromLatin1("tool"),       QString::fromLatin1("KBib"));
  m_url.addQueryItem(QString::fromLatin1("retmode"),    QString::fromLatin1("xml"));
  m_url.addQueryItem(QString::fromLatin1("usehistory"), QString::fromLatin1("y"));
  m_url.addQueryItem(QString::fromLatin1("retmax"),     QString::fromLatin1("1")); // we're just getting the count
  m_url.addQueryItem(QString::fromLatin1("db"),         m_dbname);
   
  QString str;
  QString query = QString();
  if (!value1.isEmpty()){
  
        str = QChar('"') + value1 + QChar('"');
        switch(key1) {
              case Title:
                    query = str + QString::fromLatin1("[titl]");
                    break;

              case Author:
                    query = str + QString::fromLatin1("[auth]");
                    break;

              case Keyword:
                    query = str + QString::fromLatin1("[MH]");
                    break;

              case All:
                    query = str + QString::fromLatin1("[ALL]");
                    break;      
                    
              case Journal:     
                    query = str + QString::fromLatin1("[TA]");
                    break;
                    
              case Year:        
                    query = str + QString::fromLatin1("[PDAT]");
                    break;
              default:
                    stop();
                    return;
        }
  }
  
  if (!value2.isEmpty() ){
        if (!query.isEmpty()){
              switch(operator1){
                    case 0:
                          query += QString::fromLatin1(" AND ");
                          break;
                    case 1:
                          query += QString::fromLatin1(" OR ");
                          break;
                    case 2:
                          query += QString::fromLatin1(" NOT ");
                          break;
                    default:
                          stop();
                          return;    
              }
            
        }
        str = QChar('"') + value2 + QChar('"');
        switch(key2) {
              case Title:
                    query += str + QString::fromLatin1("[titl]");
                    break;

              case Author:
                    query += str + QString::fromLatin1("[auth]");
                    break;

              case Keyword:
                    query += str + QString::fromLatin1("[MH]");
                    break;

              case All:
                    query += str + QString::fromLatin1("[ALL]");
                    break;      
                    
              case Journal:     
                    query += str + QString::fromLatin1("[TA]");
                    break;
                    
              case Year:        
                    query += str + QString::fromLatin1("[PDAT]");
                    break;
              default:
                    stop();
                    return;
        }
        
  }
  
  if (!value3.isEmpty() ){
        if (!query.isEmpty()){
              switch(operator2){
                    case 0:
                          query += QString::fromLatin1(" AND ");
                          break;
                    case 1:
                          query += QString::fromLatin1(" OR ");
                          break;
                    case 2:
                          query += QString::fromLatin1(" NOT ");
                          break;
                    default:
                          stop();
                          return;    
              }
            
        }
        str = QChar('"') + value3 + QChar('"');
        switch(key3) {
              case Title:
                    query += str + QString::fromLatin1("[titl]");
                    break;

              case Author:
                    query += str + QString::fromLatin1("[auth]");
                    break;

              case Keyword:
                    query += str + QString::fromLatin1("[MH]");
                    break;

              case All:
                    query += str + QString::fromLatin1("[ALL]");
                    break;      
                    
              case Journal:     
                    query += str + QString::fromLatin1("[TA]");
                    break;
                    
              case Year:        
                    query += str + QString::fromLatin1("[PDAT]");
                    break;
              default:
                    stop();
                    return;
        }
        
  }
  
  if (query.isEmpty()){
        stop();
        return;
  }
  
  
  m_url.addQueryItem(QString::fromLatin1("term"), query);
  
 
  m_step = Search;
  std::cerr << m_url.prettyURL() << "\n";
  m_job = KIO::get(m_url, false, false);
  connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
              SLOT(slotData(KIO::Job*, const QByteArray&)));
  connect(m_job, SIGNAL(result(KIO::Job*)),
              SLOT(slotComplete(KIO::Job*)));
}

void EntrezSearcher::stop() {
      if(!m_started) {
            return;
      }
      if(m_job) {
            m_job->kill();
            m_job = 0;
      }
      m_started = false;
      m_data.truncate(0);
      m_step = Begin;
      emit signalDone(this);
}

void EntrezSearcher::slotData(KIO::Job*, const QByteArray& data_) {
      QDataStream stream(m_data, IO_WriteOnly | IO_Append);
      stream.writeRawBytes(data_.data(), data_.size());
}

void EntrezSearcher::slotComplete(KIO::Job* job_) {
  // since the fetch is done, don't worry about holding the job pointer
      m_job = 0;

      if(job_->error()) {
            emit signalMessage(job_->errorString(), 0);
            stop();
            return;
      }

      if(m_data.isEmpty()) {
            std::cerr << "EntrezSearcher::slotComplete() - no data\n";
            stop();
            return;
      }

  switch(m_step) {
        case Search:
              searchResults();
              break;
        case Fetch:
              fetchResults();
              break;
        default:
              std::cerr << "EntrezSearcher::slotComplete() - wrong step = " << m_step << "\n";
              break;
  }
}

void EntrezSearcher::searchResults() {
      QDomDocument dom;
      if(!dom.setContent(m_data, false)) {
            std::cerr << "EntrezFetcher::searchResults() - server did not return valid XML.\n";
            stop();
            return;
      }
  // find Count, QueryKey, and WebEnv elements
      int count = 0;
      for(QDomNode n = dom.documentElement().firstChild(); !n.isNull(); n = n.nextSibling()) {
            QDomElement e = n.toElement();
            if(e.isNull()) {
                  continue;
            }
            if(e.tagName() == QString::fromLatin1("Count")) {
                  m_total = e.text().toInt();
                  ++count;
            } else if(e.tagName() == QString::fromLatin1("QueryKey")) {
                  m_queryKey = e.text();
                  ++count;
            } else if(e.tagName() == QString::fromLatin1("WebEnv")) {
                  m_webEnv = e.text();
                  ++count;
            }
            if(count >= 3) {
                  break; // found them all
            }
      }
      m_waitingRetrieveRange = true;
      m_step = Wait;
      if (m_total > 0)
            emit signalQueryResult(m_total);    
      else{
            signalMessage(i18n("No reference was found"), 1);
            stop();
      }
}


void EntrezSearcher::retrieveRange(unsigned int min, unsigned int max){
    if (m_step != Wait)
            return;
      m_waitingRetrieveRange = false;
      if (min < 1 && max < 1){
            stop();
            return;
      }
      m_url = KURL(QString::fromLatin1(ENTREZ_BASE_URL));
      m_url.addPath(QString::fromLatin1(ENTREZ_FETCH_CGI));
      m_url.addQueryItem(QString::fromLatin1("tool"),       QString::fromLatin1("KBib"));
      m_url.addQueryItem(QString::fromLatin1("retmode"),    QString::fromLatin1("xml"));
      m_url.addQueryItem(QString::fromLatin1("retstart"),   QString::number(min-1));
      m_url.addQueryItem(QString::fromLatin1("retmax"),     QString::number(max-min+1));
      m_url.addQueryItem(QString::fromLatin1("usehistory"), QString::fromLatin1("y"));
      m_url.addQueryItem(QString::fromLatin1("db"),         m_dbname);
      m_url.addQueryItem(QString::fromLatin1("query_key"),  m_queryKey);
      m_url.addQueryItem(QString::fromLatin1("WebEnv"),     m_webEnv);

      m_data.truncate(0);
      m_step = Fetch;
//  myDebug() << m_url.prettyURL() << endl;
      m_job = KIO::get(m_url, false, false);
      connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
                  SLOT(slotData(KIO::Job*, const QByteArray&)));
      connect(m_job, SIGNAL(result(KIO::Job*)),
                  SLOT(slotComplete(KIO::Job*)));
      
}


void EntrezSearcher::fetchResults(){
      QFile f(QString::fromLatin1("/tmp/kbib-entrez-pubmed.xml"));
      if(f.open(IO_WriteOnly)) {
            QTextStream t(&f);
//          t.setEncoding(QTextStream::UnicodeUTF8);
//          t << QString(m_data); 
            t << QString::fromUtf8(m_data, m_data.size());
      }
      f.close();
            
      //Convert to bibtex
      med2xml("/tmp/kbib-entrez-pubmed.xml", "/tmp/kbib-entrez-mods.xml");
      xml2bib("/tmp/kbib-entrez-mods.xml", "/tmp/kbib-entrez-mods.bib");
      //Read bibfile
      BibentryTable *entryList = new BibentryTable();
      entryList->readBibfile("/tmp/kbib-entrez-mods.bib", false);
      
      for (int i = 0; i < entryList->size(); i++){
            BibEntry *bib = entryList->get_entry(i);
            if (bib)
                  emit signalResultFound(new BibEntry(*bib));     
      }
      delete entryList;
      stop();
}


void EntrezSearcher::setSource(const QString s){
      m_name = s ;      
}


QStringList EntrezSearcher::searchKey(){
      QStringList keyList;
      keyList << searchManager::self()->searchKeyString(All) << searchManager::self()->searchKeyString(Author)
                  << searchManager::self()->searchKeyString(Title) << searchManager::self()->searchKeyString(Journal)
                  << searchManager::self()->searchKeyString(Keyword) << searchManager::self()->searchKeyString(Year);
      return keyList;
}

SearcherConfigWidget* EntrezSearcher::configWidget(QWidget* parent_) {
      return new EntrezConfigWidget(parent_, this);
}

EntrezConfigWidget::EntrezConfigWidget(QWidget* parent_, EntrezSearcher* searcher_/*=0*/)
      : SearcherConfigWidget(parent_) {
      m_searcher = searcher_;
      QVBoxLayout* l = new QVBoxLayout(optionsWidget());
      l->addWidget(new QLabel(i18n("This source has no options."), optionsWidget()));
      l->addStretch();
}




#include "entrezsearcher.moc"

Generated by  Doxygen 1.6.0   Back to index