Add rescan-xml-info command to YACReaderLibraryServer

This commit is contained in:
Luis Ángel San Martín 2023-08-26 14:09:18 +02:00
parent 5706407778
commit 39ba4efcd2
5 changed files with 404 additions and 276 deletions

View File

@ -14,6 +14,9 @@ Version counting is based on semantic versioning (Major.Feature.Patch)
* Improve content reloading. Navigation and selection state is no longer reseted after content changes (e.g. library updates, tags edits, etc.)
* The app will try to move comics and folders to the trash bin when deletions are requested, if the file system used doesn't support trash bin the files will be removed permanetly.
### YACReaderLibrary
* Add `rescan-xml-info` command.
## 9.13.1
### YACReaderLibrary

View File

@ -48,6 +48,7 @@ HEADERS += ../YACReaderLibrary/library_creator.h \
../YACReaderLibrary/db/reading_list.h \
../YACReaderLibrary/initial_comic_info_extractor.h \
../YACReaderLibrary/xml_info_parser.h \
../YACReaderLibrary/xml_info_library_scanner.h \
../common/comic_db.h \
../common/folder.h \
../common/library_item.h \
@ -78,6 +79,7 @@ SOURCES += ../YACReaderLibrary/library_creator.cpp \
../YACReaderLibrary/db/reading_list.cpp \
../YACReaderLibrary/initial_comic_info_extractor.cpp \
../YACReaderLibrary/xml_info_parser.cpp \
../YACReaderLibrary/xml_info_library_scanner.cpp \
../common/comic_db.cpp \
../common/folder.cpp \
../common/library_item.cpp \

View File

