WIP: Новые таблицы и изменение старых структур #6

Draft
alex wants to merge 12 commits from Новые-таблицы into master
10 changed files with 230 additions and 96 deletions
Showing only changes of commit d01c789b06 - Show all commits

View File

@@ -23,14 +23,13 @@ PSApplication {
Depends { name: "rdbase" } Depends { name: "rdbase" }
Depends { name: "model" } Depends { name: "model" }
Depends { name: "quazip" } Depends { name: "quazip" }
Depends { name: "utils" }
cpp.cxxLanguageVersion: "c++20" cpp.cxxLanguageVersion: "c++20"
Group { Group {
name: "cpp" name: "cpp"
files: [ files: [
"fb2extractor.cpp",
"fb2extractor.h",
"main.cpp", "main.cpp",
] ]
} }

View File

@@ -11,7 +11,6 @@ PSLibrary {
"DATABASE_SQLITE", "DATABASE_SQLITE",
"DATABASE_LIBRARY" "DATABASE_LIBRARY"
] ]
consoleApplication: true
Depends { name: "Qt"; submodules: [ "core", "network" ] } Depends { name: "Qt"; submodules: [ "core", "network" ] }
Depends { name: "cpp" } Depends { name: "cpp" }

View File

@@ -1,26 +0,0 @@
#ifndef FB2EXTRACTOR_H
#define FB2EXTRACTOR_H
#include <QDebug>
#include <QXmlStreamReader>
#include <QString>
#include <external_libs/quazip/quazip/quazip.h>
#include <external_libs/quazip/quazip/quazipfile.h>
// class FB2Extractor
// {
// public:
// FB2Extractor();
// };
struct Fb2Metadata
{
QString title;
QStringList authors;
QStringList genres;
};
Fb2Metadata parseFb2Metadata(QXmlStreamReader& sr);
#endif // FB2EXTRACTOR_H

View File

