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

woksearcher.cpp

//
// C++ Implementation: woksearcher
//
// Description: 
//
//
// Author: Thach Nguyen <thach.nguyen@rmit.edu.au>, (C) 2007
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "woksearcher.h"
#include "searchmanager.h"

#include <klocale.h>
#include <kio/job.h>
#include <kstandarddirs.h>
#include <kconfig.h>
#include <kcombobox.h>
#include <klineedit.h>
#include <kaccelmanager.h>
#include <knuminput.h>
#include <qdom.h>
#include <qregexp.h>
#include <qlabel.h>
#include <qfile.h>
#include <qlayout.h>
#include <qwhatsthis.h>

#include <iostream>

namespace {
  static const char* WOK_BASE_URL = "http://estipub.isiknowledge.com";
  static const char* WOK_SEARCH_CGI = "esti/cgi";
}


WOKSearcher::WOKSearcher(QObject *parent, const char *name)
      : searcher(parent, name),m_step(Begin), m_started(false)
{
      m_host = QString::fromLatin1(WOK_BASE_URL);
      m_dbname = QString::fromLatin1("WOS");
}


WOKSearcher::~WOKSearcher()
{
}
QString WOKSearcher::defaultName() {
      return i18n("Web of Knowledge");
}

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

void WOKSearcher::readConfig(KConfig* config_, const QString& group_) {
      KConfigGroupSaver groupSaver(config_, group_);
      QString s = config_->readEntry("Database", QString::fromLatin1("WOS")); 
      if(!s.isEmpty()) {
            m_dbname = s;
      }
      
      s = config_->readEntry("Name", defaultName()); 
      if(!s.isEmpty()) {
            m_name = s;
      }
      
      m_host = config_->readEntry("Host", WOK_BASE_URL);
}


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

void WOKSearcher::search(SearchKey key1, SearchKey key2, SearchKey key3 , const QString& value1, const QString& value2, const QString& value3, int operator1, int operator2) {
    std::cerr << "Searching WOK\n";
    m_started = true;

    m_data.truncate(0);

    m_url = KURL(m_host);
    m_url.addPath(QString::fromLatin1(WOK_SEARCH_CGI));

    QString str;
    m_query = QString();

    if (!value1.isEmpty())
    {
        switch(key1)
        {
        case Title:
            m_query = QString::fromLatin1("TI=(");
            break;

        case Author:
            m_query = QString::fromLatin1("AU=(");
            break;

        case Keyword:
            m_query = QString::fromLatin1("TS=(");
            break;

        case Year:
            m_query = QString::fromLatin1("PY=(");
            break;

        default:
            stop();
            return;
        }
            m_query += value1 + QString::fromLatin1(")");
    }


    if (!value2.isEmpty() )
    {
        if (!m_query.isEmpty())
        {
            switch(operator1)
            {
            case 0:
                m_query += QString::fromLatin1(" and ");
                break;
            case 1:
                m_query += QString::fromLatin1(" or ");
                break;
            case 2:
                m_query += QString::fromLatin1(" not ");
                break;
            default:
                stop();
                return;
            }

        }

        switch(key2)
        {
        case Title:
            m_query += QString::fromLatin1("TI=(");
            break;

        case Author:
            m_query += QString::fromLatin1("AU=(");
            break;

        case Keyword:
            m_query += QString::fromLatin1("TS=(");
            break;

        case Year:
            m_query += QString::fromLatin1("PY=(");
            break;

        default:
            stop();
            return;
        }
            m_query += value2 + QString::fromLatin1(")");

    }

    if (!value3.isEmpty() )
    {
        if (!m_query.isEmpty())
        {
            switch(operator2)
            {
            case 0:
                m_query += QString::fromLatin1(" and ");
                break;
            case 1:
                m_query += QString::fromLatin1(" or ");
                break;
            case 2:
                m_query += QString::fromLatin1(" not ");
                break;
            default:
                stop();
                return;
            }

        }
        switch(key3)
        {
        case Title:
            m_query += str + QString::fromLatin1("TI=(");
            break;

        case Author:
            m_query += str + QString::fromLatin1("AU=(");
            break;

        case Keyword:
            m_query += str + QString::fromLatin1("TS=(");
            break;

        case Year:
            m_query += str + QString::fromLatin1("PY=(");
            break;

        default:
            stop();
            return;
        }
            m_query += value3 + QString::fromLatin1(")");

    }


    if (m_query.isEmpty())
    {
        stop();
        return;
    }
    m_url.addQueryItem(QString::fromLatin1("databaseID"), m_dbname);
    m_url.addQueryItem(QString::fromLatin1("rspType"), "xml");
    m_url.addQueryItem(QString::fromLatin1("method"), "search");
      m_url.addQueryItem(QString::fromLatin1("firstRec"), "1");
      m_url.addQueryItem(QString::fromLatin1("numRecs"), "1");
      m_url.addQueryItem(QString::fromLatin1("query"), m_query);

    m_step = Search;

    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 WOKSearcher::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 WOKSearcher::slotData(KIO::Job*, const QByteArray& data_) {
      QDataStream stream(m_data, IO_WriteOnly | IO_Append);
      stream.writeRawBytes(data_.data(), data_.size());
}

void WOKSearcher::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 << "WOKSearcher::slotComplete() - no data\n";
            stop();
            return;
      }

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

