File indexing completed on 2024-05-12 05:09:28
0001 /*************************************************************************** 0002 Copyright (C) 2011 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 "bibliosharefetcher.h" 0026 #include "../utils/isbnvalidator.h" 0027 #include "../entry.h" 0028 #include "../images/imagefactory.h" 0029 #include "../images/imageinfo.h" 0030 #include "../core/tellico_strings.h" 0031 #include "../tellico_debug.h" 0032 0033 #include <KLocalizedString> 0034 #include <KConfigGroup> 0035 0036 #include <QLineEdit> 0037 #include <QLabel> 0038 #include <QVBoxLayout> 0039 #include <QUrlQuery> 0040 0041 namespace { 0042 static const char* BIBLIOSHARE_BASE_URL = "https://www.biblioshare.org/BNCServices/BNCServices.asmx/"; 0043 static const char* BIBLIOSHARE_TOKEN = "nsnqwebh87kstlty"; 0044 } 0045 0046 using namespace Tellico; 0047 using Tellico::Fetch::BiblioShareFetcher; 0048 0049 BiblioShareFetcher::BiblioShareFetcher(QObject* parent_) 0050 : XMLFetcher(parent_) 0051 , m_token(QLatin1String(BIBLIOSHARE_TOKEN)) { 0052 setLimit(1); 0053 setXSLTFilename(QStringLiteral("biblioshare2tellico.xsl")); 0054 } 0055 0056 BiblioShareFetcher::~BiblioShareFetcher() { 0057 } 0058 0059 QString BiblioShareFetcher::source() const { 0060 return m_name.isEmpty() ? defaultName() : m_name; 0061 } 0062 0063 // https://www.booknetcanada.ca/get-a-token 0064 QString BiblioShareFetcher::attribution() const { 0065 return i18n(providedBy, QLatin1String("https://www.booknetcanada.ca/biblioshare"), QLatin1String("BNC BiblioShare")); 0066 } 0067 0068 bool BiblioShareFetcher::canFetch(int type) const { 0069 return type == Data::Collection::Book || type == Data::Collection::Bibtex; 0070 } 0071 0072 void BiblioShareFetcher::readConfigHook(const KConfigGroup& config_) { 0073 QString k = config_.readEntry("Token", BIBLIOSHARE_TOKEN); 0074 if(!k.isEmpty()) { 0075 m_token = k; 0076 } 0077 } 0078 0079 QUrl BiblioShareFetcher::searchUrl() { 0080 QUrl u(QString::fromLatin1(BIBLIOSHARE_BASE_URL)); 0081 u.setPath(u.path() + QStringLiteral("BiblioSimple")); 0082 0083 QUrlQuery q; 0084 q.addQueryItem(QStringLiteral("Token"), m_token); 0085 0086 switch(request().key()) { 0087 case ISBN: 0088 { 0089 // only grab first value 0090 QString v = request().value().section(QLatin1Char(';'), 0); 0091 v = ISBNValidator::isbn13(v); 0092 v.remove(QLatin1Char('-')); 0093 q.addQueryItem(QStringLiteral("EAN"), v); 0094 } 0095 break; 0096 0097 default: 0098 return QUrl(); 0099 } 0100 u.setQuery(q); 0101 // myDebug() << "url:" << u.url(); 0102 return u; 0103 } 0104 0105 Tellico::Data::EntryPtr BiblioShareFetcher::fetchEntryHookData(Data::EntryPtr entry_) { 0106 Q_ASSERT(entry_); 0107 0108 if(!entry_) { 0109 myWarning() << "no entry"; 0110 return entry_; 0111 } 0112 0113 // if the entry cover is not set, go ahead and try to fetch it 0114 if(entry_->field(QStringLiteral("cover")).isEmpty()) { 0115 QString isbn = ISBNValidator::cleanValue(entry_->field(QStringLiteral("isbn"))); 0116 if(!isbn.isEmpty()) { 0117 isbn = ISBNValidator::isbn13(isbn); 0118 isbn.remove(QLatin1Char('-')); 0119 0120 QUrl imageUrl(QString::fromLatin1(BIBLIOSHARE_BASE_URL)); 0121 imageUrl.setPath(imageUrl.path() + QStringLiteral("Images")); 0122 QUrlQuery q; 0123 q.addQueryItem(QStringLiteral("Token"), m_token); 0124 q.addQueryItem(QStringLiteral("EAN"), isbn); 0125 // the actual values for SAN Thumbnail don't seem to matter, they just can't be empty 0126 q.addQueryItem(QStringLiteral("SAN"), QStringLiteral("string")); 0127 q.addQueryItem(QStringLiteral("Thumbnail"), QStringLiteral("cover")); 0128 imageUrl.setQuery(q); 0129 const QString id = ImageFactory::addImage(imageUrl, true); 0130 if(!id.isEmpty()) { 0131 // placeholder images are 120x120 or 1x1 0132 Data::ImageInfo info = ImageFactory::imageInfo(id); 0133 if((info.width() != 120 || info.height() != 120) && 0134 (info.width() != 1 || info.height() != 1)) { 0135 entry_->setField(QStringLiteral("cover"), id); 0136 } 0137 } 0138 } 0139 } 0140 0141 return entry_; 0142 } 0143 0144 Tellico::Fetch::FetchRequest BiblioShareFetcher::updateRequest(Data::EntryPtr entry_) { 0145 const QString isbn = entry_->field(QStringLiteral("isbn")); 0146 if(!isbn.isEmpty()) { 0147 return FetchRequest(Fetch::ISBN, isbn); 0148 } 0149 0150 return FetchRequest(); 0151 } 0152 0153 Tellico::Fetch::ConfigWidget* BiblioShareFetcher::configWidget(QWidget* parent_) const { 0154 return new BiblioShareFetcher::ConfigWidget(parent_, this); 0155 } 0156 0157 QString BiblioShareFetcher::defaultName() { 0158 return QStringLiteral("BiblioShare"); 0159 } 0160 0161 QString BiblioShareFetcher::defaultIcon() { 0162 return favIcon(QUrl(QLatin1String("https://www.booknetcanada.ca")), 0163 QUrl(QLatin1String("https://images.squarespace-cdn.com/content/v1/550334cbe4b0e08b6885e88f/1443713102643-G58N3NF6V7EWOGZ0I4A8/favicon.ico?format=100w"))); 0164 } 0165 0166 BiblioShareFetcher::ConfigWidget::ConfigWidget(QWidget* parent_, const BiblioShareFetcher* fetcher_) 0167 : Fetch::ConfigWidget(parent_) { 0168 QGridLayout* l = new QGridLayout(optionsWidget()); 0169 l->setSpacing(4); 0170 l->setColumnStretch(1, 10); 0171 0172 int row = -1; 0173 QLabel* al = new QLabel(i18n("Registration is required for accessing this data source. " 0174 "If you agree to the terms and conditions, <a href='%1'>sign " 0175 "up for an account</a>, and enter your information below.", 0176 QStringLiteral("https://www.booknetcanada.ca/get-a-token")), 0177 optionsWidget()); 0178 al->setOpenExternalLinks(true); 0179 al->setWordWrap(true); 0180 ++row; 0181 l->addWidget(al, row, 0, 1, 2); 0182 // richtext gets weird with size 0183 al->setMinimumWidth(al->sizeHint().width()); 0184 0185 QLabel* label = new QLabel(i18n("Access key: "), optionsWidget()); 0186 l->addWidget(label, ++row, 0); 0187 0188 m_tokenEdit = new QLineEdit(optionsWidget()); 0189 connect(m_tokenEdit, &QLineEdit::textChanged, this, &ConfigWidget::slotSetModified); 0190 l->addWidget(m_tokenEdit, row, 1); 0191 QString w = i18n("The default Tellico key may be used, but searching may fail due to reaching access limits."); 0192 label->setWhatsThis(w); 0193 m_tokenEdit->setWhatsThis(w); 0194 label->setBuddy(m_tokenEdit); 0195 0196 l->setRowStretch(++row, 10); 0197 0198 if(fetcher_) { 0199 // only show the key if it is not the default Tellico one... 0200 // that way the user is prompted to apply for their own 0201 if(fetcher_->m_token != QLatin1String(BIBLIOSHARE_TOKEN)) { 0202 m_tokenEdit->setText(fetcher_->m_token); 0203 } 0204 } 0205 } 0206 0207 void BiblioShareFetcher::ConfigWidget::saveConfigHook(KConfigGroup& config_) { 0208 QString token = m_tokenEdit->text().trimmed(); 0209 if(!token.isEmpty()) { 0210 config_.writeEntry("Token", token); 0211 } 0212 } 0213 0214 QString BiblioShareFetcher::ConfigWidget::preferredName() const { 0215 return BiblioShareFetcher::defaultName(); 0216 }