diff --git a/src/cpp-opds.qbs b/src/cpp-opds.qbs index 572fa67..ecf85a1 100644 --- a/src/cpp-opds.qbs +++ b/src/cpp-opds.qbs @@ -23,14 +23,13 @@ PSApplication { Depends { name: "rdbase" } Depends { name: "model" } Depends { name: "quazip" } + Depends { name: "utils" } cpp.cxxLanguageVersion: "c++20" Group { name: "cpp" files: [ - "fb2extractor.cpp", - "fb2extractor.h", "main.cpp", ] } diff --git a/src/database/database.qbs b/src/database/database.qbs index 48a25ac..3cdc49d 100644 --- a/src/database/database.qbs +++ b/src/database/database.qbs @@ -11,7 +11,6 @@ PSLibrary { "DATABASE_SQLITE", "DATABASE_LIBRARY" ] - consoleApplication: true Depends { name: "Qt"; submodules: [ "core", "network" ] } Depends { name: "cpp" } diff --git a/src/fb2extractor.h b/src/fb2extractor.h deleted file mode 100644 index 20c0ffd..0000000 --- a/src/fb2extractor.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef FB2EXTRACTOR_H -#define FB2EXTRACTOR_H - -#include -#include -#include - -#include -#include - -// class FB2Extractor -// { -// public: -// FB2Extractor(); -// }; - -struct Fb2Metadata -{ - QString title; - QStringList authors; - QStringList genres; -}; - -Fb2Metadata parseFb2Metadata(QXmlStreamReader& sr); - -#endif // FB2EXTRACTOR_H diff --git a/src/main.cpp b/src/main.cpp index 8ded449..088a307 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,7 +15,8 @@ #include -#include "fb2extractor.h" +#include +#include QMap readFb2MetadataFromZip(const QString& zipPath) { @@ -36,43 +37,43 @@ QMap readFb2MetadataFromZip(const QString& zipPath) qWarning() << "*********" << count << "*********"; // Получение информации о файле - QuaZipFileInfo fileInfo; - if (zip.getCurrentFileInfo(&fileInfo)) - { - qDebug() << "File:" << fileInfo.name - << "Size:" << fileInfo.uncompressedSize << "bytes" - << "Compressed:" << fileInfo.compressedSize << "bytes" - << "Modified:" << fileInfo.dateTime.toString(Qt::ISODate); - } + // QuaZipFileInfo fileInfo; + // if (zip.getCurrentFileInfo(&fileInfo)) + // { + // qDebug() << "File:" << fileInfo.name + // << "Size:" << fileInfo.uncompressedSize << "bytes" + // << "Compressed:" << fileInfo.compressedSize << "bytes" + // << "Modified:" << fileInfo.dateTime.toString(Qt::ISODate); + // } QString fb2FileName = zip.getCurrentFileName(); + qWarning() << fb2FileName; + // if (fb2FileName.isEmpty()) + // { + // qWarning() << "No FB2 file found in archive"; + // zip.close(); + // return metadata; + // } - if (fb2FileName.isEmpty()) - { - qWarning() << "No FB2 file found in archive"; - zip.close(); - return metadata; - } - - // Читаем FB2 файл из архива - // qWarning() << "Читаем FB2 файл из архива" << fb2FileName; + // // Читаем FB2 файл из архива + // // qWarning() << "Читаем FB2 файл из архива" << fb2FileName; QuaZipFile fb2File(&zip); - bool isOpen = fb2File.open(QIODevice::ReadOnly); - int zipError = fb2File.getZipError(); - if (!isOpen || zipError != UNZ_OK) - { - qWarning() << "Failed to open FB2 file in archive"; - zip.close(); - return metadata; - } + // bool isOpen = fb2File.open(QIODevice::ReadOnly); + // int zipError = fb2File.getZipError(); + // if (!isOpen || zipError != UNZ_OK) + // { + // qWarning() << "Failed to open FB2 file in archive"; + // zip.close(); + // return metadata; + // } - // Парсим XML метаданные - QXmlStreamReader fXmlBook(&fb2File); - const auto data = parseFb2Metadata(fXmlBook); + // // Парсим XML метаданные + // QXmlStreamReader fXmlBook(&fb2File); + // const auto data = parseFb2Metadata(fXmlBook); - qWarning() << data.title << data.authors << data.genres; + // qWarning() << data.title << data.authors << data.genres; - qWarning() << "*********" << count << "*********"; + // qWarning() << "*********" << count << "*********"; } return metadata; @@ -187,31 +188,19 @@ int main(int argc, char* argv[]) QString zipArzh = "/home/alex/repos/exp/cpp-opds/f.fb2-631519-634744.zip"; const auto books = readFb2MetadataFromZip(zipArzh); - qWarning() << " books.count()" << books.count(); + // qWarning() << " books.count()" << books.count(); - // QuaZip zip(zipArzh); - // if (!zip.open(QuaZip::mdUnzip)) - // { - // qWarning() << "Failed to open archive"; - // } - // else - // { - // qWarning() << "Total files:" << zip.getEntriesCount(); - - // for (bool more = zip.goToFirstFile(); more; more = zip.goToNextFile()) - // { - // QuaZipFileInfo fileInfo; - // if (zip.getCurrentFileInfo(&fileInfo)) - // { - // qDebug() << "File:" << fileInfo.name - // << "Size:" << fileInfo.uncompressedSize << "bytes" - // << "Compressed:" << fileInfo.compressedSize << "bytes" - // << "Modified:" << fileInfo.dateTime.toString(Qt::ISODate); - // } - // } - // } - - // zip.close(); + auto z = ZipWrapper(zipArzh); + for (const auto& filename : z.getFiles()) + { + if (filename.endsWith(".fb2")) + { + auto zf = z.getFile(filename).data(); + auto fb2File = FB2Extractor(*zf); + const auto book = fb2File.parse(); + // qWarning() << book.title; + } + } // Set up code that uses the Qt event loop here. // Call a.quit() or a.exit() to quit the application. diff --git a/src/fb2extractor.cpp b/src/utils/fb2extractor.cpp similarity index 67% rename from src/fb2extractor.cpp rename to src/utils/fb2extractor.cpp index 87b0156..da59847 100644 --- a/src/fb2extractor.cpp +++ b/src/utils/fb2extractor.cpp @@ -1,21 +1,35 @@ #include "fb2extractor.h" -// FB2Extractor::FB2Extractor() {} +// FB2Extractor::FB2Extractor() +// { +// } -Fb2Metadata parseFb2Metadata(QXmlStreamReader &sr) +FB2Extractor::FB2Extractor(QuaZipFile& file) : + m_file(&file) { +} + +FB2Extractor::~FB2Extractor() +{ + m_file.close(); +} + +Fb2Metadata FB2Extractor::parse() +{ + QXmlStreamReader xmlData(&m_file); + Fb2Metadata meta; QString currentElement; bool inTitleInfo = false; bool inAuthor = false; QString currentAuthor; - while (!sr.atEnd()) + while (!xmlData.atEnd()) { - switch (sr.readNext()) + switch (xmlData.readNext()) { case QXmlStreamReader::StartElement: - currentElement = sr.name().toString(); + currentElement = xmlData.name().toString(); if (currentElement == "title-info") { @@ -25,11 +39,11 @@ Fb2Metadata parseFb2Metadata(QXmlStreamReader &sr) { if (currentElement == "book-title") { - meta.title = sr.readElementText(); + meta.title = xmlData.readElementText(); } else if (currentElement == "genre") { - meta.genres << sr.readElementText(); + meta.genres << xmlData.readElementText(); } else if (currentElement == "author") { @@ -38,17 +52,17 @@ Fb2Metadata parseFb2Metadata(QXmlStreamReader &sr) } else if (inAuthor && (currentElement == "first-name" || currentElement == "last-name" || currentElement == "middle-name")) { - currentAuthor += sr.readElementText() + " "; + currentAuthor += xmlData.readElementText() + " "; } } break; case QXmlStreamReader::EndElement: - if (sr.name().toString() == "title-info") + if (xmlData.name().toString() == "title-info") { inTitleInfo = false; } - else if (sr.name().toString() == "author" && inAuthor) + else if (xmlData.name().toString() == "author" && inAuthor) { meta.authors << currentAuthor.trimmed(); inAuthor = false; @@ -70,9 +84,9 @@ Fb2Metadata parseFb2Metadata(QXmlStreamReader &sr) } } - if (sr.hasError()) + if (xmlData.hasError()) { - qWarning() << "XML parsing error:" << sr.errorString(); + qWarning() << "XML parsing error:" << xmlData.errorString(); } return meta; diff --git a/src/utils/fb2extractor.h b/src/utils/fb2extractor.h new file mode 100644 index 0000000..9b33a83 --- /dev/null +++ b/src/utils/fb2extractor.h @@ -0,0 +1,36 @@ +#ifndef FB2EXTRACTOR_H +#define FB2EXTRACTOR_H + +#include "utils_global.h" + +#include +#include +#include + +#include + +struct Fb2Metadata +{ + QString title; // Название книги + QStringList authors; // Авторы + QStringList genres; // Жанры +}; + +Fb2Metadata UTILS_EXPORT parseFb2Metadata(QXmlStreamReader& sr); + +class UTILS_EXPORT FB2Extractor +{ +public: + FB2Extractor(QuaZipFile& file); + ~FB2Extractor(); + + /*! + * \brief Распарсить инфу из содержимого + */ + Fb2Metadata parse(); + +private: + QuaZipFile m_file; +}; + +#endif // FB2EXTRACTOR_H diff --git a/src/utils/utils.qbs b/src/utils/utils.qbs new file mode 100644 index 0000000..fced4a7 --- /dev/null +++ b/src/utils/utils.qbs @@ -0,0 +1,22 @@ +/*! + \qmltype cpp-opds + \inherits Project + \brief Описание +*/ +PSLibrary { + name: "utils" + cpp.defines: [ + "UTILS_LIBRARY" + ] + + Depends { name: "Qt"; submodules: [ "core" ] } + Depends { name: "quazip" } + + Group { + name: "cpp" + files: [ + "**/*.h", + "**/*.cpp", + ] + } +} diff --git a/src/utils/utils_global.h b/src/utils/utils_global.h new file mode 100644 index 0000000..7daa3fb --- /dev/null +++ b/src/utils/utils_global.h @@ -0,0 +1,12 @@ +#ifndef UTILS_GLOBAL_H +#define UTILS_GLOBAL_H + +#include + +#if defined(UTILS_LIBRARY) +#define UTILS_EXPORT Q_DECL_EXPORT +#else +#define UTILS_EXPORT Q_DECL_IMPORT +#endif + +#endif // UTILS_GLOBAL_H diff --git a/src/utils/zipwrapper.cpp b/src/utils/zipwrapper.cpp new file mode 100644 index 0000000..0822709 --- /dev/null +++ b/src/utils/zipwrapper.cpp @@ -0,0 +1,60 @@ +#include "zipwrapper.h" + +#include +#include + +// zipwrapper.cpp +#include "zipwrapper.h" + +#include + +ZipWrapper::ZipWrapper(const QString& zipFilePath) : + m_zip(new QuaZip(zipFilePath)) +{ + if (!m_zip->open(QuaZip::mdUnzip)) + { + qWarning() << "Failed to open archive:" << zipFilePath + << "Error:" << m_zip->getZipError(); + } +} + +ZipWrapper::~ZipWrapper() +{ + if (isOpen()) + { + m_zip->close(); + } +} + +QStringList ZipWrapper::getFiles() +{ + if (!isOpen()) + return {}; + return m_zip->getFileNameList(); +} + +QSharedPointer ZipWrapper::getFile(const QString& filename) +{ + QSharedPointer file(new QuaZipFile(m_zip.data())); + + if (!file->open(QIODevice::ReadOnly)) + { + qWarning() << "Failed to open file:" << filename + << "Error:" << file->getZipError(); + return nullptr; + } + + for (bool more = m_zip->goToFirstFile(); more; more = m_zip->goToNextFile()) + if (m_zip->getCurrentFileName() == filename) + { + auto shqzf = QSharedPointer(new QuaZipFile(m_zip.data())); + return shqzf; + }; + + return file; +} + +bool ZipWrapper::isOpen() const +{ + return m_zip && m_zip->isOpen(); +} diff --git a/src/utils/zipwrapper.h b/src/utils/zipwrapper.h new file mode 100644 index 0000000..72c5dca --- /dev/null +++ b/src/utils/zipwrapper.h @@ -0,0 +1,29 @@ +// zipwrapper.h +#ifndef ZIPWRAPPER_H +#define ZIPWRAPPER_H + +#include "utils_global.h" + +#include +#include +#include +#include + +class QuaZip; +class QuaZipFile; + +class UTILS_EXPORT ZipWrapper +{ +public: + explicit ZipWrapper(const QString& zipFilePath); + ~ZipWrapper(); + + QStringList getFiles(); + QSharedPointer getFile(const QString& filename); + bool isOpen() const; + +private: + QSharedPointer m_zip; +}; + +#endif // ZIPWRAPPER_H