Skip to content

Commit

Permalink
Merge pull request #380 from YACReader/develop
Browse files Browse the repository at this point in the history
9.12
  • Loading branch information
luisangelsm authored Apr 23, 2023
2 parents fa3e5ea + 8f73876 commit fb85df7
Show file tree
Hide file tree
Showing 46 changed files with 2,068 additions and 335 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ Version counting is based on semantic versioning (Major.Feature.Patch)

## WIP

## 9.12

### YACReaderLibrary
* Fix scroll in grid views when using Qt6 builds.
* Fix deleting metadata from comics also deleted the number of pages info.
* Use https://github.com/nayuki/QR-Code-generator instead of libqrencode for QR code generation.
* Do not accept empty values for the server port in the server settings dialog.

### Server
* New search API that exposes the search engine.
* Print scannable QR code at server start

## 9.11

### YACReader
* Fix segfault (or worse) when exiting YACReader while processing a comic.
* Fix last read page calculation in double page mode.
Expand Down
7 changes: 1 addition & 6 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,9 @@ enter their respective subfolders and run the commands from there.

The headless version of YACReaderLibrary is located in the YACReaderLibraryServer
folder. To build it, enter the folder and run the commands described above.

Note: If your system has multiple versions of Qt, you need to make sure you are
using qmake for Qt5

## Build dependencies:

- Qt >= 5.9 with the following modules:
- Qt >= 5.15 with the following modules:
- declarative
- quickcontrols
- sql
Expand All @@ -31,7 +27,6 @@ using qmake for Qt5
- network
- Backends for pdf rendering (optional) and file
decompression (see below)
- qrencode for QR code generation (optional)

Not all dependencies are needed at build time. For example the qml components in
YACReaderLibrary (GridView, InfoView) will only show a white page if the
Expand Down
5 changes: 0 additions & 5 deletions YACReader/YACReader.pro
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ DEFINES += YACREADER
include (../config.pri)
include (../dependencies/pdf_backend.pri)

unix:haiku {
DEFINES += _BSD_SOURCE
LIBS += -lnetwork -lbsd
}

