File indexing completed on 2024-11-24 04:34:32

0001 /***************************************************************************
0002  *   SPDX-License-Identifier: GPL-2.0-or-later
0003  *                                                                         *
0004  *   SPDX-FileCopyrightText: 2004-2019 Thomas Fischer <fischer@unix-ag.uni-kl.de>
0005  *   SPDX-FileCopyrightText: 2014 Pavel Zorin-Kranich <pzorin@math.uni-bonn.de>
0006  *   SPDX-FileCopyrightText: 2018 Alexander Dunlap <alexander.dunlap@gmail.com>
0007  *                                                                         *
0008  *   This program is free software; you can redistribute it and/or modify  *
0009  *   it under the terms of the GNU General Public License as published by  *
0010  *   the Free Software Foundation; either version 2 of the License, or     *
0011  *   (at your option) any later version.                                   *
0012  *                                                                         *
0013  *   This program is distributed in the hope that it will be useful,       *
0014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0016  *   GNU General Public License for more details.                          *
0017  *                                                                         *
0018  *   You should have received a copy of the GNU General Public License     *
0019  *   along with this program; if not, see <https://www.gnu.org/licenses/>. *
0020  ***************************************************************************/
0021 
0022 #include "onlinesearchmrlookup.h"
0023 
0024 #include <QNetworkReply>
0025 #include <QNetworkRequest>
0026 #include <QNetworkAccessManager>
0027 #include <QMap>
0028 #include <QUrlQuery>
0029 
0030 #include <KLocalizedString>
0031 
0032 #include <KBibTeX>
0033 #include <FileImporterBibTeX>
0034 #include "internalnetworkaccessmanager.h"
0035 #include "logging_networking.h"
0036 
0037 const QString OnlineSearchMRLookup::queryUrlStem = QStringLiteral("https://mathscinet.ams.org/mrlookup");
0038 
0039 OnlineSearchMRLookup::OnlineSearchMRLookup(QObject *parent)
0040         : OnlineSearchAbstract(parent)
0041 {
0042     /// nothing
0043 }
0044 
0045 void OnlineSearchMRLookup::startSearch(const QMap<QueryKey, QString> &query, int)
0046 {
0047     m_hasBeenCanceled = false;
0048     Q_EMIT progress(curStep = 0, numSteps = 1);
0049 
0050     QUrl url(queryUrlStem);
0051     QUrlQuery q(url);
0052 
0053     const QString title = query[QueryKey::Title];
0054     q.addQueryItem(QStringLiteral("ti"), title);
0055 
0056     const QString authors = query[QueryKey::Author];
0057     q.addQueryItem(QStringLiteral("au"), authors);
0058 
0059     const QString year = query[QueryKey::Year];
0060     if (!year.isEmpty())
0061         q.addQueryItem(QStringLiteral("year"), year);
0062 
0063     q.addQueryItem(QStringLiteral("format"), QStringLiteral("bibtex"));
0064 
0065     url.setQuery(q);
0066     QNetworkRequest request(url);
0067     QNetworkReply *reply = InternalNetworkAccessManager::instance().get(request);
0068     InternalNetworkAccessManager::instance().setNetworkReplyTimeout(reply);
0069     connect(reply, &QNetworkReply::finished, this, &OnlineSearchMRLookup::doneFetchingResultPage);
0070 
0071     refreshBusyProperty();
0072 }
0073 
0074 QString OnlineSearchMRLookup::label() const
0075 {
0076     return i18n("MR Lookup");
0077 }
0078 
0079 QUrl OnlineSearchMRLookup::homepage() const
0080 {
0081     return QUrl(QStringLiteral("https://mathscinet.ams.org/mrlookup"));
0082 }
0083 
0084 void OnlineSearchMRLookup::doneFetchingResultPage()
0085 {
0086     QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
0087 
0088     Q_EMIT progress(curStep = numSteps, numSteps);
0089 
0090     if (handleErrors(reply)) {
0091         /// ensure proper treatment of UTF-8 characters
0092         QString htmlCode = QString::fromUtf8(reply->readAll().constData());
0093 
0094         QString bibtexCode;
0095         int p1 = -1, p2 = -1;
0096         while ((p1 = htmlCode.indexOf(QStringLiteral("<pre>"), p2 + 1)) >= 0 && (p2 = htmlCode.indexOf(QStringLiteral("</pre>"), p1 + 1)) >= 0) {
0097             bibtexCode += QStringView{htmlCode}.mid(p1 + 5, p2 - p1 - 5);
0098             bibtexCode += QLatin1Char('\n');
0099         }
0100 
0101         FileImporterBibTeX importer(this);
0102         File *bibtexFile = importer.fromString(bibtexCode);
0103 
0104         bool hasEntry = false;
0105         if (bibtexFile != nullptr) {
0106             for (const auto &element : const_cast<const File &>(*bibtexFile)) {
0107                 const QSharedPointer<Entry> entry = element.dynamicCast<Entry>();
0108                 hasEntry |= publishEntry(entry);
0109             }
0110             delete bibtexFile;
0111         }
0112 
0113         stopSearch(hasEntry ? resultNoError : resultUnspecifiedError);
0114     }
0115 
0116     refreshBusyProperty();
0117 }
0118 
0119 void OnlineSearchMRLookup::sanitizeEntry(QSharedPointer<Entry> entry)
0120 {
0121     OnlineSearchAbstract::sanitizeEntry(entry);
0122 
0123     /// Rewrite 'fjournal' fields to become 'journal' fields
0124     /// (overwriting them if necessary)
0125     const QString ftFJournal = QStringLiteral("fjournal");
0126     if (entry->contains(ftFJournal)) {
0127         Value v = entry->value(ftFJournal);
0128         entry->remove(Entry::ftJournal);
0129         entry->remove(ftFJournal);
0130         entry->insert(Entry::ftJournal, v);
0131     }
0132 
0133     /// Remove URL from entry if contains a DOI and the DOI field is present
0134     if (entry->contains(Entry::ftDOI) && entry->contains(Entry::ftUrl)) {
0135         Value v = entry->value(Entry::ftUrl);
0136         if (v.containsPattern(QStringLiteral("https://dx.doi.org"))) {
0137             entry->remove(Entry::ftUrl);
0138         }
0139     }
0140 }