File indexing completed on 2024-05-12 05:10:10
0001 /*************************************************************************** 0002 Copyright (C) 2024 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 <config.h> 0026 0027 #include "filereaderbook.h" 0028 #include "../fieldformat.h" 0029 #include "../images/imagefactory.h" 0030 #include "../core/netaccess.h" 0031 0032 #include <KLocalizedString> 0033 #include <KFileItem> 0034 0035 #include <QPixmap> 0036 #include <QIcon> 0037 0038 namespace { 0039 static const int FILE_PREVIEW_SIZE = 128; 0040 } 0041 0042 using Tellico::FileReaderBook; 0043 0044 class FileReaderBook::Private { 0045 public: 0046 Private() {} 0047 0048 // cache the icon image ids to avoid repeated creation of Data::Image objects 0049 QHash<QString, QString> iconImageId; 0050 }; 0051 0052 FileReaderBook::FileReaderBook(const QUrl& url_) : FileReaderMetaData(url_), d(new Private) { 0053 } 0054 0055 FileReaderBook::~FileReaderBook() = default; 0056 0057 bool FileReaderBook::populate(Data::EntryPtr entry, const KFileItem& item) { 0058 // reads pdf and ebooks 0059 if(item.mimetype() != QLatin1String("application/pdf") && 0060 item.mimetype() != QLatin1String("application/epub+zip") && 0061 item.mimetype() != QLatin1String("application/fb2+zip") && 0062 item.mimetype() != QLatin1String("application/fb2+xml") && 0063 item.mimetype() != QLatin1String("application/x-mobipocket-ebook")) { 0064 return false; 0065 } 0066 #ifndef HAVE_KFILEMETADATA 0067 return false; 0068 #else 0069 bool isEmpty = true; 0070 QStringList authors, publishers, genres, keywords; 0071 const auto props = properties(item); 0072 for(auto it = props.constBegin(); it != props.constEnd(); ++it) { 0073 const QString value = it.value().toString(); 0074 if(value.isEmpty()) continue; 0075 switch(it.key()) { 0076 case KFileMetaData::Property::Title: 0077 isEmpty = false; // require a title or author 0078 entry->setField(QStringLiteral("title"), value); 0079 break; 0080 0081 case KFileMetaData::Property::Author: 0082 isEmpty = false; // require a title or author 0083 authors += value; 0084 break; 0085 0086 case KFileMetaData::Property::Publisher: 0087 publishers += value; 0088 break; 0089 0090 case KFileMetaData::Property::Subject: 0091 keywords += value; 0092 break; 0093 0094 case KFileMetaData::Property::Genre: 0095 genres += value; 0096 break; 0097 0098 case KFileMetaData::Property::ReleaseYear: 0099 entry->setField(QStringLiteral("pub_year"), value); 0100 break; 0101 0102 // is description usually the plot or just comments? 0103 case KFileMetaData::Property::Description: 0104 entry->setField(QStringLiteral("plot"), value); 0105 break; 0106 0107 case KFileMetaData::Property::PageCount: 0108 entry->setField(QStringLiteral("pages"), value); 0109 break; 0110 0111 default: 0112 if(!value.isEmpty()) { 0113 // myDebug() << "skipping" << it.key() << it.value(); 0114 } 0115 break; 0116 } 0117 } 0118 0119 if(isEmpty) return false; 0120 0121 if(!authors.isEmpty()) { 0122 entry->setField(QStringLiteral("author"), authors.join(FieldFormat::delimiterString())); 0123 } 0124 if(!publishers.isEmpty()) { 0125 entry->setField(QStringLiteral("publisher"), publishers.join(FieldFormat::delimiterString())); 0126 } 0127 if(!genres.isEmpty()) { 0128 entry->setField(QStringLiteral("genre"), genres.join(FieldFormat::delimiterString())); 0129 } 0130 if(!keywords.isEmpty()) { 0131 entry->setField(QStringLiteral("keyword"), keywords.join(FieldFormat::delimiterString())); 0132 } 0133 0134 const QString url = QStringLiteral("url"); 0135 if(!entry->collection()->hasField(url)) { 0136 Data::FieldPtr f(new Data::Field(url, i18n("URL"), Data::Field::URL)); 0137 f->setCategory(i18n("Personal")); 0138 entry->collection()->addField(f); 0139 } 0140 entry->setField(url, item.url().url()); 0141 entry->setField(QStringLiteral("binding"), i18n("E-Book")); 0142 0143 const QString cover = QStringLiteral("cover"); 0144 QPixmap pixmap; 0145 if(useFilePreview()) { 0146 pixmap = Tellico::NetAccess::filePreview(item, FILE_PREVIEW_SIZE); 0147 } 0148 if(pixmap.isNull()) { 0149 if(d->iconImageId.contains(item.iconName())) { 0150 entry->setField(cover, d->iconImageId.value(item.iconName())); 0151 } else { 0152 pixmap = QIcon::fromTheme(item.iconName()).pixmap(QSize(FILE_PREVIEW_SIZE, FILE_PREVIEW_SIZE)); 0153 const QString id = ImageFactory::addImage(pixmap, QStringLiteral("PNG")); 0154 if(!id.isEmpty()) { 0155 entry->setField(cover, id); 0156 d->iconImageId.insert(item.iconName(), id); 0157 } 0158 } 0159 } else { 0160 const QString id = ImageFactory::addImage(pixmap, QStringLiteral("PNG")); 0161 if(!id.isEmpty()) { 0162 entry->setField(cover, id); 0163 } 0164 } 0165 0166 #endif 0167 return true; 0168 }