void WOKSearcher::searchResults(){
/*    QFile f(QString::fromLatin1("/home/s9510300/tmp/WOS1.xml"));
    QString str;
    if(f.open(IO_ReadOnly)) {
      QTextStream stream( &f );
      str = stream.read(); 
      f.close();
    }
      
      QDomDocument dom;
      if(!dom.setContent(str, false)) {
            std::cerr << "WOKSearcher::fetchResults() - server did not return valid XML.\n";
            stop();
            return;
      }
*/

      
      
      QString str = QString::fromUtf8(m_data, m_data.size());
      
      QDomDocument dom;
      if(!dom.setContent(m_data, false)) {
            std::cerr << "WOKSearcher::searchResults() - server did not return valid XML.\n";
            stop();
            return;
      }

      int count = 0;
      for(QDomNode n = dom.documentElement().firstChild(); !n.isNull(); n = n.nextSibling()) {
            if ( n.nodeName() == QString::fromLatin1 ( "searchResults" ) )
            {
                  for ( QDomNode f = n.firstChild(); !f.isNull(); f = f.nextSibling() )
                  {

                        QDomElement e = f.toElement();
                        if ( e.isNull() )
                        {
                              continue;
                        }
                        if ( e.tagName() == QString::fromLatin1 ( "recordsFound" ) )
                        {
                              m_total = e.text().toInt();
                              break;
                        }
                  }
                  count++;
                  
            }
            else if (n.nodeName() == QString::fromLatin1 ( "sessionID" ) ){
                  QDomElement e = n.toElement();      
                  m_sessionID = e.text();
                  count++;
            }
            if (count == 2)
                  break;
      }
      m_waitingRetrieveRange = true;
      m_step = Wait;
      if (m_total > 0)
            emit signalQueryResult(m_total);    
      else{
            signalMessage(i18n("No reference was found"), 1);
            stop();
      }

      
}