CONFIG(force_angle) {
contains(QMAKE_TARGET.arch, x86_64) {
Release:DESTDIR = ../release64_angle
Expand Down
14 changes: 7 additions & 7 deletions YACReaderLibrary/YACReaderLibrary.pro
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@ DEFINES += SERVER_RELEASE YACREADER_LIBRARY
include (../config.pri)
include (../dependencies/pdf_backend.pri)

unix:haiku {
DEFINES += _BSD_SOURCE
LIBS += -lnetwork -lbsd
}

INCLUDEPATH += ../common/gl

# there are two builds for Windows, Desktop OpenGL based and ANGLE OpenGL ES based
Expand Down Expand Up @@ -83,6 +78,7 @@ HEADERS += comic_flow.h \
db/comic_query_result_processor.h \
db/folder_query_result_processor.h \
db/query_lexer.h \
db/search_query.h \
folder_content_view.h \
initial_comic_info_extractor.h \
library_comic_opener.h \
Expand Down Expand Up @@ -154,7 +150,8 @@ HEADERS += comic_flow.h \
yacreader_comic_info_helper.h \
db/reading_list.h \
db/query_parser.h \
current_comic_view_helper.h
current_comic_view_helper.h \
ip_config_helper.h

!CONFIG(no_opengl) {
HEADERS += ../common/gl/yacreader_flow_gl.h
Expand All @@ -166,6 +163,7 @@ SOURCES += comic_flow.cpp \
db/comic_query_result_processor.cpp \
db/folder_query_result_processor.cpp \
db/query_lexer.cpp \
db/search_query.cpp \
folder_content_view.cpp \
initial_comic_info_extractor.cpp \
library_comic_opener.cpp \
Expand Down Expand Up @@ -235,7 +233,8 @@ SOURCES += comic_flow.cpp \
yacreader_comic_info_helper.cpp\
db/reading_list.cpp \
current_comic_view_helper.cpp \
db/query_parser.cpp
db/query_parser.cpp \
ip_config_helper.cpp

!CONFIG(no_opengl) {
SOURCES += ../common/gl/yacreader_flow_gl.cpp
Expand All @@ -262,6 +261,7 @@ include(../compressed_archive/libarchive/libarchive-wrapper.pri)
include(./comic_vine/comic_vine.pri)
include(../third_party/QsLog/QsLog.pri)
include(../shortcuts_management/shortcuts_management.pri)
include(../third_party/QrCode/QrCode.pri)

RESOURCES += images.qrc files.qrc
win32:RESOURCES += images_win.qrc
Expand Down
24 changes: 3 additions & 21 deletions YACReaderLibrary/db/comic_query_result_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
#include "comic_model.h"
#include "data_base_management.h"
#include "qnaturalsorting.h"
#include "db_helper.h"
#include "query_parser.h"

#include "QsLog.h"
#include "search_query.h"

YACReader::ComicQueryResultProcessor::ComicQueryResultProcessor()
: querySearchQueue(1)
Expand All @@ -22,25 +19,10 @@ void YACReader::ComicQueryResultProcessor::createModelData(const QString &filter
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
QSqlQuery selectQuery(db);

std::string queryString("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened "
"FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) LEFT JOIN folder f ON (f.id == c.parentId) WHERE ");

try {
QueryParser parser;
auto result = parser.parse(filter.toStdString());
result.buildSqlString(queryString);

queryString += " LIMIT :limit";

selectQuery.prepare(queryString.c_str());
selectQuery.bindValue(":limit", 500); // TODO, load this value from settings
result.bindValues(selectQuery);

selectQuery.exec();
auto query = comicsSearchQuery(db, filter);

auto data = modelData(selectQuery);
auto data = modelData(query);

emit newData(data, databasePath);
} catch (const std::exception &e) {
Expand Down
40 changes: 8 additions & 32 deletions YACReaderLibrary/db/folder_query_result_processor.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
#include "folder_query_result_processor.h"

#include "folder_item.h"
#include "qnaturalsorting.h"
#include "yacreader_global_gui.h"
#include "query_parser.h"
#include "folder_model.h"
#include "data_base_management.h"

#include "QsLog.h"
#include "search_query.h"

#include <QSqlQuery>
#include <QSqlDatabase>
Expand All @@ -20,41 +16,21 @@ YACReader::FolderQueryResultProcessor::FolderQueryResultProcessor(FolderModel *m
{
}

void YACReader::FolderQueryResultProcessor::createModelData(const QString &filter, bool includeComics)
void YACReader::FolderQueryResultProcessor::createModelData(const QString &filter)
{
querySearchQueue.cancelPending();

querySearchQueue.enqueue([=] {
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(model->getDatabase());
try {
auto query = foldersSearchQuery(db, filter);

QSqlQuery selectQuery(db); // TODO check
if (!includeComics) {
selectQuery.prepare("select * from folder where id <> 1 and upper(name) like upper(:filter) order by parentId,name ");
selectQuery.bindValue(":filter", "%%" + filter + "%%");
} else {
std::string queryString("SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed "
"FROM folder f LEFT JOIN comic c ON (f.id = c.parentId) "
"INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) WHERE ");

try {
QueryParser parser;
auto result = parser.parse(filter.toStdString());
result.buildSqlString(queryString);

queryString += " AND f.id <> 1 ORDER BY f.parentId,f.name";

selectQuery.prepare(queryString.c_str());
result.bindValues(selectQuery);

selectQuery.exec();

setupFilteredModelData(selectQuery);
} catch (const std::exception &e) {
// Do nothing, uncomplete search string will end here and it is part of how the QueryParser works
// I don't like the idea of using exceptions for this though
}
setupFilteredModelData(query);
} catch (const std::exception &e) {
// Do nothing, uncomplete search string will end here and it is part of how the QueryParser works
// I don't like the idea of using exceptions for this though
}

connectionName = db.connectionName();
Expand Down
2 changes: 1 addition & 1 deletion YACReaderLibrary/db/folder_query_result_processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class FolderQueryResultProcessor : public QObject
FolderQueryResultProcessor(FolderModel *model);

public slots:
void createModelData(const QString &filter, bool includeComics);
void createModelData(const QString &filter);

signals:
void newData(QMap<unsigned long long int, FolderItem *> *filteredItems, FolderItem *root);
Expand Down
3 changes: 3 additions & 0 deletions YACReaderLibrary/db/query_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#include <vector>
#include <list>

#define SEARCH_FOLDERS_QUERY "SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed, f.numChildren, f.firstChildHash FROM folder f LEFT JOIN comic c ON (f.id = c.parentId) INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) WHERE "
#define SEARCH_COMICS_QUERY "SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened,ci.coverSizeRatio,ci.lastTimeOpened,ci.manga FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) LEFT JOIN folder f ON (f.id == c.parentId) WHERE "

/**
* This class is used to generate an SQL query string from a search expression,
* with a syntax very similar to that used by the Google search engine.
Expand Down
43 changes: 43 additions & 0 deletions YACReaderLibrary/db/search_query.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

#include "search_query.h"
#include "query_parser.h"

#include <QtCore>
#include <QSqlQuery>

QSqlQuery foldersSearchQuery(QSqlDatabase &db, const QString &filter)
{
QueryParser parser;
auto result = parser.parse(filter.toStdString());

std::string queryString(SEARCH_FOLDERS_QUERY);
result.buildSqlString(queryString);
queryString += " AND f.id <> 1 ORDER BY f.parentId,f.name";

QSqlQuery selectQuery(db);
selectQuery.prepare(queryString.c_str());
result.bindValues(selectQuery);

selectQuery.exec();

return selectQuery;
}

QSqlQuery comicsSearchQuery(QSqlDatabase &db, const QString &filter)
{
QueryParser parser;
auto result = parser.parse(filter.toStdString());

std::string queryString(SEARCH_COMICS_QUERY);
result.buildSqlString(queryString);
queryString += " LIMIT :limit";

QSqlQuery selectQuery(db);
selectQuery.prepare(queryString.c_str());
selectQuery.bindValue(":limit", 500); // TODO, load this value from settings
result.bindValues(selectQuery);

selectQuery.exec();

return selectQuery;
}
10 changes: 10 additions & 0 deletions YACReaderLibrary/db/search_query.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

#ifndef SEARCHQUERY_H
#define SEARCHQUERY_H

#include <QSqlDatabase>

QSqlQuery foldersSearchQuery(QSqlDatabase &db, const QString &filter);
QSqlQuery comicsSearchQuery(QSqlDatabase &db, const QString &filter);

#endif // SEARCHQUERY_H
33 changes: 33 additions & 0 deletions YACReaderLibrary/ip_config_helper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include <QNetworkInterface>
#include "ip_config_helper.h"
#include "qnaturalsorting.h"

// 192.168 (most comon local subnet for ips are always put first)
// IPs are sorted using natoral sorting

QList<QString> getIpAddresses()
{
auto ipComparator = [](const QString &ip1, const QString &ip2) {
if (ip1.startsWith("192.168") && ip2.startsWith("192.168"))
return naturalSortLessThanCI(ip1, ip2);

if (ip1.startsWith("192.168"))
return true;

if (ip2.startsWith("192.168"))
return false;

return naturalSortLessThanCI(ip1, ip2);
};

QList<QString> addresses;
for (auto add : QNetworkInterface::allAddresses()) {
// Exclude loopback, local, multicast
if (add.isGlobal()) {
addresses.push_back(add.toString());
}
}

std::sort(addresses.begin(), addresses.end(), ipComparator);
return addresses;
}
4 changes: 4 additions & 0 deletions YACReaderLibrary/ip_config_helper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#ifndef YR_IP_CONFIG_HELPER
#define YR_IP_CONFIG_HELPER
QList<QString> getIpAddresses();
#endif
2 changes: 1 addition & 1 deletion YACReaderLibrary/library_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2415,7 +2415,7 @@ void LibraryWindow::toNormal()
void LibraryWindow::setSearchFilter(QString filter)
{
if (!filter.isEmpty()) {
folderQueryResultProcessor->createModelData(filter, true);
folderQueryResultProcessor->createModelData(filter);
comicQueryResultProcessor.createModelData(filter, foldersModel->getDatabase());
} else if (status == LibraryWindow::Searching) { // if no searching, then ignore this
clearSearchFilter();
Expand Down
2 changes: 1 addition & 1 deletion YACReaderLibrary/qml/FolderContentView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ Rectangle {
return;
}

var newValue = Math.min((grid.contentHeight - grid.height - (true ? main.continuReadingHeight : main.topContentMargin)), (Math.max(grid.originY , grid.contentY - event.angleDelta.y)));
var newValue = Math.min((grid.contentHeight - grid.height + grid.originY), (Math.max(grid.originY , grid.contentY - event.angleDelta.y)));
grid.contentY = newValue;
}
}
Expand Down
10 changes: 9 additions & 1 deletion YACReaderLibrary/qml/FolderContentView6.qml
Original file line number Diff line number Diff line change
Expand Up @@ -430,11 +430,19 @@ Rectangle {
return;
}

var newValue = Math.min((grid.contentHeight - grid.height - (true ? main.continuReadingHeight : main.topContentMargin)), (Math.max(grid.originY , grid.contentY - event.angleDelta.y)));
var newValue = Math.min((grid.contentHeight - grid.height + grid.originY), (Math.max(grid.originY , grid.contentY - event.angleDelta.y)));
grid.contentY = newValue;
}
}

onOriginYChanged: {
console.log(" origin changed ", grid.originY)
}

onContentYChanged: {
console.log(" content y changed ", grid.contentY)
}

ScrollBar.vertical: ScrollBar {
visible: grid.contentHeight > grid.height

Expand Down
2 changes: 1 addition & 1 deletion YACReaderLibrary/qml/GridComicsView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ SplitView {
return;
}

var newValue = Math.min((grid.contentHeight - grid.height - (showCurrentComic ? 270 : 20)), (Math.max(grid.originY , grid.contentY - event.angleDelta.y)));
var newValue = Math.min((grid.contentHeight - grid.height + grid.originY), (Math.max(grid.originY , grid.contentY - event.angleDelta.y)));
grid.contentY = newValue;
}
}
Expand Down
2 changes: 1 addition & 1 deletion YACReaderLibrary/qml/GridComicsView6.qml
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,7 @@ SplitView {
return;
}

var newValue = Math.min((grid.contentHeight - grid.height - (showCurrentComic ? 270 : 20)), (Math.max(grid.originY , grid.contentY - event.angleDelta.y)));
var newValue = Math.min((grid.contentHeight - grid.height + grid.originY), (Math.max(grid.originY , grid.contentY - event.angleDelta.y)));
grid.contentY = newValue;
}
}
Expand Down
Loading

0 comments on commit fb85df7

Please sign in to comment.