From 39ba4efcd23935a03ccb4d08f253fa96f00bcc41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 26 Aug 2023 14:09:18 +0200 Subject: [PATCH] Add `rescan-xml-info` command to YACReaderLibraryServer --- CHANGELOG.md | 3 + .../YACReaderLibraryServer.pro | 2 + .../console_ui_library_creator.cpp | 26 + .../console_ui_library_creator.h | 1 + YACReaderLibraryServer/main.cpp | 648 ++++++++++-------- 5 files changed, 404 insertions(+), 276 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c045f98e..a4ffde8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/YACReaderLibraryServer/YACReaderLibraryServer.pro b/YACReaderLibraryServer/YACReaderLibraryServer.pro index 39e652fc..7c892f61 100644 --- a/YACReaderLibraryServer/YACReaderLibraryServer.pro +++ b/YACReaderLibraryServer/YACReaderLibraryServer.pro @@ -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 \ diff --git a/YACReaderLibraryServer/console_ui_library_creator.cpp b/YACReaderLibraryServer/console_ui_library_creator.cpp index 4b2b85df..8933c5a0 100644 --- a/YACReaderLibraryServer/console_ui_library_creator.cpp +++ b/YACReaderLibraryServer/console_ui_library_creator.cpp @@ -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++; diff --git a/YACReaderLibraryServer/console_ui_library_creator.h b/YACReaderLibraryServer/console_ui_library_creator.h index a97c92e9..6049aafc 100644 --- a/YACReaderLibraryServer/console_ui_library_creator.h +++ b/YACReaderLibraryServer/console_ui_library_creator.h @@ -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; diff --git a/YACReaderLibraryServer/main.cpp b/YACReaderLibraryServer/main.cpp index 833be3a6..46363826 100644 --- a/YACReaderLibraryServer/main.cpp +++ b/YACReaderLibraryServer/main.cpp @@ -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,222 +104,21 @@ int main(int argc, char **argv) settings->beginGroup("libraryConfig"); if (command == "start") { - parser.clearPositionalArguments(); - parser.addPositionalArgument("start", "Start YACReaderLibraryServer"); - parser.process(app); - - QString destLog = YACReader::getSettingsPath() + "/yacreaderlibrary.log"; - QDir().mkpath(YACReader::getSettingsPath()); - - Logger &logger = Logger::instance(); - - if (parser.isSet("loglevel")) { - if (parser.value("loglevel") == "trace") { - logger.setLoggingLevel(QsLogging::TraceLevel); - } else if (parser.value("loglevel") == "info") { - logger.setLoggingLevel(QsLogging::InfoLevel); - } else if (parser.value("loglevel") == "debug") { - logger.setLoggingLevel(QsLogging::DebugLevel); - } else if (parser.value("loglevel") == "warn") { - logger.setLoggingLevel(QsLogging::WarnLevel); - } else if (parser.value("loglevel") == "error") { - logger.setLoggingLevel(QsLogging::ErrorLevel); - } else { - parser.showHelp(); - } - } - - DestinationPtrU fileDestination(DestinationFactory::MakeFileDestination( - destLog, LogRotationOption::EnableLogRotation, MaxSizeBytes(1048576), MaxOldLogCount(2))); - DestinationPtrU debugDestination(DestinationFactory::MakeDebugOutputDestination()); - logger.addDestination(std::move(debugDestination)); - logger.addDestination(std::move(fileDestination)); - - QTranslator translator; - QString sufix = QLocale::system().name(); -#if defined Q_OS_UNIX && !defined Q_OS_MACOS - translator.load(QString(DATADIR) + "/yacreader/languages/yacreaderlibrary_" + sufix); -#else - translator.load(QCoreApplication::applicationDirPath() + "/languages/yacreaderlibrary_" + sufix); -#endif - app.installTranslator(&translator); - - QTranslator viewerTranslator; -#if defined Q_OS_UNIX && !defined Q_OS_MACOS - viewerTranslator.load(QString(DATADIR) + "/yacreader/languages/yacreader_" + sufix); -#else - viewerTranslator.load(QCoreApplication::applicationDirPath() + "/languages/yacreader_" + sufix); -#endif - app.installTranslator(&viewerTranslator); - - qRegisterMetaType("ComicDB"); - - QLOG_INFO() << "YACReaderLibraryServer attempting to start"; - - logSystemAndConfig(); - - if (YACReaderLocalServer::isRunning()) // allow one server instance - { - QLOG_WARN() << "another instance of YACReaderLibrary is running"; -#ifdef Q_OS_WIN - logger.shutDownLoggerThread(); -#endif - return 0; - } - - QLOG_INFO() << "YACReaderLibrary starting"; - - // server - YACReaderHttpServer *httpServer = new YACReaderHttpServer(); - if (parser.isSet("port")) { - bool valid; - qint32 port = parser.value("port").toInt(&valid); - if (!valid || port < 1 || port > 65535) { - qout << "Error: " << parser.value("port") << " is not a valid port" << Qt::endl; - parser.showHelp(); - return 0; - } else { - httpServer->start(port); - } - - } else { - httpServer->start(); - } - - printServerInfo(httpServer); - - // Update libraries to new versions - LibrariesUpdater updater; - updater.updateIfNeeded(); - - YACReaderLocalServer *localServer = new YACReaderLocalServer(); - - YACReaderLibraries libraries; - auto librariesUpdateCoordinator = new LibrariesUpdateCoordinator(settings, libraries, []() { - return true; - }); - - app.connect(librariesUpdateCoordinator, &LibrariesUpdateCoordinator::updateStarted, &app, []() { - QLOG_INFO() << "Starting libraries update"; - }); - app.connect(librariesUpdateCoordinator, &LibrariesUpdateCoordinator::updateEnded, &app, []() { - QLOG_INFO() << "Done updating libraries"; - }); - - int ret = app.exec(); - - QLOG_INFO() << "YACReaderLibrary closed with exit code :" << ret; - - // shutdown - httpServer->stop(); - delete httpServer; - localServer->close(); - delete localServer; -#ifdef Q_OS_WIN - logger.shutDownLoggerThread(); -#endif - return ret; + return start(app, parser, args, settings, qout); } else if (command == "create-library") { - parser.clearPositionalArguments(); - parser.addPositionalArgument("create-library", "Creates a library named \"name\" in the specified destination "); - parser.addPositionalArgument("name", "Library name", "\"name\""); - parser.addPositionalArgument("path", "Path to the folder where the library will be created", ""); - parser.process(app); - - const QStringList args = parser.positionalArguments(); - if (args.length() != 3) { - parser.showHelp(); - return 0; - } - - ConsoleUILibraryCreator *libraryCreatorUI = new ConsoleUILibraryCreator(settings); - libraryCreatorUI->createLibrary(args.at(1), args.at(2)); - - return 0; + return createLibrary(app, parser, settings); } else if (command == "update-library") { - parser.clearPositionalArguments(); - parser.addPositionalArgument("update-library", "Updates an existing library at "); - parser.addPositionalArgument("path", "Path to the library to be updated", ""); - parser.process(app); - - const QStringList args = parser.positionalArguments(); - if (args.length() != 2) { - parser.showHelp(); - return 0; - } - - ConsoleUILibraryCreator *libraryCreatorUI = new ConsoleUILibraryCreator(settings); - libraryCreatorUI->updateLibrary(args.at(1)); - - return 0; + return updateLibrary(app, parser, settings); } else if (command == "add-library") { - parser.clearPositionalArguments(); - parser.addPositionalArgument("add-library", "Adds an exiting library named \"name\" at the specified origin "); - parser.addPositionalArgument("name", "Library name", "\"name\""); - parser.addPositionalArgument("path", "Path to the folder where the library is", ""); - parser.process(app); - - const QStringList args = parser.positionalArguments(); - if (args.length() != 3) { - parser.showHelp(); - return 0; - } - - ConsoleUILibraryCreator *libraryCreatorUI = new ConsoleUILibraryCreator(settings); - libraryCreatorUI->addExistingLibrary(args.at(1), args.at(2)); - - return 0; + return addLibrary(app, parser, settings); } else if (command == "remove-library") { - parser.clearPositionalArguments(); - parser.addPositionalArgument("remove-library", "Removes a library named \"name\" from the list of libraries"); - parser.addPositionalArgument("name", "Library name", "\"name\""); - parser.process(app); - - const QStringList args = parser.positionalArguments(); - if (args.length() != 2) { - parser.showHelp(); - return 0; - } - - ConsoleUILibraryCreator *libraryCreatorUI = new ConsoleUILibraryCreator(settings); - libraryCreatorUI->removeLibrary(args.at(1)); - - return 0; + return removeLibrary(app, parser, settings); } else if (command == "list-libraries") { - parser.clearPositionalArguments(); - parser.addPositionalArgument("list-libraries", "List all available libraries"); - parser.process(app); - - YACReaderLibraries libraries = DBHelper::getLibraries(); - for (QString libraryName : libraries.getNames()) - qout << libraryName << " : " << libraries.getPath(libraryName) << Qt::endl; - - return 0; + return listLibraries(app, parser, qout); } else if (command == "set-port") { - parser.clearPositionalArguments(); - parser.addPositionalArgument("set-port", "Set server port (persistent)."); - parser.addPositionalArgument("port", "1-65535", ""); - parser.process(app); - - const QStringList args = parser.positionalArguments(); - if (args.length() != 2) { - parser.showHelp(); - return 0; - } - - bool valid; - qint32 port = args.at(1).toInt(&valid); - if (!valid || port < 1 || port > 65535) { - qout << "Invalid server port"; - parser.showHelp(); - return 0; - } - - QSettings *settings = new QSettings(YACReader::getSettingsPath() + "/" + QCoreApplication::applicationName() + ".ini", QSettings::IniFormat); - settings->setValue("listener/port", QString::number(port)); - delete settings; - return 0; - + return setPort(app, parser, qout); + } else if (command == "rescan-xml-info") { + return rescanXmlInfo(app, parser, settings); } else // error { parser.process(app); @@ -378,3 +126,351 @@ int main(int argc, char **argv) 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); + + QString destLog = YACReader::getSettingsPath() + "/yacreaderlibrary.log"; + QDir().mkpath(YACReader::getSettingsPath()); + + Logger &logger = Logger::instance(); + + if (parser.isSet("loglevel")) { + if (parser.value("loglevel") == "trace") { + logger.setLoggingLevel(QsLogging::TraceLevel); + } else if (parser.value("loglevel") == "info") { + logger.setLoggingLevel(QsLogging::InfoLevel); + } else if (parser.value("loglevel") == "debug") { + logger.setLoggingLevel(QsLogging::DebugLevel); + } else if (parser.value("loglevel") == "warn") { + logger.setLoggingLevel(QsLogging::WarnLevel); + } else if (parser.value("loglevel") == "error") { + logger.setLoggingLevel(QsLogging::ErrorLevel); + } else { + parser.showHelp(); + } + } + + DestinationPtrU fileDestination(DestinationFactory::MakeFileDestination( + destLog, LogRotationOption::EnableLogRotation, MaxSizeBytes(1048576), MaxOldLogCount(2))); + DestinationPtrU debugDestination(DestinationFactory::MakeDebugOutputDestination()); + logger.addDestination(std::move(debugDestination)); + logger.addDestination(std::move(fileDestination)); + + QTranslator translator; + QString sufix = QLocale::system().name(); +#if defined Q_OS_UNIX && !defined Q_OS_MACOS + translator.load(QString(DATADIR) + "/yacreader/languages/yacreaderlibrary_" + sufix); +#else + translator.load(QCoreApplication::applicationDirPath() + "/languages/yacreaderlibrary_" + sufix); +#endif + app.installTranslator(&translator); + + QTranslator viewerTranslator; +#if defined Q_OS_UNIX && !defined Q_OS_MACOS + viewerTranslator.load(QString(DATADIR) + "/yacreader/languages/yacreader_" + sufix); +#else + viewerTranslator.load(QCoreApplication::applicationDirPath() + "/languages/yacreader_" + sufix); +#endif + app.installTranslator(&viewerTranslator); + + qRegisterMetaType("ComicDB"); + + QLOG_INFO() << "YACReaderLibraryServer attempting to start"; + + logSystemAndConfig(); + + if (YACReaderLocalServer::isRunning()) // allow one server instance + { + QLOG_WARN() << "another instance of YACReaderLibrary is running"; +#ifdef Q_OS_WIN + logger.shutDownLoggerThread(); +#endif + return 0; + } + + QLOG_INFO() << "YACReaderLibrary starting"; + + // server + YACReaderHttpServer *httpServer = new YACReaderHttpServer(); + if (parser.isSet("port")) { + bool valid; + qint32 port = parser.value("port").toInt(&valid); + if (!valid || port < 1 || port > 65535) { + qout << "Error: " << parser.value("port") << " is not a valid port" << Qt::endl; + parser.showHelp(); + return 0; + } else { + httpServer->start(port); + } + + } else { + httpServer->start(); + } + + printServerInfo(httpServer); + + // Update libraries to new versions + LibrariesUpdater updater; + updater.updateIfNeeded(); + + YACReaderLocalServer *localServer = new YACReaderLocalServer(); + + YACReaderLibraries libraries; + auto librariesUpdateCoordinator = new LibrariesUpdateCoordinator(settings, libraries, []() { + return true; + }); + + app.connect(librariesUpdateCoordinator, &LibrariesUpdateCoordinator::updateStarted, &app, []() { + QLOG_INFO() << "Starting libraries update"; + }); + app.connect(librariesUpdateCoordinator, &LibrariesUpdateCoordinator::updateEnded, &app, []() { + QLOG_INFO() << "Done updating libraries"; + }); + + int ret = app.exec(); + + QLOG_INFO() << "YACReaderLibrary closed with exit code :" << ret; + + // shutdown + httpServer->stop(); + delete httpServer; + localServer->close(); + delete localServer; +#ifdef Q_OS_WIN + logger.shutDownLoggerThread(); +#endif + return ret; +} + +// ----------------------------------------------------------------------------- +// 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 "); + parser.addPositionalArgument("name", "Library name", "\"name\""); + parser.addPositionalArgument("path", "Path to the folder where the library will be created", ""); + parser.process(app); + + const QStringList args = parser.positionalArguments(); + if (args.length() != 3) { + parser.showHelp(); + return 0; + } + + ConsoleUILibraryCreator *libraryCreatorUI = new ConsoleUILibraryCreator(settings); + libraryCreatorUI->createLibrary(args.at(1), args.at(2)); + + return 0; +} + +// ----------------------------------------------------------------------------- +// update-library--------------------------------------------------------------- +// ----------------------------------------------------------------------------- +int updateLibrary(QCoreApplication &app, QCommandLineParser &parser, QSettings *settings) +{ + parser.clearPositionalArguments(); + parser.addPositionalArgument("update-library", "Updates an existing library at "); + parser.addPositionalArgument("path", "Path to the library to be updated", ""); + parser.process(app); + + const QStringList args = parser.positionalArguments(); + if (args.length() != 2) { + parser.showHelp(); + return 0; + } + + ConsoleUILibraryCreator *libraryCreatorUI = new ConsoleUILibraryCreator(settings); + libraryCreatorUI->updateLibrary(args.at(1)); + + return 0; +} + +// ----------------------------------------------------------------------------- +// 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 "); + parser.addPositionalArgument("name", "Library name", "\"name\""); + parser.addPositionalArgument("path", "Path to the folder where the library is", ""); + parser.process(app); + + const QStringList args = parser.positionalArguments(); + if (args.length() != 3) { + parser.showHelp(); + return 0; + } + + ConsoleUILibraryCreator *libraryCreatorUI = new ConsoleUILibraryCreator(settings); + libraryCreatorUI->addExistingLibrary(args.at(1), args.at(2)); + + return 0; +} + +// ----------------------------------------------------------------------------- +// 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\""); + parser.process(app); + + const QStringList args = parser.positionalArguments(); + if (args.length() != 2) { + parser.showHelp(); + return 0; + } + + ConsoleUILibraryCreator *libraryCreatorUI = new ConsoleUILibraryCreator(settings); + libraryCreatorUI->removeLibrary(args.at(1)); + + return 0; +} + +// ----------------------------------------------------------------------------- +// list-libraries--------------------------------------------------------------- +// ----------------------------------------------------------------------------- +int listLibraries(QCoreApplication &app, QCommandLineParser &parser, QTextStream &qout) +{ + parser.clearPositionalArguments(); + parser.addPositionalArgument("list-libraries", "List all available libraries"); + parser.process(app); + + YACReaderLibraries libraries = DBHelper::getLibraries(); + for (QString libraryName : libraries.getNames()) + qout << libraryName << " : " << libraries.getPath(libraryName) << Qt::endl; + + return 0; +} + +// ----------------------------------------------------------------------------- +// 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", ""); + parser.process(app); + + const QStringList args = parser.positionalArguments(); + if (args.length() != 2) { + parser.showHelp(); + return 0; + } + + bool valid; + qint32 port = args.at(1).toInt(&valid); + if (!valid || port < 1 || port > 65535) { + qout << "Invalid server port"; + parser.showHelp(); + return 0; + } + + QSettings *settings = new QSettings(YACReader::getSettingsPath() + "/" + QCoreApplication::applicationName() + ".ini", QSettings::IniFormat); + settings->setValue("listener/port", QString::number(port)); + delete settings; + return 0; +} + +// ----------------------------------------------------------------------------- +// 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 and imports any missing tags from legacy ComicInfo.xml."); + parser.addPositionalArgument("path", "Path to the library to scan", ""); + 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"; + } +}