@ -4,6 +4,9 @@
#include "library_creator.h"
#include "yacreader_libraries.h"
#include "xml_info_library_scanner.h"
using namespace YACReader;
ConsoleUILibraryCreator::ConsoleUILibraryCreator(QSettings *settings, QObject *parent)
: QObject(parent), numComicsProcessed(0), settings(settings)
@ -114,6 +117,29 @@ void ConsoleUILibraryCreator::removeLibrary(const QString &name)
std::cout << "Library removed : " << name.toUtf8().constData() << std::endl;
}
void ConsoleUILibraryCreator::rescanXMLInfoLibrary(const QString &path)
{
QDir pathDir(path);
if (!pathDir.exists()) {
std::cout << "Directory not found." << std::endl;
return;
}
QEventLoop eventLoop;
XMLInfoLibraryScanner *scanner = new XMLInfoLibraryScanner();
QString cleanPath = QDir::cleanPath(pathDir.absolutePath());
connect(scanner, &XMLInfoLibraryScanner::finished, this, &ConsoleUILibraryCreator::done);
connect(scanner, &XMLInfoLibraryScanner::comicScanned, this, &ConsoleUILibraryCreator::newComic);
connect(scanner, &XMLInfoLibraryScanner::finished, &eventLoop, &QEventLoop::quit);
std::cout << "Scanning comics";
scanner->scanLibrary(cleanPath, QDir::cleanPath(pathDir.absolutePath() + "/.yacreaderlibrary"));
eventLoop.exec();
}
void ConsoleUILibraryCreator::newComic(const QString & /*relativeComicPath*/, const QString & /*coverPath*/)
{
numComicsProcessed++;

View File

@ -12,6 +12,7 @@ public:
void updateLibrary(const QString &path);
void addExistingLibrary(const QString &name, const QString &path);
void removeLibrary(const QString &name);
void rescanXMLInfoLibrary(const QString &path);
private:
uint numComicsProcessed;

View File

@ -25,74 +25,23 @@
#include "ip_config_helper.h"
using namespace QsLogging;
// Returns false in case of a parse error (unknown option or missing value); returns true otherwise.
void logSystemAndConfig()
{
QLOG_INFO() << "---------- System & configuration ----------";
QLOG_INFO() << "OS:" << QSysInfo::prettyProductName() << "Version: " << QSysInfo::productVersion();
QLOG_INFO() << "Kernel:" << QSysInfo::kernelType() << QSysInfo::kernelVersion() << "Architecture:" << QSysInfo::currentCpuArchitecture();
QLOG_INFO() << "Libraries: " << DBHelper::getLibraries().getLibraries();
QLOG_INFO() << "--------------------------------------------";
}
int start(QCoreApplication &app, QCommandLineParser &parser, const QStringList &args, QSettings *settings, QTextStream &qout);
int createLibrary(QCoreApplication &app, QCommandLineParser &parser, QSettings *settings);
int updateLibrary(QCoreApplication &app, QCommandLineParser &parser, QSettings *settings);
int addLibrary(QCoreApplication &app, QCommandLineParser &parser, QSettings *settings);
int removeLibrary(QCoreApplication &app, QCommandLineParser &parser, QSettings *settings);
int listLibraries(QCoreApplication &app, QCommandLineParser &parser, QTextStream &qout);
int setPort(QCoreApplication &app, QCommandLineParser &parser, QTextStream &qout);
int rescanXmlInfo(QCoreApplication &app, QCommandLineParser &parser, QSettings *settings);
void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
Q_UNUSED(context);
QByteArray localMsg = msg.toLocal8Bit();
switch (type) {
case QtInfoMsg: {
QLOG_INFO() << localMsg.constData();
break;
}
case QtDebugMsg: {
QLOG_DEBUG() << localMsg.constData();
break;
}
case QtWarningMsg: {
QLOG_WARN() << localMsg.constData();
break;
}
case QtCriticalMsg: {
QLOG_ERROR() << localMsg.constData();
break;
}
case QtFatalMsg: {
QLOG_FATAL() << localMsg.constData();
break;
}
}
}
void printServerInfo(YACReaderHttpServer *httpServer)
{
auto addresses = getIpAddresses();
QLOG_INFO() << "Running on" << addresses.first() + ":" + httpServer->getPort().toLocal8Bit() << "\n";
qrcodegen::QrCode code = qrcodegen::QrCode::encodeText(
(addresses.first() + ":" + httpServer->getPort()).toLocal8Bit(),
qrcodegen::QrCode::Ecc::LOW);
int border = 4;
for (int y = -border; y < code.getSize() + border; y += 2) {
QString QRCodeString;
for (int x = -border - 1; x < code.getSize() + border + 1; x++) {
QRCodeString.append((code.getModule(x, y) && code.getModule(x, y + 1))
? " "
: code.getModule(x, y + 1) ? u8"\u2580"
: code.getModule(x, y) ? u8"\u2584"
: u8"\u2588");
}
QLOG_INFO() << QRCodeString;
}
if (addresses.length() > 1) {
QLOG_INFO() << addresses.length() - 1 << "more network interfaces detected";
}
}
void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg);
void printServerInfo(YACReaderHttpServer *httpServer);
void logSystemAndConfig();
// -----------------------------------------------------------------------------
// main-------------------------------------------------------------------------
// -----------------------------------------------------------------------------
int main(int argc, char **argv)
{
qInstallMessageHandler(messageHandler);
@ -136,7 +85,7 @@ int main(int argc, char **argv)
.arg(settingsPath));
parser.addHelpOption();
const QCommandLineOption versionOption = parser.addVersionOption();
parser.addPositionalArgument("command", "The command to execute. [start, create-library, update-library, add-library, remove-library, list-libraries, set-port]");
parser.addPositionalArgument("command", "The command to execute. [start, create-library, update-library, add-library, remove-library, list-libraries, set-port, rescan-xml-info]");
parser.addOption({ "loglevel", "Set log level. Valid values: trace, info, debug, warn, error.", "loglevel", "info" });
parser.addOption({ "port", "Set server port (temporary). Valid values: 1-65535", "port" });
parser.parse(app.arguments());
@ -155,6 +104,34 @@ int main(int argc, char **argv)
settings->beginGroup("libraryConfig");
if (command == "start") {
return start(app, parser, args, settings, qout);
} else if (command == "create-library") {
return createLibrary(app, parser, settings);
} else if (command == "update-library") {
return updateLibrary(app, parser, settings);
} else if (command == "add-library") {
return addLibrary(app, parser, settings);
} else if (command == "remove-library") {
return removeLibrary(app, parser, settings);
} else if (command == "list-libraries") {
return listLibraries(app, parser, qout);
} else if (command == "set-port") {
return setPort(app, parser, qout);
} else if (command == "rescan-xml-info") {
return rescanXmlInfo(app, parser, settings);
} else // error
{
parser.process(app);
parser.showHelp();
return 0;
}
}
// -----------------------------------------------------------------------------
// start------------------------------------------------------------------------
// -----------------------------------------------------------------------------
int start(QCoreApplication &app, QCommandLineParser &parser, const QStringList &args, QSettings *settings, QTextStream &qout)
{
parser.clearPositionalArguments();
parser.addPositionalArgument("start", "Start YACReaderLibraryServer");
parser.process(app);
@ -270,7 +247,13 @@ int main(int argc, char **argv)
logger.shutDownLoggerThread();
#endif
return ret;
} else if (command == "create-library") {
}
// -----------------------------------------------------------------------------
// create-library---------------------------------------------------------------
// -----------------------------------------------------------------------------
int createLibrary(QCoreApplication &app, QCommandLineParser &parser, QSettings *settings)
{
parser.clearPositionalArguments();
parser.addPositionalArgument("create-library", "Creates a library named \"name\" in the specified destination <path>");
parser.addPositionalArgument("name", "Library name", "\"name\"");
@ -287,7 +270,13 @@ int main(int argc, char **argv)
libraryCreatorUI->createLibrary(args.at(1), args.at(2));
return 0;
} else if (command == "update-library") {
}
// -----------------------------------------------------------------------------
// update-library---------------------------------------------------------------
// -----------------------------------------------------------------------------
int updateLibrary(QCoreApplication &app, QCommandLineParser &parser, QSettings *settings)
{
parser.clearPositionalArguments();
parser.addPositionalArgument("update-library", "Updates an existing library at <path>");
parser.addPositionalArgument("path", "Path to the library to be updated", "<path>");
@ -303,7 +292,13 @@ int main(int argc, char **argv)
libraryCreatorUI->updateLibrary(args.at(1));
return 0;
} else if (command == "add-library") {
}
// -----------------------------------------------------------------------------
// add-library---------------------------------------------------------------
// -----------------------------------------------------------------------------
int addLibrary(QCoreApplication &app, QCommandLineParser &parser, QSettings *settings)
{
parser.clearPositionalArguments();
parser.addPositionalArgument("add-library", "Adds an exiting library named \"name\" at the specified origin <path>");
parser.addPositionalArgument("name", "Library name", "\"name\"");
@ -320,7 +315,13 @@ int main(int argc, char **argv)
libraryCreatorUI->addExistingLibrary(args.at(1), args.at(2));
return 0;
} else if (command == "remove-library") {
}
// -----------------------------------------------------------------------------
// remove-library---------------------------------------------------------------
// -----------------------------------------------------------------------------
int removeLibrary(QCoreApplication &app, QCommandLineParser &parser, QSettings *settings)
{
parser.clearPositionalArguments();
parser.addPositionalArgument("remove-library", "Removes a library named \"name\" from the list of libraries");
parser.addPositionalArgument("name", "Library name", "\"name\"");
@ -336,7 +337,13 @@ int main(int argc, char **argv)
libraryCreatorUI->removeLibrary(args.at(1));
return 0;
} else if (command == "list-libraries") {
}
// -----------------------------------------------------------------------------
// list-libraries---------------------------------------------------------------
// -----------------------------------------------------------------------------
int listLibraries(QCoreApplication &app, QCommandLineParser &parser, QTextStream &qout)
{
parser.clearPositionalArguments();
parser.addPositionalArgument("list-libraries", "List all available libraries");
parser.process(app);
@ -346,7 +353,13 @@ int main(int argc, char **argv)
qout << libraryName << " : " << libraries.getPath(libraryName) << Qt::endl;
return 0;
} else if (command == "set-port") {
}
// -----------------------------------------------------------------------------
// set-port---------------------------------------------------------------------
// -----------------------------------------------------------------------------
int setPort(QCoreApplication &app, QCommandLineParser &parser, QTextStream &qout)
{
parser.clearPositionalArguments();
parser.addPositionalArgument("set-port", "Set server port (persistent).");
parser.addPositionalArgument("port", "1-65535", "<port>");
@ -370,11 +383,94 @@ int main(int argc, char **argv)
settings->setValue("listener/port", QString::number(port));
delete settings;
return 0;
}
} else // error
{
// -----------------------------------------------------------------------------
// rescan-xml-info--------------------------------------------------------------
// -----------------------------------------------------------------------------
int rescanXmlInfo(QCoreApplication &app, QCommandLineParser &parser, QSettings *settings)
{
parser.clearPositionalArguments();
parser.addPositionalArgument("rescan-xml-info", "Rescans all the files from an existing library at <path> and imports any missing tags from legacy ComicInfo.xml.");
parser.addPositionalArgument("path", "Path to the library to scan", "<path>");
parser.process(app);
const QStringList args = parser.positionalArguments();
if (args.length() != 2) {
parser.showHelp();
return 0;
}
ConsoleUILibraryCreator *libraryCreatorUI = new ConsoleUILibraryCreator(settings);
libraryCreatorUI->rescanXMLInfoLibrary(args.at(1));
return 0;
}
// -----------------------------------------------------------------------------
void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
Q_UNUSED(context);
QByteArray localMsg = msg.toLocal8Bit();
switch (type) {
case QtInfoMsg: {
QLOG_INFO() << localMsg.constData();
break;
}
case QtDebugMsg: {
QLOG_DEBUG() << localMsg.constData();
break;
}
case QtWarningMsg: {
QLOG_WARN() << localMsg.constData();
break;
}
case QtCriticalMsg: {
QLOG_ERROR() << localMsg.constData();
break;
}
case QtFatalMsg: {
QLOG_FATAL() << localMsg.constData();
break;
}
}
}
void logSystemAndConfig()
{
QLOG_INFO() << "---------- System & configuration ----------";
QLOG_INFO() << "OS:" << QSysInfo::prettyProductName() << "Version: " << QSysInfo::productVersion();
QLOG_INFO() << "Kernel:" << QSysInfo::kernelType() << QSysInfo::kernelVersion() << "Architecture:" << QSysInfo::currentCpuArchitecture();
QLOG_INFO() << "Libraries: " << DBHelper::getLibraries().getLibraries();
QLOG_INFO() << "--------------------------------------------";
}
void printServerInfo(YACReaderHttpServer *httpServer)
{
auto addresses = getIpAddresses();
QLOG_INFO() << "Running on" << addresses.first() + ":" + httpServer->getPort().toLocal8Bit() << "\n";
qrcodegen::QrCode code = qrcodegen::QrCode::encodeText(
(addresses.first() + ":" + httpServer->getPort()).toLocal8Bit(),
qrcodegen::QrCode::Ecc::LOW);
int border = 4;
for (int y = -border; y < code.getSize() + border; y += 2) {
QString QRCodeString;
for (int x = -border - 1; x < code.getSize() + border + 1; x++) {
QRCodeString.append((code.getModule(x, y) && code.getModule(x, y + 1))
? " "
: code.getModule(x, y + 1) ? u8"\u2580"
: code.getModule(x, y) ? u8"\u2584"
: u8"\u2588");
}
QLOG_INFO() << QRCodeString;
}
if (addresses.length() > 1) {
QLOG_INFO() << addresses.length() - 1 << "more network interfaces detected";
}
}