File indexing completed on 2024-05-12 05:09:41

0001 /***************************************************************************
0002     Copyright (C) 2012 Robby Stephenson <robby@periapsis.org>
0003  ***************************************************************************/
0004 
0005 /***************************************************************************
0006  *                                                                         *
0007  *   This program is free software; you can redistribute it and/or         *
0008  *   modify it under the terms of the GNU General Public License as        *
0009  *   published by the Free Software Foundation; either version 2 of        *
0010  *   the License or (at your option) version 3 or any later version        *
0011  *   accepted by the membership of KDE e.V. (or its successor approved     *
0012  *   by the membership of KDE e.V.), which shall act as a proxy            *
0013  *   defined in Section 14 of version 3 of the license.                    *
0014  *                                                                         *
0015  *   This program is distributed in the hope that it will be useful,       *
0016  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0018  *   GNU General Public License for more details.                          *
0019  *                                                                         *
0020  *   You should have received a copy of the GNU General Public License     *
0021  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
0022  *                                                                         *
0023  ***************************************************************************/
0024 
0025 #include "springerfetcher.h"
0026 #include "../entry.h"
0027 #include "../utils/isbnvalidator.h"
0028 #include "../tellico_debug.h"
0029 
0030 #include <KLocalizedString>
0031 #include <KConfigGroup>
0032 #include <QUrl>
0033 
0034 #include <QLabel>
0035 #include <QVBoxLayout>
0036 #include <QDomDocument>
0037 #include <QUrlQuery>
0038 
0039 namespace {
0040   static const char* SPRINGER_BASE_URL = "http://api.springer.com/metadata/pam";
0041   static const char* SPRINGER_API_KEY = "m2z42cbw68qhhjcrm8tbj2hc";
0042   static const int SPRINGER_QUERY_COUNT = 10;
0043 }
0044 
0045 using namespace Tellico;
0046 using Tellico::Fetch::SpringerFetcher;
0047 
0048 SpringerFetcher::SpringerFetcher(QObject* parent_)
0049     : XMLFetcher(parent_), m_start(0), m_total(-1) {
0050   setLimit(SPRINGER_QUERY_COUNT);
0051   setXSLTFilename(QStringLiteral("springer2tellico.xsl"));
0052 }
0053 
0054 SpringerFetcher::~SpringerFetcher() {
0055 }
0056 
0057 QString SpringerFetcher::source() const {
0058   return m_name.isEmpty() ? defaultName() : m_name;
0059 }
0060 
0061 QString SpringerFetcher::attribution() const {
0062   return i18n("This data is licensed under <a href=""%1"">specific terms</a>.",
0063               QLatin1String("https://dev.springernature.com/"));
0064 }
0065 
0066 bool SpringerFetcher::canSearch(Fetch::FetchKey k) const  {
0067   return k == Title || k == Person || k == Keyword || k == ISBN || k == DOI || k == Raw;
0068 }
0069 
0070 bool SpringerFetcher::canFetch(int type) const {
0071   return type == Data::Collection::Bibtex;
0072 }
0073 
0074 void SpringerFetcher::readConfigHook(const KConfigGroup&) {
0075 }
0076 
0077 void SpringerFetcher::resetSearch() {
0078   m_start = 0;
0079   m_total = -1;
0080 }
0081 
0082 QUrl SpringerFetcher::searchUrl() {
0083   QUrl u(QString::fromLatin1(SPRINGER_BASE_URL));
0084   QUrlQuery q;
0085   q.addQueryItem(QStringLiteral("api_key"), QLatin1String(SPRINGER_API_KEY));
0086   q.addQueryItem(QStringLiteral("s"), QString::number(m_start + 1));
0087   q.addQueryItem(QStringLiteral("p"), QString::number(SPRINGER_QUERY_COUNT));
0088 
0089   switch(request().key()) {
0090     case Title:
0091       q.addQueryItem(QStringLiteral("q"), QStringLiteral("title:\"%1\" OR book:\"%1\"").arg(request().value()));
0092       break;
0093 
0094     case Person:
0095       q.addQueryItem(QStringLiteral("q"), QStringLiteral("name:%1").arg(request().value()));
0096       break;
0097 
0098     case Keyword:
0099       q.addQueryItem(QStringLiteral("q"), QStringLiteral("\"%1\"").arg(request().value()));
0100       break;
0101 
0102     case ISBN:
0103       {
0104         // only grab first value
0105         QString v = request().value().section(QLatin1Char(';'), 0);
0106         v = ISBNValidator::isbn13(v);
0107         q.addQueryItem(QStringLiteral("q"), QStringLiteral("isbn:%1").arg(v));
0108       }
0109       break;
0110 
0111     case DOI:
0112       q.addQueryItem(QStringLiteral("q"), QStringLiteral("doi:%1").arg(request().value()));
0113       break;
0114 
0115     case Raw:
0116       q.addQueryItem(QStringLiteral("q"), request().value());
0117       break;
0118 
0119     default:
0120       return QUrl();
0121   }
0122   u.setQuery(q);
0123 
0124 //  myDebug() << "url:" << u.url();
0125   return u;
0126 }
0127 
0128 void SpringerFetcher::parseData(QByteArray& data_) {
0129   QDomDocument dom;
0130   if(!dom.setContent(data_, false)) {
0131     myWarning() << "server did not return valid XML.";
0132     return;
0133   }
0134   // total is /response/result/total
0135   QDomNode n = dom.documentElement().namedItem(QStringLiteral("result"))
0136                                     .namedItem(QStringLiteral("total"));
0137   QDomElement e = n.toElement();
0138   if(!e.isNull()) {
0139     m_total = e.text().toInt();
0140 //    myDebug() << "total = " << m_total;
0141   }
0142 }
0143 
0144 void SpringerFetcher::checkMoreResults(int count_) {
0145   m_start = count_;
0146   m_hasMoreResults = m_start < m_total;
0147 }
0148 
0149 Tellico::Fetch::FetchRequest SpringerFetcher::updateRequest(Data::EntryPtr entry_) {
0150   const QString doi = entry_->field(QStringLiteral("doi"));
0151   if(!doi.isEmpty()) {
0152     return FetchRequest(Fetch::DOI, doi);
0153   }
0154 
0155   const QString isbn = entry_->field(QStringLiteral("isbn"));
0156   if(!isbn.isEmpty()) {
0157     return FetchRequest(Fetch::ISBN, isbn);
0158   }
0159 
0160   const QString title = entry_->field(QStringLiteral("title"));
0161   if(!title.isEmpty()) {
0162     return FetchRequest(Fetch::Title, title);
0163   }
0164 
0165   return FetchRequest();
0166 }
0167 
0168 Tellico::Fetch::ConfigWidget* SpringerFetcher::configWidget(QWidget* parent_) const {
0169   return new SpringerFetcher::ConfigWidget(parent_, this);
0170 }
0171 
0172 QString SpringerFetcher::defaultName() {
0173   return QStringLiteral("SpringerLink");
0174 }
0175 
0176 QString SpringerFetcher::defaultIcon() {
0177   return favIcon("https://link.springer.com/static/sites/link/images/favicon-32x32.png");
0178 }
0179 
0180 SpringerFetcher::ConfigWidget::ConfigWidget(QWidget* parent_, const SpringerFetcher* fetcher_)
0181     : Fetch::ConfigWidget(parent_) {
0182   QVBoxLayout* l = new QVBoxLayout(optionsWidget());
0183   l->addWidget(new QLabel(i18n("This source has no options."), optionsWidget()));
0184   l->addStretch();
0185 
0186   // now add additional fields widget
0187   addFieldsWidget(SpringerFetcher::allOptionalFields(), fetcher_ ? fetcher_->optionalFields() : QStringList());
0188 }
0189 
0190 void SpringerFetcher::ConfigWidget::saveConfigHook(KConfigGroup&) {
0191 }
0192 
0193 QString SpringerFetcher::ConfigWidget::preferredName() const {
0194   return SpringerFetcher::defaultName();
0195 }