7#include "datetimeparser_p.h"
8#include "fb2extractor.h"
9#include "kfilemetadata_debug.h"
13#include <QXmlStreamReader>
21Fb2Extractor::Fb2Extractor(
QObject *parent)
28static const QString regularMimeType()
30 return QStringLiteral(
"application/x-fictionbook+xml");
33static const QString compressedMimeType()
35 return QStringLiteral(
"application/x-zip-compressed-fb2");
38static const QStringList supportedMimeTypes = {regularMimeType(), compressedMimeType()};
44 return supportedMimeTypes;
49 std::unique_ptr<QIODevice> device;
50 std::unique_ptr<KZip> zip;
53 device.reset(
new QFile(result->
inputUrl()));
59 zip.reset(
new KZip(result->
inputUrl()));
64 const auto entries = zip->directory()->entries();
65 if (entries.count() != 1) {
69 const QString entryPath = entries.first();
70 if (!entryPath.
endsWith(QLatin1String(
".fb2"))) {
74 const auto *entry = zip->directory()->file(entryPath);
79 device.reset(entry->createDevice());
84 QXmlStreamReader xml(device.get());
86 bool inFictionBook =
false;
87 bool inDescription =
false;
88 bool inTitleInfo =
false;
89 bool inAuthor =
false;
90 bool inDocumentInfo =
false;
91 bool inPublishInfo =
false;
94 QString authorFirstName;
95 QString authorMiddleName;
96 QString authorLastName;
97 QString authorNickName;
99 while (!xml.atEnd() && !xml.hasError()) {
102 if (xml.name() == QLatin1String(
"FictionBook")) {
103 if (xml.isStartElement()) {
104 inFictionBook =
true;
105 }
else if (xml.isEndElement()) {
108 }
else if (xml.name() == QLatin1String(
"description")) {
109 if (xml.isStartElement()) {
110 inDescription =
true;
111 }
else if (xml.isEndElement()) {
112 inDescription =
false;
114 }
else if (xml.name() == QLatin1String(
"title-info")) {
115 if (xml.isStartElement()) {
117 }
else if (xml.isEndElement()) {
120 }
else if (xml.name() == QLatin1String(
"document-info")) {
121 if (xml.isStartElement()) {
122 inDocumentInfo =
true;
123 }
else if (xml.isEndElement()) {
124 inDocumentInfo =
false;
126 }
else if (xml.name() == QLatin1String(
"publish-info")) {
127 if (xml.isStartElement()) {
128 inPublishInfo =
true;
129 }
else if (xml.isEndElement()) {
130 inPublishInfo =
false;
132 }
else if (xml.name() == QLatin1String(
"body")) {
133 if (xml.isStartElement()) {
135 }
else if (xml.isEndElement()) {
140 if (!inFictionBook) {
144 if (inDescription && result->
inputFlags() & ExtractionResult::ExtractMetaData) {
146 if (xml.isStartElement()) {
147 if (xml.name() == QLatin1String(
"author")) {
149 }
else if (inAuthor) {
150 if (xml.name() == QLatin1String(
"first-name")) {
151 authorFirstName = xml.readElementText();
152 }
else if (xml.name() == QLatin1String(
"middle-name")) {
153 authorMiddleName = xml.readElementText();
154 }
else if (xml.name() == QLatin1String(
"last-name")) {
155 authorLastName = xml.readElementText();
156 }
else if (xml.name() == QLatin1String(
"nickname")) {
157 authorNickName = xml.readElementText();
159 }
else if (xml.name() == QLatin1String(
"book-title")) {
161 }
else if (xml.name() == QLatin1String(
"annotation")) {
163 }
else if (xml.name() == QLatin1String(
"lang")) {
165 }
else if (xml.name() == QLatin1String(
"genre")) {
168 }
else if (xml.isEndElement()) {
171 QStringList nameParts = {authorFirstName, authorMiddleName, authorLastName};
176 }
else if (!authorNickName.
isEmpty()) {
180 authorFirstName.
clear();
181 authorMiddleName.
clear();
182 authorLastName.
clear();
183 authorNickName.
clear();
185 }
else if (inDocumentInfo) {
186 if (xml.name() == QLatin1String(
"date")) {
188 const auto dateValue = xml.attributes().value(QLatin1String(
"value"));
192 dt = Parser::dateTimeFromString(xml.readElementText());
198 }
else if (xml.name() == QLatin1String(
"program-used")) {
201 }
else if (xml.name() == QLatin1String(
"publisher")) {
204 }
else if (inPublishInfo) {
205 if (xml.name() == QLatin1String(
"publisher")) {
207 }
else if (xml.name() == QLatin1String(
"year")) {
209 const int releaseYear = xml.readElementText().toInt(&ok);
215 }
else if (inBody && result->
inputFlags() & ExtractionResult::ExtractPlainText && xml.isCharacters() && !xml.isWhitespace()) {
216 result->
append(xml.text().toString());
221#include "moc_fb2extractor.cpp"
QDateTime fromString(QStringView string, QStringView format, QCalendar cal)
bool isValid() const const
bool isEmpty() const const
qsizetype removeAll(const AT &t)
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString join(QChar separator) const const