@@ -15,7 +15,8 @@
#include <iostream> #include <iostream>
#include "fb2extractor.h" #include <utils/fb2extractor.h>
#include <utils/zipwrapper.h>
QMap<QString, QString> readFb2MetadataFromZip(const QString& zipPath) QMap<QString, QString> readFb2MetadataFromZip(const QString& zipPath)
{ {
@@ -36,43 +37,43 @@ QMap<QString, QString> readFb2MetadataFromZip(const QString& zipPath)
qWarning() << "*********" << count << "*********"; qWarning() << "*********" << count << "*********";
// Получение информации о файле // Получение информации о файле
QuaZipFileInfo fileInfo; // QuaZipFileInfo fileInfo;
if (zip.getCurrentFileInfo(&fileInfo)) // if (zip.getCurrentFileInfo(&fileInfo))
{ // {
qDebug() << "File:" << fileInfo.name // qDebug() << "File:" << fileInfo.name
<< "Size:" << fileInfo.uncompressedSize << "bytes" // << "Size:" << fileInfo.uncompressedSize << "bytes"
<< "Compressed:" << fileInfo.compressedSize << "bytes" // << "Compressed:" << fileInfo.compressedSize << "bytes"
<< "Modified:" << fileInfo.dateTime.toString(Qt::ISODate); // << "Modified:" << fileInfo.dateTime.toString(Qt::ISODate);
} // }
QString fb2FileName = zip.getCurrentFileName(); QString fb2FileName = zip.getCurrentFileName();
qWarning() << fb2FileName;
// if (fb2FileName.isEmpty())
// {
// qWarning() << "No FB2 file found in archive";
// zip.close();
// return metadata;
// }
if (fb2FileName.isEmpty()) // // Читаем FB2 файл из архива
{ // // qWarning() << "Читаем FB2 файл из архива" << fb2FileName;
qWarning() << "No FB2 file found in archive";
zip.close();
return metadata;
}
// Читаем FB2 файл из архива
// qWarning() << "Читаем FB2 файл из архива" << fb2FileName;
QuaZipFile fb2File(&zip); QuaZipFile fb2File(&zip);
bool isOpen = fb2File.open(QIODevice::ReadOnly); // bool isOpen = fb2File.open(QIODevice::ReadOnly);
int zipError = fb2File.getZipError(); // int zipError = fb2File.getZipError();
if (!isOpen || zipError != UNZ_OK) // if (!isOpen || zipError != UNZ_OK)
{ // {
qWarning() << "Failed to open FB2 file in archive"; // qWarning() << "Failed to open FB2 file in archive";
zip.close(); // zip.close();
return metadata; // return metadata;
} // }
// Парсим XML метаданные // // Парсим XML метаданные
QXmlStreamReader fXmlBook(&fb2File); // QXmlStreamReader fXmlBook(&fb2File);
const auto data = parseFb2Metadata(fXmlBook); // 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; 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"; QString zipArzh = "/home/alex/repos/exp/cpp-opds/f.fb2-631519-634744.zip";
const auto books = readFb2MetadataFromZip(zipArzh); const auto books = readFb2MetadataFromZip(zipArzh);
qWarning() << " books.count()" << books.count(); // qWarning() << " books.count()" << books.count();
// QuaZip zip(zipArzh); auto z = ZipWrapper(zipArzh);
// if (!zip.open(QuaZip::mdUnzip)) for (const auto& filename : z.getFiles())
// { {
// qWarning() << "Failed to open archive"; if (filename.endsWith(".fb2"))
// } {
// else auto zf = z.getFile(filename).data();
// { auto fb2File = FB2Extractor(*zf);
// qWarning() << "Total files:" << zip.getEntriesCount(); const auto book = fb2File.parse();
// qWarning() << book.title;
// 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();
// Set up code that uses the Qt event loop here. // Set up code that uses the Qt event loop here.
// Call a.quit() or a.exit() to quit the application. // Call a.quit() or a.exit() to quit the application.

View File

@@ -1,21 +1,35 @@
#include "fb2extractor.h" #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; Fb2Metadata meta;
QString currentElement; QString currentElement;
bool inTitleInfo = false; bool inTitleInfo = false;
bool inAuthor = false; bool inAuthor = false;
QString currentAuthor; QString currentAuthor;
while (!sr.atEnd()) while (!xmlData.atEnd())
{ {
switch (sr.readNext()) switch (xmlData.readNext())
{ {
case QXmlStreamReader::StartElement: case QXmlStreamReader::StartElement:
currentElement = sr.name().toString(); currentElement = xmlData.name().toString();
if (currentElement == "title-info") if (currentElement == "title-info")
{ {
@@ -25,11 +39,11 @@ Fb2Metadata parseFb2Metadata(QXmlStreamReader &sr)
{ {
if (currentElement == "book-title") if (currentElement == "book-title")
{ {
meta.title = sr.readElementText(); meta.title = xmlData.readElementText();
} }
else if (currentElement == "genre") else if (currentElement == "genre")
{ {
meta.genres << sr.readElementText(); meta.genres << xmlData.readElementText();
} }
else if (currentElement == "author") else if (currentElement == "author")
{ {
@@ -38,17 +52,17 @@ Fb2Metadata parseFb2Metadata(QXmlStreamReader &sr)
} }
else if (inAuthor && (currentElement == "first-name" || currentElement == "last-name" || currentElement == "middle-name")) else if (inAuthor && (currentElement == "first-name" || currentElement == "last-name" || currentElement == "middle-name"))
{ {
currentAuthor += sr.readElementText() + " "; currentAuthor += xmlData.readElementText() + " ";
} }
} }
break; break;
case QXmlStreamReader::EndElement: case QXmlStreamReader::EndElement:
if (sr.name().toString() == "title-info") if (xmlData.name().toString() == "title-info")
{ {
inTitleInfo = false; inTitleInfo = false;
} }
else if (sr.name().toString() == "author" && inAuthor) else if (xmlData.name().toString() == "author" && inAuthor)
{ {
meta.authors << currentAuthor.trimmed(); meta.authors << currentAuthor.trimmed();
inAuthor = false; 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; return meta;

36
src/utils/fb2extractor.h Normal file
View File

@@ -0,0 +1,36 @@
#ifndef FB2EXTRACTOR_H
#define FB2EXTRACTOR_H
#include "utils_global.h"
#include <QDebug>
#include <QString>
#include <QXmlStreamReader>
#include <external_libs/quazip/quazip/quazipfile.h>
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

22
src/utils/utils.qbs Normal file
View File

@@ -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",
]
}
}

12
src/utils/utils_global.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef UTILS_GLOBAL_H
#define UTILS_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(UTILS_LIBRARY)
#define UTILS_EXPORT Q_DECL_EXPORT
#else
#define UTILS_EXPORT Q_DECL_IMPORT
#endif
#endif // UTILS_GLOBAL_H

60
src/utils/zipwrapper.cpp Normal file
View File

@@ -0,0 +1,60 @@
#include "zipwrapper.h"
#include <external_libs/quazip/quazip/quazip.h>
#include <external_libs/quazip/quazip/quazipfile.h>
// zipwrapper.cpp
#include "zipwrapper.h"
#include <QDebug>
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<QuaZipFile> ZipWrapper::getFile(const QString& filename)
{
QSharedPointer<QuaZipFile> 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<QuaZipFile>(new QuaZipFile(m_zip.data()));
return shqzf;
};
return file;
}
bool ZipWrapper::isOpen() const
{
return m_zip && m_zip->isOpen();
}

29
src/utils/zipwrapper.h Normal file
View File

@@ -0,0 +1,29 @@
// zipwrapper.h
#ifndef ZIPWRAPPER_H
#define ZIPWRAPPER_H
#include "utils_global.h"
#include <QScopedPointer>
#include <QString>
#include <QStringList>
#include <QSharedPointer>
class QuaZip;
class QuaZipFile;
class UTILS_EXPORT ZipWrapper
{
public:
explicit ZipWrapper(const QString& zipFilePath);
~ZipWrapper();
QStringList getFiles();
QSharedPointer<QuaZipFile> getFile(const QString& filename);
bool isOpen() const;
private:
QSharedPointer<QuaZip> m_zip;
};
#endif // ZIPWRAPPER_H