ОНО РАБОТАЕТ
хоть и стрёмно
This commit is contained in:
82
src/main.cpp
82
src/main.cpp
@@ -18,67 +18,6 @@
|
|||||||
#include <utils/fb2extractor.h>
|
#include <utils/fb2extractor.h>
|
||||||
#include <utils/zipwrapper.h>
|
#include <utils/zipwrapper.h>
|
||||||
|
|
||||||
QMap<QString, QString> readFb2MetadataFromZip(const QString& zipPath)
|
|
||||||
{
|
|
||||||
QMap<QString, QString> metadata;
|
|
||||||
QuaZip zip(zipPath);
|
|
||||||
|
|
||||||
if (!zip.open(QuaZip::mdUnzip))
|
|
||||||
{
|
|
||||||
qWarning() << "Failed to open ZIP archive";
|
|
||||||
return metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
for (bool more = zip.goToFirstFile(); more; more = zip.goToNextFile())
|
|
||||||
{
|
|
||||||
++count;
|
|
||||||
|
|
||||||
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);
|
|
||||||
// }
|
|
||||||
|
|
||||||
QString fb2FileName = zip.getCurrentFileName();
|
|
||||||
qWarning() << fb2FileName;
|
|
||||||
// if (fb2FileName.isEmpty())
|
|
||||||
// {
|
|
||||||
// qWarning() << "No FB2 file found in archive";
|
|
||||||
// zip.close();
|
|
||||||
// return metadata;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Читаем 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;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Парсим XML метаданные
|
|
||||||
// QXmlStreamReader fXmlBook(&fb2File);
|
|
||||||
// const auto data = parseFb2Metadata(fXmlBook);
|
|
||||||
|
|
||||||
// qWarning() << data.title << data.authors << data.genres;
|
|
||||||
|
|
||||||
// qWarning() << "*********" << count << "*********";
|
|
||||||
}
|
|
||||||
|
|
||||||
return metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fillBooksBD(uDBase& db)
|
void fillBooksBD(uDBase& db)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -184,21 +123,20 @@ int main(int argc, char* argv[])
|
|||||||
RestApiServer server(*db);
|
RestApiServer server(*db);
|
||||||
server.start(8080);
|
server.start(8080);
|
||||||
|
|
||||||
// QString zipArzh = "f.fb2-631519-634744.zip";
|
|
||||||
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);
|
|
||||||
// qWarning() << " books.count()" << books.count();
|
|
||||||
|
|
||||||
auto z = ZipWrapper(zipArzh);
|
auto z = ZipWrapper(zipArzh);
|
||||||
for (const auto& filename : z.getFiles())
|
const auto books = z.work();
|
||||||
|
|
||||||
|
for (const auto& book : books)
|
||||||
{
|
{
|
||||||
if (filename.endsWith(".fb2"))
|
try
|
||||||
{
|
{
|
||||||
auto zf = z.getFile(filename).data();
|
addBook(*db, book.title, book.authors);
|
||||||
auto fb2File = FB2Extractor(*zf);
|
}
|
||||||
const auto book = fb2File.parse();
|
catch (const odb::exception& e)
|
||||||
// qWarning() << book.title;
|
{
|
||||||
|
std::cerr << "Error adding test data: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,6 +151,6 @@ int main(int argc, char* argv[])
|
|||||||
// If you do not need a running Qt event loop, remove the call
|
// If you do not need a running Qt event loop, remove the call
|
||||||
// to a.exec() or use the Non-Qt Plain C++ Application template.
|
// to a.exec() or use the Non-Qt Plain C++ Application template.
|
||||||
|
|
||||||
qWarning() << "S EXIT";
|
// qWarning() << "S EXIT";
|
||||||
return a.exec();
|
return a.exec();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,19 +112,18 @@ QByteArray RestApiServer::processRequest(const QString& request)
|
|||||||
|
|
||||||
QJsonObject j;
|
QJsonObject j;
|
||||||
j["id"] = QString::number(book.id());
|
j["id"] = QString::number(book.id());
|
||||||
|
|
||||||
// QJsonObject author;
|
// QJsonObject author;
|
||||||
// author["id"] = QString::number(book.author()->id());
|
// author["id"] = QString::number(book.author()->id());
|
||||||
// author["fullName"] = book.author()->fullName();
|
// author["fullName"] = book.author()->fullName();
|
||||||
// author["langCode"] = book.author()->langCode();
|
// author["langCode"] = book.author()->langCode();
|
||||||
// j["author"] = author;
|
// j["author"] = author;
|
||||||
// // j["series"] = book.series()->serName();
|
// j["series"] = book.series()->serName();
|
||||||
// // j["genre"] = book.genre()->name();
|
// j["genre"] = book.genre()->name();
|
||||||
// j["title"] = book.title();
|
j["title"] = book.title();
|
||||||
// j["year"] = book.year();
|
// j["year"] = book.year();
|
||||||
// j["lastModified"] = book.lastModified().toString();
|
// j["lastModified"] = book.lastModified().toString();
|
||||||
// j["lang"] = book.lang();
|
// j["lang"] = book.lang();
|
||||||
// jArray.push_back(j);
|
jArray.push_back(j);
|
||||||
}
|
}
|
||||||
auto jDoc = QJsonDocument(jArray);
|
auto jDoc = QJsonDocument(jArray);
|
||||||
t.commit();
|
t.commit();
|
||||||
|
|||||||
@@ -16,6 +16,14 @@ FB2Extractor::~FB2Extractor()
|
|||||||
|
|
||||||
Fb2Metadata FB2Extractor::parse()
|
Fb2Metadata FB2Extractor::parse()
|
||||||
{
|
{
|
||||||
|
bool isOpen = m_file.open(QIODevice::ReadOnly);
|
||||||
|
// int zipError = fb2File.getZipError();
|
||||||
|
if (!isOpen)
|
||||||
|
{
|
||||||
|
qWarning() << "file in extractor is not open";
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
QXmlStreamReader xmlData(&m_file);
|
QXmlStreamReader xmlData(&m_file);
|
||||||
|
|
||||||
Fb2Metadata meta;
|
Fb2Metadata meta;
|
||||||
|
|||||||
@@ -11,9 +11,9 @@
|
|||||||
|
|
||||||
struct Fb2Metadata
|
struct Fb2Metadata
|
||||||
{
|
{
|
||||||
QString title; // Название книги
|
QString title; // Название книги
|
||||||
QStringList authors; // Авторы
|
QVector<QString> authors; // Авторы
|
||||||
QStringList genres; // Жанры
|
QStringList genres; // Жанры
|
||||||
};
|
};
|
||||||
|
|
||||||
Fb2Metadata UTILS_EXPORT parseFb2Metadata(QXmlStreamReader& sr);
|
Fb2Metadata UTILS_EXPORT parseFb2Metadata(QXmlStreamReader& sr);
|
||||||
|
|||||||
@@ -1,60 +1,142 @@
|
|||||||
#include "zipwrapper.h"
|
#include "zipwrapper.h"
|
||||||
|
|
||||||
#include <external_libs/quazip/quazip/quazip.h>
|
#include "fb2extractor.h"
|
||||||
|
|
||||||
#include <external_libs/quazip/quazip/quazipfile.h>
|
#include <external_libs/quazip/quazip/quazipfile.h>
|
||||||
|
|
||||||
// zipwrapper.cpp
|
namespace
|
||||||
#include "zipwrapper.h"
|
{
|
||||||
|
Fb2Metadata parse(QuaZipFile& m_file)
|
||||||
|
{
|
||||||
|
bool isOpen = m_file.open(QIODevice::ReadOnly);
|
||||||
|
// int zipError = fb2File.getZipError();
|
||||||
|
if (!isOpen)
|
||||||
|
{
|
||||||
|
qWarning() << "file in extractor is not open";
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
#include <QDebug>
|
QXmlStreamReader xmlData(&m_file);
|
||||||
|
|
||||||
|
Fb2Metadata meta;
|
||||||
|
QString currentElement;
|
||||||
|
bool inTitleInfo = false;
|
||||||
|
bool inAuthor = false;
|
||||||
|
QString currentAuthor;
|
||||||
|
|
||||||
|
while (!xmlData.atEnd())
|
||||||
|
{
|
||||||
|
switch (xmlData.readNext())
|
||||||
|
{
|
||||||
|
case QXmlStreamReader::StartElement:
|
||||||
|
currentElement = xmlData.name().toString();
|
||||||
|
|
||||||
|
if (currentElement == "title-info")
|
||||||
|
{
|
||||||
|
inTitleInfo = true;
|
||||||
|
}
|
||||||
|
else if (inTitleInfo)
|
||||||
|
{
|
||||||
|
if (currentElement == "book-title")
|
||||||
|
{
|
||||||
|
meta.title = xmlData.readElementText();
|
||||||
|
}
|
||||||
|
else if (currentElement == "genre")
|
||||||
|
{
|
||||||
|
meta.genres << xmlData.readElementText();
|
||||||
|
}
|
||||||
|
else if (currentElement == "author")
|
||||||
|
{
|
||||||
|
inAuthor = true;
|
||||||
|
currentAuthor.clear();
|
||||||
|
}
|
||||||
|
else if (inAuthor && (currentElement == "first-name" || currentElement == "last-name" || currentElement == "middle-name"))
|
||||||
|
{
|
||||||
|
currentAuthor += xmlData.readElementText() + " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QXmlStreamReader::EndElement:
|
||||||
|
if (xmlData.name().toString() == "title-info")
|
||||||
|
{
|
||||||
|
inTitleInfo = false;
|
||||||
|
}
|
||||||
|
else if (xmlData.name().toString() == "author" && inAuthor)
|
||||||
|
{
|
||||||
|
meta.authors << currentAuthor.trimmed();
|
||||||
|
inAuthor = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QXmlStreamReader::Characters:
|
||||||
|
// Обработка текста уже делается в readElementText()
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Прерываем парсинг, если нашли все метаданные
|
||||||
|
if (!meta.title.isEmpty() && !meta.authors.isEmpty() && !meta.genres.isEmpty())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xmlData.hasError())
|
||||||
|
{
|
||||||
|
qWarning() << "XML parsing error:" << xmlData.errorString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
ZipWrapper::ZipWrapper(const QString& zipFilePath) :
|
ZipWrapper::ZipWrapper(const QString& zipFilePath) :
|
||||||
m_zip(new QuaZip(zipFilePath))
|
m_zip(zipFilePath)
|
||||||
{
|
{
|
||||||
if (!m_zip->open(QuaZip::mdUnzip))
|
m_zip.open(QuaZip::mdUnzip);
|
||||||
{
|
isOpen();
|
||||||
qWarning() << "Failed to open archive:" << zipFilePath
|
|
||||||
<< "Error:" << m_zip->getZipError();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ZipWrapper::~ZipWrapper()
|
ZipWrapper::~ZipWrapper()
|
||||||
{
|
{
|
||||||
if (isOpen())
|
// В любом случае закрываем архив
|
||||||
{
|
m_zip.close();
|
||||||
m_zip->close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList ZipWrapper::getFiles()
|
QVector<Fb2Metadata> ZipWrapper::work()
|
||||||
{
|
{
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
return {};
|
return {};
|
||||||
return m_zip->getFileNameList();
|
|
||||||
}
|
|
||||||
|
|
||||||
QSharedPointer<QuaZipFile> ZipWrapper::getFile(const QString& filename)
|
// int i = 0;
|
||||||
{
|
QVector<Fb2Metadata> parsedBooks;
|
||||||
QSharedPointer<QuaZipFile> file(new QuaZipFile(m_zip.data()));
|
for (bool more = m_zip.goToFirstFile(); more; more = m_zip.goToNextFile())
|
||||||
|
|
||||||
if (!file->open(QIODevice::ReadOnly))
|
|
||||||
{
|
{
|
||||||
qWarning() << "Failed to open file:" << filename
|
// ++i;
|
||||||
<< "Error:" << file->getZipError();
|
if (m_zip.getCurrentFileName().endsWith(".fb2"))
|
||||||
return nullptr;
|
{
|
||||||
|
QuaZipFile fb2File(&m_zip);
|
||||||
|
|
||||||
|
auto fb2Extr = parse(fb2File);
|
||||||
|
// qWarning() << i << ":" << fb2Extr.title << fb2Extr.authors << fb2Extr.genres;
|
||||||
|
parsedBooks.push_back(fb2Extr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
qWarning() << "Неизвестный файл" << &m_zip;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (bool more = m_zip->goToFirstFile(); more; more = m_zip->goToNextFile())
|
return parsedBooks;
|
||||||
if (m_zip->getCurrentFileName() == filename)
|
|
||||||
{
|
|
||||||
auto shqzf = QSharedPointer<QuaZipFile>(new QuaZipFile(m_zip.data()));
|
|
||||||
return shqzf;
|
|
||||||
};
|
|
||||||
|
|
||||||
return file;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZipWrapper::isOpen() const
|
bool ZipWrapper::isOpen()
|
||||||
{
|
{
|
||||||
return m_zip && m_zip->isOpen();
|
if (m_zip.isOpen())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
qWarning() << "Не удалось открыть архив:" << m_zip.getZipName();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,31 @@
|
|||||||
// zipwrapper.h
|
|
||||||
#ifndef ZIPWRAPPER_H
|
#ifndef ZIPWRAPPER_H
|
||||||
#define ZIPWRAPPER_H
|
#define ZIPWRAPPER_H
|
||||||
|
|
||||||
#include "utils_global.h"
|
#include "utils_global.h"
|
||||||
|
|
||||||
#include <QScopedPointer>
|
#include <QDebug>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QXmlStreamReader>
|
||||||
#include <QSharedPointer>
|
|
||||||
|
|
||||||
class QuaZip;
|
|
||||||
class QuaZipFile;
|
|
||||||
|
#include <external_libs/quazip/quazip/quazip.h>
|
||||||
|
#include <external_libs/quazip/quazip/quazipfile.h> // TODO для совместимости. Временно
|
||||||
|
|
||||||
|
#include "fb2extractor.h"
|
||||||
|
|
||||||
class UTILS_EXPORT ZipWrapper
|
class UTILS_EXPORT ZipWrapper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ZipWrapper(const QString& zipFilePath);
|
ZipWrapper(const QString& zipFilePath);
|
||||||
~ZipWrapper();
|
~ZipWrapper();
|
||||||
|
|
||||||
QStringList getFiles();
|
QVector<Fb2Metadata> work();
|
||||||
QSharedPointer<QuaZipFile> getFile(const QString& filename);
|
|
||||||
bool isOpen() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSharedPointer<QuaZip> m_zip;
|
bool isOpen();
|
||||||
|
|
||||||
|
QuaZip m_zip;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ZIPWRAPPER_H
|
#endif // ZIPWRAPPER_H
|
||||||
|
|||||||
Reference in New Issue
Block a user