void WOKSearcher::retrieveRange(unsigned int min, unsigned int max){
      if (m_step != Wait)
            return;
      m_waitingRetrieveRange = false;
    if ((min < 1 && max < 1) || max < min)
    {
        stop();
        return;
    }
      m_url = KURL(m_host);
      m_url.addPath(QString::fromLatin1(WOK_SEARCH_CGI));
    m_url.addQueryItem(QString::fromLatin1("databaseID"), m_dbname);
      m_url.addQueryItem(QString::fromLatin1("SID"), m_sessionID);
    m_url.addQueryItem(QString::fromLatin1("rspType"), "xml");
    m_url.addQueryItem(QString::fromLatin1("method"), "searchRetrieve");
      m_url.addQueryItem(QString::fromLatin1("firstRec"), QString::number(min));
      m_url.addQueryItem(QString::fromLatin1("numRecs"), QString::number(max-min+1));
      m_url.addQueryItem(QString::fromLatin1("query"), m_query);


    m_data.truncate(0);
    m_step = Fetch;

    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 WOKSearcher::fetchResults(){
/*    QFile f(QString::fromLatin1("/home/s9510300/tmp/CCC.xm"));
    QString str;
    if(f.open(IO_ReadOnly)) {
      QTextStream stream( &f );
      str = stream.read(); 
      f.close();
    }
      
      QDomDocument dom;
      if(!dom.setContent(str, false)) {
            std::cerr << "WOKSearcher::fetchResults() - server did not return valid XML.\n";
            stop();
            return;
      }
*/    
      
      
      QDomDocument dom;
      if(!dom.setContent(m_data, false)) {
            std::cerr << "WOKSearcher::fetchResults() - server did not return valid XML.\n";
            stop();
            return;
      }

      BibEntry *entry;
      
      for(QDomNode m = dom.documentElement().firstChild(); !m.isNull(); m = m.nextSibling()) {
            if ( m.nodeName() == QString::fromLatin1 ( "records" ) )
            {
                  for ( QDomNode n = m.firstChild(); !n.isNull(); n = n.nextSibling() )
                  {

                        if ( n.nodeName() == QString::fromLatin1 ( "REC" ) ){
                              for (QDomNode o = n.firstChild(); !o.isNull(); o = o.nextSibling() ){

                                    if ( o.nodeName() == QString::fromLatin1 ( "item" ) )
                                    {
                                          entry = new BibEntry(QString::fromLatin1("article"), QString());
                                          QDomElement e;
                                          for ( QDomNode p = o.firstChild(); !p.isNull(); p = p.nextSibling() )
                                          {

                                                if (p.nodeName() == QString::fromLatin1("source_title") ){
                                                      e = p.toElement();      
                                                      if (!e.isNull()){
                                                            if (!e.text().isEmpty())
                                                                  entry->setField(QString::fromLatin1("journal"), e.text());  
                                                      }
                                                }
                                                else if (p.nodeName() == QString::fromLatin1("item_title") ){
                                                      e = p.toElement();      
                                                      if (!e.isNull()){
                                                            if (!e.text().isEmpty())
                                                                  entry->setField(QString::fromLatin1("title"), e.text());    
                                                      }
                                                }
                                                else if (p.nodeName() == QString::fromLatin1("bib_pages") ){
                                                      e = p.toElement();      
                                                      if (!e.isNull()){
                                                            if (!e.text().isEmpty())
                                                                  entry->setField(QString::fromLatin1("pages"), e.text());    
                                                      }
                                                }
                                                else if (p.nodeName() == QString::fromLatin1("ut") ){
                                                      e = p.toElement();      
                                                      if (!e.isNull()){
                                                            if (!e.text().isEmpty())
                                                                  entry->setField(QString::fromLatin1("url"), QString::fromLatin1("http://links.isiglobalnet2.com/gateway/Gateway.cgi?GWVersion=1&SrcAuth=KBib&SrcApp=KBib&KeyUT=") + e.text());      
                                                      }
                                                }
                                                else if (p.nodeName() == QString::fromLatin1("article_nos") ){
                                                      for ( QDomNode q = p.firstChild(); !q.isNull(); q = q.nextSibling() ){
                                                            if ( q.nodeName() == QString::fromLatin1 ( "article_no" ) ){
                                                                  e = p.toElement();      
                                                                  if (!e.isNull()){
                                                                        if (!e.text().isEmpty())
                                                                              entry->setField(QString::fromLatin1("doi"), e.text().section(QString::fromLatin1("DOI "), 1));  
                                                                  }
                                                            }
                                                      }
                                                }
                                                else if (p.nodeName() == QString::fromLatin1("bib_issue") ){
                                                      QDomNamedNodeMap nodeMap = p.attributes();
                                                      for (int i = 0; i < nodeMap.count(); i++){
                                                            if (nodeMap.item(i).nodeName() == QString::fromLatin1("year"))
                                                                  entry->setField(QString::fromLatin1("year"), nodeMap.item(i).nodeValue());
                                                            if (nodeMap.item(i).nodeName() == QString::fromLatin1("vol"))
                                                                  entry->setField(QString::fromLatin1("volume"), nodeMap.item(i).nodeValue());
                                                      }
                                                }
                                                
                                                else if (p.nodeName() == QString::fromLatin1("bib_id") ){
                                                      e = p.toElement();      
                                                      if (!e.isNull()){
                                                            if (!e.text().isEmpty()){
                                                                  QRegExp entryRx1(QString::fromLatin1(".*\\((.+)\\):.+\\s+(.+)\\s+\\d\\d\\s+\\d\\d\\d\\d") );          
                                                                  QRegExp entryRx2(QString::fromLatin1(".*\\((.+)\\):.+\\s+(.+)\\s+\\d\\d\\d\\d") );
                                                                  QRegExp entryRx3(QString::fromLatin1(".*\\((.+)\\):.+\\s+\\d\\d\\d\\d") );
                                                                  QRegExp entryRx4(QString::fromLatin1(".*:.+\\s+(\\S+)\\s+\\d\\d\\d\\d") );
                                                                  
                                                                  
                                                                  if (entryRx1.exactMatch(e.text()))
                                                            {
                                                                        QString text = entryRx1.cap(1);
                                                                        entry->setField(QString::fromLatin1("number"),text);
                                                                        text = entryRx1.cap(2);
                                                                        entry->setField(QString::fromLatin1("month"),text);
                                                            
                                                                  }
                                                                  else if (entryRx2.exactMatch(e.text()))
                                                            {
                                                                        QString text = entryRx2.cap(1);
                                                                        entry->setField(QString::fromLatin1("number"),text);
                                                                        text = entryRx2.cap(2);
                                                                        entry->setField(QString::fromLatin1("month"),text);
                                                            
                                                                  }
                                                                  
                                                                  else if (entryRx3.exactMatch(e.text()))
                                                            {
                                                                        QString text = entryRx3.cap(1);
                                                                        entry->setField(QString::fromLatin1("number"),text);
                                                                  }
                                                                  else if (entryRx4.exactMatch(e.text()))
                                                            {
                                                                        QString text = entryRx4.cap(1);
                                                                        entry->setField(QString::fromLatin1("month"),text);
                                                            
                                                                  }
                                                            }     
                                                      }
                                                }
                                                
                                                else if (p.nodeName() == QString::fromLatin1("authors") ){
                                                      RefField *field = BibEntryDefTable::self()->getRefField(QString::fromLatin1("author"));
                                                      QString linkSt;
                                                      if (field)
                                                            linkSt = field->connectingString;
                                                      else
                                                            linkSt = QString::fromLatin1(" and ");
                                                      QString author;
                                                      for ( QDomNode q = p.firstChild(); !q.isNull(); q = q.nextSibling() ){
                                                            if ( q.nodeName() == QString::fromLatin1 ( "primaryauthor" ) || q.nodeName() == QString::fromLatin1 ( "author" )){
                                                                  e = q.toElement();      
                                                                  if (!e.isNull()){
                                                                        if (!e.text().isEmpty()){
                                                                              if (author.isEmpty() )
                                                                                    author = e.text();
                                                                              else  
                                                                                    author = author + linkSt + e.text();
                                                                        }
                                                                                          
                                                                  }     
                                                                  
                                                            }
                                                      
                                                            
                                                      }
                                                      if (!author.isEmpty())
                                                            entry->setField(QString::fromLatin1("author"), author);
                                                }
                                                      
                                                else if (p.nodeName() == QString::fromLatin1("keywords") || p.nodeName() == QString::fromLatin1("keywords_plus")  ){
                                                      RefField *field = BibEntryDefTable::self()->getRefField(QString::fromLatin1("keywords"));
                                                      QString linkSt;
                                                      if (field)
                                                            linkSt = field->connectingString;
                                                      else
                                                            linkSt = QString::fromLatin1(", ");
                                                      QString keywords = entry->getField(QString::fromLatin1("keywords"));
                                                      for ( QDomNode q = p.firstChild(); !q.isNull(); q = q.nextSibling() ){
                                                            if ( q.nodeName() == QString::fromLatin1 ( "keyword" ) || q.nodeName() == QString::fromLatin1 ( "keyplus" ) ){
                                                                  e = q.toElement();      
                                                                  if (!e.isNull()){
                                                                        if (!e.text().isEmpty()){
                                                                              if (keywords.isEmpty() )
                                                                                    keywords = e.text().lower();
                                                                              else  
                                                                                    keywords = keywords + linkSt + e.text().lower();
                                                                                    
                                                                                          
                                                                        }
                                                                  }     
                                                            }
                                                      }
                                                      if (!keywords.isEmpty())
                                                            entry->setField(QString::fromLatin1("keywords"), keywords);
                                                }
                                                else if (p.nodeName() == QString::fromLatin1("abstract") ){
                                                      QString abstract;
                                                      for ( QDomNode q = p.firstChild(); !q.isNull(); q = q.nextSibling() ){
                                                            if (q.nodeName() = QString::fromLatin1("p")){
                                                                  e = q.toElement();      
                                                                  if (!e.isNull()){
                                                                        if (!e.text().isEmpty()){
                                                                              if (abstract.isEmpty())
                                                                                    abstract = e.text();
                                                                              else
                                                                                    abstract = abstract + QString::fromLatin1("\n\n") + e.text();
                                                                        
                                                                        }
                                                                  }
                                                            }     
                                                      }
                                                      entry->setField(QString::fromLatin1("abstract"), abstract); 
                                                      
                                                }
                                          
                                                
                                                
                                          }
                                          emit signalResultFound(new BibEntry(*entry));
                                          delete entry;
                                          break;
                                    }
                                    
                              }
                        }
                        
                  }
                  
                  
                  break;
            }
      }
      stop();

}


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


QStringList WOKSearcher::searchKey(){
      QStringList keyList;
      keyList << searchManager::self()->searchKeyString(Author)
                  << searchManager::self()->searchKeyString(Title)
                  << searchManager::self()->searchKeyString(Topic)
                  << searchManager::self()->searchKeyString(Year);
      return keyList;
}


SearcherConfigWidget* WOKSearcher::configWidget(QWidget* parent_)
{
    return new WOKConfigWidget(parent_, this);
}


WOKConfigWidget::WOKConfigWidget(QWidget* parent_, WOKSearcher* searcher_ /*=0*/)
        : SearcherConfigWidget(parent_)
{
    m_searcher = searcher_;
    QGridLayout* l = new QGridLayout(optionsWidget(), 4, 2);
    l->setSpacing(4);
    l->setColStretch(1, 10);

    int row = -1;
    QLabel* label = new QLabel(i18n("Server address: "), optionsWidget());
    l->addWidget(label, ++row, 0);
    m_hostEdit = new KLineEdit(optionsWidget());
    l->addWidget(m_hostEdit, row, 1);
    QString w = i18n("Enter the host name or IP address of the WOK server. By default it is http://estipub.isiknowledge.com. If your instution uses different address, enter it here.");
    QWhatsThis::add(label, w);
    QWhatsThis::add(m_hostEdit, w);
    label->setBuddy(m_hostEdit);

    label = new QLabel(i18n("Database: "), optionsWidget());
    l->addWidget(label, ++row, 0);
    m_dataBaseCombo = new KComboBox(optionsWidget());
    m_dataBaseCombo->insertItem(QString::fromLatin1("Web of Science") ); //, QString::fromLatin1("WOS"));
    m_dataBaseCombo->insertItem(QString::fromLatin1("Current Contents Connect")); //, QString::fromLatin1("CCC"));
//    m_dataBaseCombo->insertItem(QString::fromLatin1("Food Science and Technology Abstracts")); //, QString::fromLatin1("FSTA"));
            
    l->addWidget(m_dataBaseCombo, row, 1);
      w = i18n("The database to search. Currently, KBib can search these databases: Web of Science (WOS) and Current Contents Connect (CCC) ");
    QWhatsThis::add(label, w);
    QWhatsThis::add(m_dataBaseCombo, w);
    label->setBuddy(m_dataBaseCombo);

    l->setRowStretch(++row, 1);

    if(searcher_)
    {
        m_hostEdit->setText(searcher_->m_host);
            if ((searcher_->m_dbname).upper() == QString::fromLatin1("CCC") )
                  m_dataBaseCombo->setCurrentItem(1);
//          else if ((searcher_->m_dbname).upper() == QString::fromLatin1("FSTA") )
//                m_dataBaseCombo->setCurrentItem(2);
            else
                  m_dataBaseCombo->setCurrentItem(0);
    }
      else
            m_hostEdit->setText(WOK_BASE_URL);
    KAcceleratorManager::manage(optionsWidget());
}

void WOKConfigWidget::updateSearcher()
{
    WOKSearcher *s = static_cast<WOKSearcher*>(m_searcher);
    s->m_host = m_hostEdit->text().stripWhiteSpace();
    switch(m_dataBaseCombo->currentItem()){
            case 1:
                  s->m_dbname = QString::fromLatin1("CCC");
                  break;
//          case 2:
//                s->m_dbname = QString::fromLatin1("FSTA");
//                break;
            default:
                  s->m_dbname = QString::fromLatin1("WOS");
                  break;      
                        
            
      }
}


#include "woksearcher.moc"

Generated by  Doxygen 1.6.0   Back to index