From 0910937e39ae76804585a6f183b15b71b617a440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Mon, 27 Sep 2021 15:28:47 +0200 Subject: [PATCH] Add function for parsing xml info into ComicInfo --- YACReaderLibrary/xml_info_parser.cpp | 184 +++++++++++++++++++++++++++ YACReaderLibrary/xml_info_parser.h | 12 ++ 2 files changed, 196 insertions(+) create mode 100644 YACReaderLibrary/xml_info_parser.cpp create mode 100644 YACReaderLibrary/xml_info_parser.h diff --git a/YACReaderLibrary/xml_info_parser.cpp b/YACReaderLibrary/xml_info_parser.cpp new file mode 100644 index 00000000..aa51ad73 --- /dev/null +++ b/YACReaderLibrary/xml_info_parser.cpp @@ -0,0 +1,184 @@ +#include "xml_info_parser.h" + +#include + +bool isValidText(const QString &string) +{ + return !string.isEmpty() && !string.isNull(); +} + +QString transLateMultiValuedString(QString &string, const QString &originSeparator = ", ", const QString &targetSeparator = "\n") +{ + return string.replace(originSeparator, targetSeparator); +} + +bool parseField(QXmlStreamReader &reader, const QString &xmlName, QVariant &dest, bool multivalued = false) +{ + auto name = reader.name(); + if (name == xmlName) { + auto string = reader.readElementText(); + if (isValidText(string)) { + if (multivalued) { + dest = transLateMultiValuedString(string); + } else { + dest = string; + } + } + + return true; + } + + return false; +} + +bool parseFieldNumber(QXmlStreamReader &reader, const QString &xmlName, QVariant &dest) +{ + if (reader.name() == xmlName) { + auto string = reader.readElementText(); + if (isValidText(string)) { + bool success; + auto number = string.toInt(&success); + if (success) { + dest = number; + } + } + + return true; + } + + return false; +} + +void consolidateDate(ComicInfo &info) +{ + if (!info.year.isValid() && !info.month.isValid() && !info.day.isValid()) { + return; + } + + auto year = info.year.isNull() ? 0 : info.year.toInt(); + auto month = info.month.isNull() ? 1 : info.month.toInt(); + auto day = info.date.isNull() ? 1 : info.date.toInt(); + + info.date = QString("%1/%2/%3").arg(day).arg(month).arg(year); +} + +bool tryValues(QXmlStreamReader &reader, ComicInfo &info) +{ + std::map stringValues = { + { "Title", info.title }, + { "Volume", info.volume }, + { "StoryArc", info.storyArc }, + { "Genre", info.genere }, + { "Publisher", info.publisher }, + { "Format", info.format }, + { "AgeRating", info.ageRating }, + { "Summary", info.synopsis }, + { "Notes", info.notes }, + }; + + std::map forcedNumbers = { + { "Number", info.number }, + { "Count", info.count }, + { "AlternateNumber", info.arcNumber }, + { "AlternateCount", info.arcCount }, + { "Day", info.day }, + { "Month", info.month }, + { "Year", info.year } + }; + + std::map multiValuedStrings = { + { "Writer", info.writer }, + { "Penciller", info.penciller }, + { "Inker", info.inker }, + { "Colorist", info.colorist }, + { "Letterer", info.letterer }, + { "CoverArtist", info.coverArtist }, + { "Characters", info.characters } + }; + + for (auto &pair : stringValues) { + if (parseField(reader, pair.first, pair.second)) { + return true; + } + } + + for (auto &pair : forcedNumbers) { + if (parseFieldNumber(reader, pair.first, pair.second)) { + return true; + } + } + + for (auto &pair : multiValuedStrings) { + if (parseField(reader, pair.first, pair.second, true)) { + return true; + } + } + + if (reader.name() == "BlackAndWhite") { + auto string = reader.readElementText(); + if (isValidText(string)) { + if (string == "Yes") { + info.color = false; + } else if (string == "No") { + info.color = true; + } + } + + return true; + } + + if (reader.name() == "Manga") { + auto string = reader.readElementText(); + if (isValidText(string)) { + if (string == "Yes" || string == "YesAndRightToLeft") { + info.manga = true; + } else if (string == "No") { + info.manga = false; + } + } + + return true; + } + + if (reader.name() == "Web") { + auto string = reader.readElementText(); + if (isValidText(string)) { + auto comicVineId = string.split("-").last().replace("/", ""); + + info.comicVineID = comicVineId; + } + + return true; + } + + return false; +} + +bool YACReader::parseXMLIntoInfo(const QByteArray &xmlRawData, ComicInfo &info) +{ + if (xmlRawData.isEmpty()) { + return false; + } + + QXmlStreamReader reader(xmlRawData); + + bool someDataWasParsed = false; + + while (reader.readNextStartElement()) { + if (tryValues(reader, info)) { + someDataWasParsed = true; + } else { + if (reader.name() != "ComicInfo") { + reader.skipCurrentElement(); + } + } + } + + consolidateDate(info); + + if (reader.error()) { + return false; + } + + return someDataWasParsed; +} diff --git a/YACReaderLibrary/xml_info_parser.h b/YACReaderLibrary/xml_info_parser.h new file mode 100644 index 00000000..295aba75 --- /dev/null +++ b/YACReaderLibrary/xml_info_parser.h @@ -0,0 +1,12 @@ +#ifndef XMLINFOPARSER_H +#define XMLINFOPARSER_H + +#include "comic_db.h" + +namespace YACReader { + +bool parseXMLIntoInfo(const QByteArray &xmlRawData, ComicInfo &info); + +} + +#endif // XMLINFOPARSER_H