/*************************************************************************** copyright : (C) 2007 by Robby Stephenson email : robby@periapsis.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of version 2 of the GNU General Public License as * * published by the Free Software Foundation; * * * ***************************************************************************/ #include "citebasefetcher.h" #include "messagehandler.h" #include "../translators/bibteximporter.h" #include "../tellico_kernel.h" #include "../tellico_utils.h" #include "../collection.h" #include "../entry.h" #include "../core/netaccess.h" #include "../filehandler.h" #include "../tellico_debug.h" #include #include #include // #define CITEBASE_TEST namespace { // always bibtex static const char* CITEBASE_BASE_URL = "http://www.citebase.org/openurl/?url_ver=Z39.88-2004&svc_id=bibtex"; } using Tellico::Fetch::CitebaseFetcher; CitebaseFetcher::CitebaseFetcher(TQObject* parent_) : Fetcher(parent_), m_job(0), m_started(false) { } CitebaseFetcher::~CitebaseFetcher() { } TQString CitebaseFetcher::defaultName() { return TQString::fromLatin1("Citebase"); } TQString CitebaseFetcher::source() const { return m_name.isEmpty() ? defaultName() : m_name; } bool CitebaseFetcher::canFetch(int type) const { return type == Data::Collection::Bibtex; } void CitebaseFetcher::readConfigHook(const KConfigGroup&) { } void CitebaseFetcher::search(FetchKey key_, const TQString& value_) { m_key = key_; m_value = value_.stripWhiteSpace(); m_started = true; if(!canFetch(Kernel::self()->collectionType())) { message(i18n("%1 does not allow searching for this collection type.").arg(source()), MessageHandler::Warning); stop(); return; } m_data.truncate(0); // myDebug() << "CitebaseFetcher::search() - value = " << value_ << endl; KURL u = searchURL(m_key, m_value); if(u.isEmpty()) { stop(); return; } m_job = KIO::get(u, false, false); connect(m_job, TQT_SIGNAL(data(KIO::Job*, const TQByteArray&)), TQT_SLOT(slotData(KIO::Job*, const TQByteArray&))); connect(m_job, TQT_SIGNAL(result(KIO::Job*)), TQT_SLOT(slotComplete(KIO::Job*))); } void CitebaseFetcher::stop() { if(!m_started) { return; } // myDebug() << "CitebaseFetcher::stop()" << endl; if(m_job) { m_job->kill(); m_job = 0; } m_data.truncate(0); m_started = false; emit signalDone(this); } void CitebaseFetcher::slotData(KIO::Job*, const TQByteArray& data_) { TQDataStream stream(m_data, IO_WriteOnly | IO_Append); stream.writeRawBytes(data_.data(), data_.size()); } void CitebaseFetcher::slotComplete(KIO::Job* job_) { // myDebug() << "CitebaseFetcher::slotComplete()" << endl; // since the fetch is done, don't worry about holding the job pointer m_job = 0; if(job_->error()) { job_->showErrorDialog(Kernel::self()->widget()); stop(); return; } if(m_data.isEmpty()) { myDebug() << "CitebaseFetcher::slotComplete() - no data" << endl; stop(); return; } #if 0 kdWarning() << "Remove debug from citebasefetcher.cpp" << endl; TQFile f(TQString::fromLatin1("/tmp/test.bib")); if(f.open(IO_WriteOnly)) { TQTextStream t(&f); t.setEncoding(TQTextStream::UnicodeUTF8); t << TQCString(m_data, m_data.size()+1); } f.close(); #endif Import::BibtexImporter imp(TQString::fromUtf8(m_data, m_data.size())); Data::CollPtr coll = imp.collection(); if(!coll) { myDebug() << "CitebaseFetcher::slotComplete() - no valid result" << endl; stop(); return; } Data::EntryVec entries = coll->entries(); for(Data::EntryVec::Iterator entry = entries.begin(); entry != entries.end(); ++entry) { if(!m_started) { // might get aborted break; } TQString desc = entry->field(TQString::fromLatin1("author")) + TQChar('/') + entry->field(TQString::fromLatin1("publisher")); if(!entry->field(TQString::fromLatin1("year")).isEmpty()) { desc += TQChar('/') + entry->field(TQString::fromLatin1("year")); } SearchResult* r = new SearchResult(this, entry->title(), desc, entry->field(TQString::fromLatin1("isbn"))); m_entries.insert(r->uid, Data::EntryPtr(entry)); emit signalResultFound(r); } stop(); // required } Tellico::Data::EntryPtr CitebaseFetcher::fetchEntry(uint uid_) { return m_entries[uid_]; } KURL CitebaseFetcher::searchURL(FetchKey key_, const TQString& value_) const { KURL u(TQString::fromLatin1(CITEBASE_BASE_URL)); switch(key_) { case ArxivID: { // remove prefix and/or version number TQString value = value_; value.remove(TQRegExp(TQString::fromLatin1("^arxiv:"), false)); value.remove(TQRegExp(TQString::fromLatin1("v\\d+$"))); u.addQueryItem(TQString::fromLatin1("rft_id"), TQString::fromLatin1("oai:arXiv.org:%1").arg(value)); } break; default: kdWarning() << "CitebaseFetcher::search() - key not recognized: " << m_key << endl; return KURL(); } #ifdef CITEBASE_TEST u = KURL::fromPathOrURL(TQString::fromLatin1("/home/robby/citebase.bib")); #endif myDebug() << "CitebaseFetcher::search() - url: " << u.url() << endl; return u; } void CitebaseFetcher::updateEntry(Data::EntryPtr entry_) { TQString arxiv = entry_->field(TQString::fromLatin1("arxiv")); if(!arxiv.isEmpty()) { search(Fetch::ArxivID, arxiv); return; } myDebug() << "CitebaseFetcher::updateEntry() - insufficient info to search" << endl; emit signalDone(this); // always need to emit this if not continuing with the search } void CitebaseFetcher::updateEntrySynchronous(Data::EntryPtr entry) { if(!entry) { return; } TQString arxiv = entry->field(TQString::fromLatin1("arxiv")); if(arxiv.isEmpty()) { return; } KURL u = searchURL(ArxivID, arxiv); TQString bibtex = FileHandler::readTextFile(u, true); if(bibtex.isEmpty()) { return; } // assume result is always utf-8 Import::BibtexImporter imp(bibtex); Data::CollPtr coll = imp.collection(); if(coll && coll->entryCount() > 0) { myLog() << "CitebaseFetcher::updateEntrySynchronous() - found arxiv result, merging" << endl; Data::Collection::mergeEntry(entry, coll->entries().front(), false /*overwrite*/); } } Tellico::Fetch::ConfigWidget* CitebaseFetcher::configWidget(TQWidget* parent_) const { return new CitebaseFetcher::ConfigWidget(parent_, this); } CitebaseFetcher::ConfigWidget::ConfigWidget(TQWidget* parent_, const CitebaseFetcher*) : Fetch::ConfigWidget(parent_) { TQVBoxLayout* l = new TQVBoxLayout(optionsWidget()); l->addWidget(new TQLabel(i18n("This source has no options."), optionsWidget())); l->addStretch(); } void CitebaseFetcher::ConfigWidget::saveConfig(KConfigGroup&) { } TQString CitebaseFetcher::ConfigWidget::preferredName() const { return CitebaseFetcher::defaultName(); } #include "citebasefetcher.moc"