Merge branch 'server_2.0' into develop

This commit is contained in:
Luis Ángel San Martín 2018-05-22 18:10:24 +02:00
commit 66d1bd1046
200 changed files with 7215 additions and 3160 deletions

7
.gitignore vendored
View File

@ -32,6 +32,13 @@ ui_*.h
*.jsc
Makefile*
*build-*
*.build*
*.app*
*.pbxproj
*.mak
*.xcworkspace*
*xcshareddata*
*.swp
# Qt unit tests
target_wrapper.*

View File

@ -1681,12 +1681,26 @@ void MainWindowViewer::decreasePageZoomLevel()
void MainWindowViewer::sendComic()
{
YACReaderLocalClient * client = new YACReaderLocalClient;
currentComicDB.info.hasBeenOpened = true;
viewer->updateComic(currentComicDB);
int retries = 1;
while(!client->sendComicInfo(libraryId,currentComicDB) && retries!=0)
retries--;
connect(client,SIGNAL(finished()),client,SLOT(deleteLater()));
//delete client;
YACReaderLocalClient * client = new YACReaderLocalClient;
currentComicDB.info.lastTimeOpened = QDateTime::currentSecsSinceEpoch();
viewer->updateComic(currentComicDB);
if (currentComicDB.info.currentPage == currentComicDB.info.numPages) {
int currentIndex = siblingComics.indexOf(currentComicDB);
if(currentIndex+1 > 0 && currentIndex+1 < siblingComics.count())
{
ComicDB & nextComic = siblingComics[currentIndex+1];
nextComic.info.hasBeenOpened = true;
int retries = 1;
while(!client->sendComicInfo(libraryId,currentComicDB,nextComic.id) && retries!=0)
retries--;
connect(client,SIGNAL(finished()),client,SLOT(deleteLater()));
}
} else {
int retries = 1;
while(!client->sendComicInfo(libraryId,currentComicDB) && retries!=0)
retries--;
connect(client,SIGNAL(finished()),client,SLOT(deleteLater()));
}
//delete client;
}

View File

@ -417,7 +417,7 @@ Render::~Render()
{
if(comic!=0)
{
//comic->moveToThread(QApplication::instance()->thread());
comic->moveToThread(QApplication::instance()->thread());
comic->deleteLater();
}
@ -679,7 +679,7 @@ void Render::setComic(Comic * c)
{
if(comic !=0)
{
//comic->moveToThread(QApplication::instance()->thread());
comic->moveToThread(QApplication::instance()->thread());
comic->disconnect();
comic->deleteLater();
}

View File

@ -1186,8 +1186,8 @@ void Viewer::updateComic(ComicDB & comic)
{
if(render->hasLoadedComic())
{
//set currentPage
if(render->currentPageIsDoublePage() == false)
//set currentPage
if(!doublePage || (doublePage && render->currentPageIsDoublePage() == false))
{
comic.info.currentPage = render->getIndex()+1;
}

View File

@ -125,47 +125,92 @@ bool YACReaderLocalClient::requestComicInfo(quint64 libraryId, ComicDB & comic,
}
}
bool YACReaderLocalClient::sendComicInfo(quint64 libraryId, ComicDB & comic)
{
localSocket->connectToServer(YACREADERLIBRARY_GUID);
if(localSocket->isOpen())
{
localSocket->connectToServer(YACREADERLIBRARY_GUID);
if(localSocket->isOpen())
{
//QLOG_INFO() << "Connection opened for sending ComicInfo";
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_8);
out << (quint32)0;
out << (quint8)YACReader::SendComicInfo;
out << libraryId;
out << comic;
out.device()->seek(0);
out << (quint32)(block.size() - sizeof(quint32));
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_8);
out << (quint32)0;
out << (quint8)YACReader::SendComicInfo;
out << libraryId;
out << comic;
out.device()->seek(0);
out << (quint32)(block.size() - sizeof(quint32));
int written, previousWritten;
written = previousWritten = 0;
int tries = 0;
while(written != block.size() && tries < 100)
{
written += localSocket->write(block);
int written, previousWritten;
written = previousWritten = 0;
int tries = 0;
while(written != block.size() && tries < 100)
{
written += localSocket->write(block);
if(written == previousWritten)
tries++;
previousWritten = written;
}
}
localSocket->waitForBytesWritten(2000);
localSocket->close();
localSocket->close();
//QLOG_INFO() << QString("Sending Comic Info : writen data (%1,%2)").arg(written).arg(block.size());
if(tries == 100 && written != block.size())
{
emit finished();
QLOG_ERROR() << QString("Sending Comic Info : unable to write data (%1,%2)").arg(written).arg(block.size());
return false;
}
emit finished();
return true;
}
emit finished();
QLOG_ERROR() << "Sending Comic Info : unable to connect to the server";
return false;
if(tries == 100 && written != block.size())
{
emit finished();
QLOG_ERROR() << QString("Sending Comic Info : unable to write data (%1,%2)").arg(written).arg(block.size());
return false;
}
emit finished();
return true;
}
emit finished();
QLOG_ERROR() << "Sending Comic Info : unable to connect to the server";
return false;
}
bool YACReaderLocalClient::sendComicInfo(quint64 libraryId, ComicDB & comic, qulonglong nextComicId)
{
localSocket->connectToServer(YACREADERLIBRARY_GUID);
if(localSocket->isOpen())
{
//QLOG_INFO() << "Connection opened for sending ComicInfo";
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_8);
out << (quint32)0;
out << (quint8)YACReader::SendComicInfo;
out << libraryId;
out << comic;
out << nextComicId;
out.device()->seek(0);
out << (quint32)(block.size() - sizeof(quint32));
int written, previousWritten;
written = previousWritten = 0;
int tries = 0;
while(written != block.size() && tries < 100)
{
written += localSocket->write(block);
if(written == previousWritten)
tries++;
previousWritten = written;
}
localSocket->waitForBytesWritten(2000);
localSocket->close();
//QLOG_INFO() << QString("Sending Comic Info : writen data (%1,%2)").arg(written).arg(block.size());
if(tries == 100 && written != block.size())
{
emit finished();
QLOG_ERROR() << QString("Sending Comic Info : unable to write data (%1,%2)").arg(written).arg(block.size());
return false;
}
emit finished();
return true;
}
emit finished();
QLOG_ERROR() << "Sending Comic Info : unable to connect to the server";
return false;
}

View File

@ -18,6 +18,8 @@ public slots:
void readMessage();
bool requestComicInfo(quint64 libraryId, ComicDB & comic,QList<ComicDB> & siblings);
bool sendComicInfo(quint64 libraryId, ComicDB & comic);
bool sendComicInfo(quint64 libraryId, ComicDB & comic, qulonglong nextComicId);
private:
QLocalSocket * localSocket;

View File

@ -1,317 +1,321 @@
TEMPLATE = app
TARGET = YACReaderLibrary
QMAKE_TARGET_BUNDLE_PREFIX = "com.yacreader"
DEPENDPATH += .
INCLUDEPATH += . \
../common \
./server \
./db \
../custom_widgets \
./comic_vine \
./comic_vine/model
DEFINES += SERVER_RELEASE NOMINMAX YACREADER_LIBRARY
QMAKE_MAC_SDK = macosx10.12
# load default build flags
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
win32 {
CONFIG(force_angle) {
message("using ANGLE")
LIBS += -loleaut32 -lole32 -lshell32 -lopengl32 -lglu32 -luser32
# linking extra libs are necesary for a successful compilation, a better approach should be
# to remove any OpenGL (desktop) dependencies
# the OpenGL stuff should be migrated to OpenGL ES
DEFINES += FORCE_ANGLE
} else {
LIBS += -loleaut32 -lole32 -lshell32 -lopengl32 -lglu32 -luser32
}
QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT /GL
QMAKE_LFLAGS_RELEASE += /LTCG
CONFIG -= embed_manifest_exe
}
CONFIG(force_angle) {
contains(QMAKE_TARGET.arch, x86_64) {
Release:DESTDIR = ../release64_angle
Debug:DESTDIR = ../debug64_angle
} else {
Release:DESTDIR = ../release_angle
Debug:DESTDIR = ../debug_angle
}
} else {
contains(QMAKE_TARGET.arch, x86_64) {
Release:DESTDIR = ../release64
Debug:DESTDIR = ../debug64
} else {
Release:DESTDIR = ../release
Debug:DESTDIR = ../debug
}
}
unix:!macx:!CONFIG(no_opengl) {
LIBS += -lGLU
}
macx {
LIBS += -framework Foundation -framework ApplicationServices -framework AppKit
CONFIG += objective_c
QT += macextras gui-private
}
unix:!macx {
CONFIG += c++11
}
#CONFIG += release
CONFIG -= flat
QT += sql network widgets script
!CONFIG(no_opengl) {
QT += opengl
}
# Input
HEADERS += comic_flow.h \
create_library_dialog.h \
library_creator.h \
library_window.h \
add_library_dialog.h \
rename_library_dialog.h \
properties_dialog.h \
options_dialog.h \
export_library_dialog.h \
import_library_dialog.h \
package_manager.h \
bundle_creator.h \
export_comics_info_dialog.h \
import_comics_info_dialog.h \
server_config_dialog.h \
comic_flow_widget.h \
db_helper.h \
./db/data_base_management.h \
./db/folder_item.h \
./db/folder_model.h \
./db/comic_model.h \
./db/comic_item.h \
../common/comic_db.h \
../common/folder.h \
../common/library_item.h \
../common/comic.h \
../common/bookmarks.h \
../common/pictureflow.h \
../common/custom_widgets.h \
../common/qnaturalsorting.h \
../common/yacreader_global.h \
../common/yacreader_global_gui.h \
../common/onstart_flow_selection_dialog.h \
../common/pdf_comic.h \
no_libraries_widget.h \
import_widget.h \
yacreader_local_server.h \
yacreader_main_toolbar.h \
comics_remover.h \
../common/http_worker.h \
yacreader_libraries.h \
../common/exit_check.h \
comics_view.h \
classic_comics_view.h \
empty_folder_widget.h \
no_search_results_widget.h \
comic_files_manager.h \
db/reading_list_model.h \
db/reading_list_item.h \
yacreader_folders_view.h \
yacreader_reading_lists_view.h \
add_label_dialog.h \
yacreader_history_controller.h \
yacreader_navigation_controller.h \
empty_label_widget.h \
empty_container_info.h \
empty_special_list.h \
empty_reading_list_widget.h \
../common/scroll_management.h \
../common/opengl_checker.h \
yacreader_comics_views_manager.h \
info_comics_view.h \
yacreader_comics_selection_helper.h \
yacreader_comic_info_helper.h
!CONFIG(no_opengl) {
HEADERS += ../common/gl/yacreader_flow_gl.h
}
SOURCES += comic_flow.cpp \
create_library_dialog.cpp \
library_creator.cpp \
library_window.cpp \
main.cpp \
add_library_dialog.cpp \
rename_library_dialog.cpp \
properties_dialog.cpp \
options_dialog.cpp \
export_library_dialog.cpp \
import_library_dialog.cpp \
package_manager.cpp \
bundle_creator.cpp \
export_comics_info_dialog.cpp \
import_comics_info_dialog.cpp \
server_config_dialog.cpp \
comic_flow_widget.cpp \
db_helper.cpp \
./db/data_base_management.cpp \
./db/folder_item.cpp \
./db/folder_model.cpp \
./db/comic_model.cpp \
./db/comic_item.cpp \
../common/comic_db.cpp \
../common/folder.cpp \
../common/library_item.cpp \
../common/comic.cpp \
../common/bookmarks.cpp \
../common/pictureflow.cpp \
../common/custom_widgets.cpp \
../common/qnaturalsorting.cpp \
../common/onstart_flow_selection_dialog.cpp \
no_libraries_widget.cpp \
import_widget.cpp \
yacreader_local_server.cpp \
yacreader_main_toolbar.cpp \
comics_remover.cpp \
../common/http_worker.cpp \
../common/yacreader_global.cpp \
../common/yacreader_global_gui.cpp \
yacreader_libraries.cpp \
../common/exit_check.cpp \
comics_view.cpp \
classic_comics_view.cpp \
empty_folder_widget.cpp \
no_search_results_widget.cpp \
comic_files_manager.cpp \
db/reading_list_model.cpp \
db/reading_list_item.cpp \
yacreader_folders_view.cpp \
yacreader_reading_lists_view.cpp \
add_label_dialog.cpp \
yacreader_history_controller.cpp \
yacreader_navigation_controller.cpp \
empty_label_widget.cpp \
empty_container_info.cpp \
empty_special_list.cpp \
empty_reading_list_widget.cpp \
../common/scroll_management.cpp \
../common/opengl_checker.cpp \
yacreader_comics_views_manager.cpp \
info_comics_view.cpp \
yacreader_comics_selection_helper.cpp \
yacreader_comic_info_helper.cpp
!CONFIG(no_opengl) {
SOURCES += ../common/gl/yacreader_flow_gl.cpp
}
include(./server/server.pri)
include(../custom_widgets/custom_widgets_yacreaderlibrary.pri)
CONFIG(7zip){
include(../compressed_archive/wrapper.pri)
} else:CONFIG(unarr) {
include(../compressed_archive/unarr/unarr-wrapper.pri)
} else {
error(No compression backend specified. Did you mess with the build system?)
}
include(./comic_vine/comic_vine.pri)
include(../QsLog/QsLog.pri)
include(../shortcuts_management/shortcuts_management.pri)
RESOURCES += images.qrc files.qrc
win32:RESOURCES += images_win.qrc
unix:!macx:RESOURCES += images_win.qrc
macx:RESOURCES += images_osx.qrc
RC_FILE = icon.rc
macx {
ICON = YACReaderLibrary.icns
}
TRANSLATIONS = yacreaderlibrary_es.ts \
yacreaderlibrary_ru.ts \
yacreaderlibrary_pt.ts \
yacreaderlibrary_fr.ts \
yacreaderlibrary_nl.ts \
yacreaderlibrary_tr.ts \
yacreaderlibrary_de.ts \
yacreaderlibrary_source.ts
#QML/GridView
QT += quick qml
HEADERS += grid_comics_view.h \
comics_view_transition.h
SOURCES += grid_comics_view.cpp \
comics_view_transition.cpp
RESOURCES += qml.qrc
win32:RESOURCES += qml_win.qrc
unix:!macx:RESOURCES += qml_win.qrc
macx:RESOURCES += qml_osx.qrc
unix:!macx {
#set install prefix if it's empty
isEmpty(PREFIX) {
PREFIX = /usr
}
isEmpty(BINDIR) {
BINDIR = $$PREFIX/bin
}
isEmpty(LIBDIR) {
LIBDIR = $$PREFIX/lib
}
isEmpty(DATADIR) {
DATADIR = $$PREFIX/share
}
DEFINES += "LIBDIR=\\\"$$LIBDIR\\\"" "DATADIR=\\\"$$DATADIR\\\""
DEFINES += "LIBDIR=\\\"$$LIBDIR\\\"" "DATADIR=\\\"$$DATADIR\\\"" "BINDIR=\\\"$$BINDIR\\\""
#MAKE INSTALL
INSTALLS += bin icon desktop server translation manpage
bin.path = $$BINDIR
isEmpty(DESTDIR) {
bin.files = YACReaderLibrary
} else {
bin.files = $$DESTDIR/YACReaderLibrary
}
server.path = $$DATADIR/yacreader
server.files = ../release/server
icon.path = $$DATADIR/icons/hicolor/scalable/apps
icon.files = ../YACReaderLibrary.svg
desktop.path = $$DATADIR/applications
desktop.files = ../YACReaderLibrary.desktop
translation.path = $$DATADIR/yacreader/languages
translation.files = ../release/languages/yacreaderlibrary_*
manpage.path = $$DATADIR/man/man1
manpage.files = ../YACReaderLibrary.1
}
TEMPLATE = app
TARGET = YACReaderLibrary
QMAKE_TARGET_BUNDLE_PREFIX = "com.yacreader"
DEPENDPATH += .
INCLUDEPATH += . \
../common \
./server \
./db \
../custom_widgets \
./comic_vine \
./comic_vine/model
DEFINES += SERVER_RELEASE NOMINMAX YACREADER_LIBRARY
QMAKE_MAC_SDK = macosx10.12
# load default build flags
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
win32 {
CONFIG(force_angle) {
message("using ANGLE")
LIBS += -loleaut32 -lole32 -lshell32 -lopengl32 -lglu32 -luser32
# linking extra libs are necesary for a successful compilation, a better approach should be
# to remove any OpenGL (desktop) dependencies
# the OpenGL stuff should be migrated to OpenGL ES
DEFINES += FORCE_ANGLE
} else {
LIBS += -loleaut32 -lole32 -lshell32 -lopengl32 -lglu32 -luser32
}
QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT /GL
QMAKE_LFLAGS_RELEASE += /LTCG
CONFIG -= embed_manifest_exe
}
CONFIG(force_angle) {
contains(QMAKE_TARGET.arch, x86_64) {
Release:DESTDIR = ../release64_angle
Debug:DESTDIR = ../debug64_angle
} else {
Release:DESTDIR = ../release_angle
Debug:DESTDIR = ../debug_angle
}
} else {
contains(QMAKE_TARGET.arch, x86_64) {
Release:DESTDIR = ../release64
Debug:DESTDIR = ../debug64
} else {
Release:DESTDIR = ../release
Debug:DESTDIR = ../debug
}
}
unix:!macx:!CONFIG(no_opengl) {
LIBS += -lGLU
}
macx {
LIBS += -framework Foundation -framework ApplicationServices -framework AppKit
CONFIG += objective_c
QT += macextras gui-private
}
unix:!macx {
CONFIG += c++11
}
#CONFIG += release
CONFIG -= flat
QT += sql network widgets script
!CONFIG(no_opengl) {
QT += opengl
}
# Input
HEADERS += comic_flow.h \
create_library_dialog.h \
library_creator.h \
library_window.h \
add_library_dialog.h \
rename_library_dialog.h \
properties_dialog.h \
options_dialog.h \
export_library_dialog.h \
import_library_dialog.h \
package_manager.h \
bundle_creator.h \
export_comics_info_dialog.h \
import_comics_info_dialog.h \
server_config_dialog.h \
comic_flow_widget.h \
db_helper.h \
./db/data_base_management.h \
./db/folder_item.h \
./db/folder_model.h \
./db/comic_model.h \
./db/comic_item.h \
../common/comic_db.h \
../common/folder.h \
../common/library_item.h \
../common/comic.h \
../common/bookmarks.h \
../common/pictureflow.h \
../common/custom_widgets.h \
../common/qnaturalsorting.h \
../common/yacreader_global.h \
../common/yacreader_global_gui.h \
../common/onstart_flow_selection_dialog.h \
../common/pdf_comic.h \
no_libraries_widget.h \
import_widget.h \
yacreader_local_server.h \
yacreader_main_toolbar.h \
comics_remover.h \
../common/http_worker.h \
yacreader_libraries.h \
../common/exit_check.h \
comics_view.h \
classic_comics_view.h \
empty_folder_widget.h \
no_search_results_widget.h \
comic_files_manager.h \
db/reading_list_model.h \
db/reading_list_item.h \
yacreader_folders_view.h \
yacreader_reading_lists_view.h \
add_label_dialog.h \
yacreader_history_controller.h \
yacreader_navigation_controller.h \
empty_label_widget.h \
empty_container_info.h \
empty_special_list.h \
empty_reading_list_widget.h \
../common/scroll_management.h \
../common/opengl_checker.h \
yacreader_comics_views_manager.h \
info_comics_view.h \
yacreader_comics_selection_helper.h \
yacreader_comic_info_helper.h \
db/reading_list.h \
current_comic_view_helper.h
!CONFIG(no_opengl) {
HEADERS += ../common/gl/yacreader_flow_gl.h
}
SOURCES += comic_flow.cpp \
create_library_dialog.cpp \
library_creator.cpp \
library_window.cpp \
main.cpp \
add_library_dialog.cpp \
rename_library_dialog.cpp \
properties_dialog.cpp \
options_dialog.cpp \
export_library_dialog.cpp \
import_library_dialog.cpp \
package_manager.cpp \
bundle_creator.cpp \
export_comics_info_dialog.cpp \
import_comics_info_dialog.cpp \
server_config_dialog.cpp \
comic_flow_widget.cpp \
db_helper.cpp \
./db/data_base_management.cpp \
./db/folder_item.cpp \
./db/folder_model.cpp \
./db/comic_model.cpp \
./db/comic_item.cpp \
../common/comic_db.cpp \
../common/folder.cpp \
../common/library_item.cpp \
../common/comic.cpp \
../common/bookmarks.cpp \
../common/pictureflow.cpp \
../common/custom_widgets.cpp \
../common/qnaturalsorting.cpp \
../common/onstart_flow_selection_dialog.cpp \
no_libraries_widget.cpp \
import_widget.cpp \
yacreader_local_server.cpp \
yacreader_main_toolbar.cpp \
comics_remover.cpp \
../common/http_worker.cpp \
../common/yacreader_global.cpp \
../common/yacreader_global_gui.cpp \
yacreader_libraries.cpp \
../common/exit_check.cpp \
comics_view.cpp \
classic_comics_view.cpp \
empty_folder_widget.cpp \
no_search_results_widget.cpp \
comic_files_manager.cpp \
db/reading_list_model.cpp \
db/reading_list_item.cpp \
yacreader_folders_view.cpp \
yacreader_reading_lists_view.cpp \
add_label_dialog.cpp \
yacreader_history_controller.cpp \
yacreader_navigation_controller.cpp \
empty_label_widget.cpp \
empty_container_info.cpp \
empty_special_list.cpp \
empty_reading_list_widget.cpp \
../common/scroll_management.cpp \
../common/opengl_checker.cpp \
yacreader_comics_views_manager.cpp \
info_comics_view.cpp \
yacreader_comics_selection_helper.cpp \
yacreader_comic_info_helper.cpp\
db/reading_list.cpp \
current_comic_view_helper.cpp
!CONFIG(no_opengl) {
SOURCES += ../common/gl/yacreader_flow_gl.cpp
}
include(./server/server.pri)
include(../custom_widgets/custom_widgets_yacreaderlibrary.pri)
CONFIG(7zip){
include(../compressed_archive/wrapper.pri)
} else:CONFIG(unarr) {
include(../compressed_archive/unarr/unarr-wrapper.pri)
} else {
error(No compression backend specified. Did you mess with the build system?)
}
include(./comic_vine/comic_vine.pri)
include(../QsLog/QsLog.pri)
include(../shortcuts_management/shortcuts_management.pri)
RESOURCES += images.qrc files.qrc
win32:RESOURCES += images_win.qrc
unix:!macx:RESOURCES += images_win.qrc
macx:RESOURCES += images_osx.qrc
RC_FILE = icon.rc
macx {
ICON = YACReaderLibrary.icns
}
TRANSLATIONS = yacreaderlibrary_es.ts \
yacreaderlibrary_ru.ts \
yacreaderlibrary_pt.ts \
yacreaderlibrary_fr.ts \
yacreaderlibrary_nl.ts \
yacreaderlibrary_tr.ts \
yacreaderlibrary_de.ts \
yacreaderlibrary_source.ts
#QML/GridView
QT += quick qml
HEADERS += grid_comics_view.h \
comics_view_transition.h
SOURCES += grid_comics_view.cpp \
comics_view_transition.cpp
RESOURCES += qml.qrc
win32:RESOURCES += qml_win.qrc
unix:!macx:RESOURCES += qml_win.qrc
macx:RESOURCES += qml_osx.qrc
unix:!macx {
#set install prefix if it's empty
isEmpty(PREFIX) {
PREFIX = /usr
}
isEmpty(BINDIR) {
BINDIR = $$PREFIX/bin
}
isEmpty(LIBDIR) {
LIBDIR = $$PREFIX/lib
}
isEmpty(DATADIR) {
DATADIR = $$PREFIX/share
}
DEFINES += "LIBDIR=\\\"$$LIBDIR\\\"" "DATADIR=\\\"$$DATADIR\\\""
DEFINES += "LIBDIR=\\\"$$LIBDIR\\\"" "DATADIR=\\\"$$DATADIR\\\"" "BINDIR=\\\"$$BINDIR\\\""
#MAKE INSTALL
INSTALLS += bin icon desktop server translation manpage
bin.path = $$BINDIR
isEmpty(DESTDIR) {
bin.files = YACReaderLibrary
} else {
bin.files = $$DESTDIR/YACReaderLibrary
}
server.path = $$DATADIR/yacreader
server.files = ../release/server
icon.path = $$DATADIR/icons/hicolor/scalable/apps
icon.files = ../YACReaderLibrary.svg
desktop.path = $$DATADIR/applications
desktop.files = ../YACReaderLibrary.desktop
translation.path = $$DATADIR/yacreader/languages
translation.files = ../release/languages/yacreaderlibrary_*
manpage.path = $$DATADIR/man/man1
manpage.files = ../YACReaderLibrary.1
}

View File

@ -265,6 +265,11 @@ void ClassicComicsView::selectIndex(int index)
tableView->selectRow(index);
}
void ClassicComicsView::updateCurrentComicView()
{
}
void ClassicComicsView::selectAll()
{
tableView->selectAll();

View File

@ -31,6 +31,7 @@ public:
void updateConfig(QSettings * settings);
void enableFilterMode(bool enabled);
void selectIndex(int index);
void updateCurrentComicView();
public slots:
void setCurrentIndex(const QModelIndex &index);

View File

@ -454,7 +454,7 @@ void ComicVineDialog::getComicsInfo(QList<QPair<ComicDB, QString> > & matchingIn
}
db.commit();
db.close();
QSqlDatabase::removeDatabase(databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
close();
emit accepted();
@ -492,7 +492,7 @@ void ComicVineDialog::getComicInfo(const QString &comicId, int count, const QStr
db.commit();
db.close();
QSqlDatabase::removeDatabase(databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
if(mode == SingleComic || currentIndex == (comics.count()-1))
{

View File

@ -5,8 +5,8 @@
#include "QsLog.h"
ComicsRemover::ComicsRemover(QModelIndexList & il, QList<QString> & ps, QObject *parent)
:QObject(parent),indexList(il), paths(ps)
ComicsRemover::ComicsRemover(QModelIndexList & il, QList<QString> & ps, qulonglong parentId, QObject *parent)
:QObject(parent),indexList(il), paths(ps), parentId(parentId)
{
}
@ -29,6 +29,7 @@ void ComicsRemover::process()
}
emit finished();
emit removedItemsFromFolder(parentId);
}

View File

@ -10,12 +10,13 @@ class ComicsRemover : public QObject
{
Q_OBJECT
public:
explicit ComicsRemover(QModelIndexList & indexList, QList<QString> & paths, QObject *parent = 0);
explicit ComicsRemover(QModelIndexList & indexList, QList<QString> & paths, qulonglong parentId, QObject *parent = 0);
signals:
void remove(int);
void removeError();
void finished();
void removedItemsFromFolder(qulonglong);
public slots:
void process();
@ -23,6 +24,7 @@ public slots:
private:
QModelIndexList indexList;
QList<QString> paths;
qulonglong parentId;
};
class FoldersRemover : public QObject

View File

@ -28,6 +28,7 @@ public:
virtual void updateConfig(QSettings * settings) = 0;
virtual void enableFilterMode(bool enabled) = 0;
virtual void selectIndex(int index) = 0;
virtual void updateCurrentComicView() = 0;
public slots:
virtual void updateInfoForIndex(int index);
@ -36,6 +37,7 @@ public slots:
signals:
void selected(unsigned int);
void openComic(const ComicDB& comic);
void comicRated(int,QModelIndex);
//Context menus

View File

@ -0,0 +1,17 @@
#include "current_comic_view_helper.h"
#include "comic_db.h"
ComicDB currentComicFromModel(ComicModel *model, bool &found) {
auto comics = model->getAllComics();
foreach (auto comic, comics) {
if (comic.info.read == false) {
found = true;
return comic;
}
}
found = false;
return ComicDB();
}

View File

@ -0,0 +1,8 @@
#ifndef CURRENT_COMIC_VIEW_HELPER_H
#define CURRENT_COMIC_VIEW_HELPER_H
#include "comic_model.h"
ComicDB currentComicFromModel(ComicModel *model, bool &found);
#endif // CURRENT_COMIC_VIEW_HELPER_H

View File

@ -176,7 +176,7 @@ bool ComicModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int
break;
}
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
//endMoveRows();
@ -295,7 +295,7 @@ QVariant ComicModel::data(const QModelIndex &index, int role) const
else if (role == RatingRole)
return item->data(Rating);
else if (role == CoverPathRole)
return QUrl("file:"+_databasePath+"/covers/"+item->data(Hash).toString()+".jpg");
return getCoverUrlPathForComicHash(item->data(Hash).toString());
else if (role == NumPagesRole)
return item->data(NumPages);
else if (role == CurrentPageRole)
@ -470,7 +470,7 @@ void ComicModel::setupFolderModelData(unsigned long long int folderId,const QStr
setupModelData(selectQuery);
}
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
endResetModel();
/*if(_data.length()==0)
@ -501,7 +501,7 @@ void ComicModel::setupLabelModelData(unsigned long long parentLabel, const QStri
setupModelDataForList(selectQuery);
}
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
endResetModel();
/*if(_data.length()==0)
@ -558,7 +558,7 @@ void ComicModel::setupReadingListModelData(unsigned long long parentReadingList,
}
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
endResetModel();
}
@ -582,10 +582,10 @@ void ComicModel::setupFavoritesModelData(const QString &databasePath)
"ORDER BY cdrl.ordering");
selectQuery.bindValue(":parentDefaultListId", 1);
selectQuery.exec();
setupModelData(selectQuery);
setupModelDataForList(selectQuery);
}
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
endResetModel();
/*if(_data.length()==0)
@ -607,12 +607,14 @@ void ComicModel::setupReadingModelData(const QString &databasePath)
QSqlQuery selectQuery(db);
selectQuery.prepare("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) "
"WHERE ci.hasBeenOpened = 1 AND ci.read = 0 AND ci.currentPage != ci.numPages AND ci.currentPage != 1");
"WHERE ci.hasBeenOpened = 1 AND ci.read = 0 "
"ORDER BY ci.lastTimeOpened DESC");
selectQuery.exec();
setupModelData(selectQuery);
setupModelDataForList(selectQuery);
}
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
endResetModel();
/*if(_data.length()==0)
@ -680,7 +682,7 @@ void ComicModel::setupModelData(const SearchModifiers modifier, const QString &f
//selectQuery.finish();
}
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
endResetModel();
emit searchNumResults(_data.length());
@ -746,7 +748,7 @@ ComicDB ComicModel::getComic(const QModelIndex & mi)
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
ComicDB c = DBHelper::loadComic(_data.at(mi.row())->data(ComicModel::Id).toULongLong(),db);
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
return c;
}
@ -756,7 +758,7 @@ ComicDB ComicModel::_getComic(const QModelIndex & mi)
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
ComicDB c = DBHelper::loadComic(_data.at(mi.row())->data(ComicModel::Id).toULongLong(),db);
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
return c;
}
@ -799,7 +801,7 @@ QList<ComicDB> ComicModel::getAllComics()
db.commit();
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
return comics;
}
@ -817,7 +819,7 @@ QList<ComicDB> ComicModel::getComics(QList<QModelIndex> list)
}
db.commit();
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
return comics;
}
//TODO
@ -848,7 +850,7 @@ QVector<YACReaderComicReadStatus> ComicModel::setComicsRead(QList<QModelIndex> l
}
db.commit();
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
emit dataChanged(index(list.first().row(),ComicModel::ReadColumn),index(list.last().row(),ComicModel::HasBeenOpened),QVector<int>() << ReadColumnRole << CurrentPageRole << HasBeenOpenedRole);
@ -871,7 +873,7 @@ qint64 ComicModel::asignNumbers(QList<QModelIndex> list,int startingNumber)
db.commit();
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
//emit dataChanged(index(0,ComicModel::Number),index(_data.count()-1,ComicModel::HasBeenOpened));
@ -904,7 +906,6 @@ QList<QModelIndex> ComicModel::getIndexesFromIds(const QList<qulonglong> &comicI
void ComicModel::startTransaction()
{
dbTransaction = DataBaseManagement::loadDatabase(_databasePath);
dbTransaction.transaction();
}
@ -913,7 +914,7 @@ void ComicModel::finishTransaction()
{
dbTransaction.commit();
dbTransaction.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(dbTransaction.connectionName());
}
void ComicModel::removeInTransaction(int row)
@ -928,7 +929,7 @@ void ComicModel::removeInTransaction(int row)
endRemoveRows();
}
/*
void ComicModel::remove(ComicDB * comic, int row)
{
beginRemoveRows(QModelIndex(),row,row);
@ -941,10 +942,10 @@ void ComicModel::remove(ComicDB * comic, int row)
_data.removeAt(row);
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
endRemoveRows();
}
*/
/*ComicDB TableModel::getComic(int row)
{
return getComic(index(row,0));
@ -989,7 +990,12 @@ void ComicModel::resetComicRating(const QModelIndex &mi)
emit dataChanged(mi,mi);
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
}
QUrl ComicModel::getCoverUrlPathForComicHash(const QString &hash) const
{
return QUrl("file:"+_databasePath+"/covers/"+hash+".jpg");
}
void ComicModel::addComicsToFavorites(const QList<qulonglong> &comicIds)
@ -1006,7 +1012,7 @@ void ComicModel::addComicsToFavorites(const QList<QModelIndex> & comicsList)
DBHelper::insertComicsInFavorites(comics,db);
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
}
void ComicModel::addComicsToLabel(const QList<qulonglong> &comicIds, qulonglong labelId)
@ -1023,7 +1029,7 @@ void ComicModel::addComicsToLabel(const QList<QModelIndex> &comicsList, qulonglo
DBHelper::insertComicsInLabel(comics,labelId,db);
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
}
void ComicModel::addComicsToReadingList(const QList<qulonglong> &comicIds, qulonglong readingListId)
@ -1040,7 +1046,7 @@ void ComicModel::addComicsToReadingList(const QList<QModelIndex> &comicsList, qu
DBHelper::insertComicsInReadingList(comics,readingListId,db);
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
}
void ComicModel::deleteComicsFromFavorites(const QList<QModelIndex> &comicsList)
@ -1052,7 +1058,7 @@ void ComicModel::deleteComicsFromFavorites(const QList<QModelIndex> &comicsList)
DBHelper::deleteComicsFromFavorites(comics,db);
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
if(mode == Favorites)
deleteComicsFromModel(comicsList);
@ -1067,7 +1073,7 @@ void ComicModel::deleteComicsFromLabel(const QList<QModelIndex> &comicsList, qul
DBHelper::deleteComicsFromLabel(comics,labelId,db);
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
deleteComicsFromModel(comicsList);
}
@ -1081,7 +1087,7 @@ void ComicModel::deleteComicsFromReadingList(const QList<QModelIndex> &comicsLis
DBHelper::deleteComicsFromReadingList(comics,readingListId,db);
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
deleteComicsFromModel(comicsList);
}
@ -1111,7 +1117,7 @@ bool ComicModel::isFavorite(const QModelIndex &index)
isFavorite = DBHelper::isFavoriteComic(_data[index.row()]->data(Id).toLongLong(),db);
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
return isFavorite;
}
@ -1130,5 +1136,5 @@ void ComicModel::updateRating(int rating, QModelIndex mi)
emit dataChanged(mi,mi);
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
}

View File

@ -6,6 +6,7 @@
#include <QVariant>
#include <QSqlQuery>
#include <QSqlDatabase>
#include <QUrl>
#include "yacreader_global_gui.h"
@ -65,11 +66,13 @@ public:
//setComicInfoForSelectedComis(QList<QModelIndex> list); -->inserta la información común para los comics seleccionados
QVector<YACReaderComicReadStatus> setComicsRead(QList<QModelIndex> list,YACReaderComicReadStatus read);
qint64 asignNumbers(QList<QModelIndex> list,int startingNumber);
void remove(ComicDB * comic, int row);
//void remove(ComicDB * comic, int row);
void removeInTransaction(int row);
void reload(const ComicDB & comic);
void resetComicRating(const QModelIndex & mi);
Q_INVOKABLE QUrl getCoverUrlPathForComicHash(const QString& hash) const;
void addComicsToFavorites(const QList<QModelIndex> &comicsList);
void addComicsToLabel(const QList<QModelIndex> &comicsList, qulonglong labelId);

View File

@ -3,7 +3,9 @@
#include <QtCore>
#include "library_creator.h"
#include "check_new_version.h"
#include "db_helper.h"
#include "QsLog.h"
static QString fields = "title ,"
@ -65,8 +67,9 @@ QSqlDatabase DataBaseManagement::createDatabase(QString name, QString path)
}
QSqlDatabase DataBaseManagement::createDatabase(QString dest)
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE",dest);
{
QString threadId = QString::number((long long)QThread::currentThreadId(), 16);
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE",dest+threadId);
db.setDatabaseName(dest);
if (!db.open())
qDebug() << db.lastError();
@ -90,9 +93,10 @@ QSqlDatabase DataBaseManagement::createDatabase(QString dest)
QSqlDatabase DataBaseManagement::loadDatabase(QString path)
{
//TODO check path
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE",path);
db.setDatabaseName(path+"/library.ydb");
//TODO check path
QString threadId = QString::number((long long)QThread::currentThreadId(), 16);
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE",path+threadId);
db.setDatabaseName(path + "/library.ydb");
if (!db.open()) {
//se devuelve una base de datos vacía e inválida
@ -106,8 +110,9 @@ QSqlDatabase DataBaseManagement::loadDatabase(QString path)
QSqlDatabase DataBaseManagement::loadDatabaseFromFile(QString filePath)
{
//TODO check path
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE",filePath);
//TODO check path
QString threadId = QString::number((long long)QThread::currentThreadId(), 16);
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE",filePath+threadId);
db.setDatabaseName(filePath);
if (!db.open()) {
//se devuelve una base de datos vacía e inválida
@ -124,99 +129,105 @@ QSqlDatabase DataBaseManagement::loadDatabaseFromFile(QString filePath)
bool DataBaseManagement::createTables(QSqlDatabase & database)
{
bool success = true;
bool success = true;
//FOLDER (representa una carpeta en disco)
{
QSqlQuery queryFolder(database);
queryFolder.prepare("CREATE TABLE folder ("
"id INTEGER PRIMARY KEY,"
"parentId INTEGER NOT NULL,"
"name TEXT NOT NULL,"
"path TEXT NOT NULL,"
//new 7.1 fields
"finished BOOLEAN DEFAULT 0," //reading
"completed BOOLEAN DEFAULT 1," //collecting
//--
"FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE)");
success = success && queryFolder.exec();
{
//COMIC INFO (representa la información de un cómic, cada cómic tendrá un idéntificador único formado por un hash sha1'de los primeros 512kb' + su tamaño en bytes)
QSqlQuery queryComicInfo(database);
queryComicInfo.prepare("CREATE TABLE comic_info ("
"id INTEGER PRIMARY KEY,"
"title TEXT,"
//COMIC INFO (representa la información de un cómic, cada cómic tendrá un idéntificador único formado por un hash sha1'de los primeros 512kb' + su tamaño en bytes)
QSqlQuery queryComicInfo(database);
queryComicInfo.prepare("CREATE TABLE comic_info ("
"id INTEGER PRIMARY KEY,"
"title TEXT,"
"coverPage INTEGER DEFAULT 1,"
"numPages INTEGER,"
"coverPage INTEGER DEFAULT 1,"
"numPages INTEGER,"
"number INTEGER,"
"isBis BOOLEAN,"
"count INTEGER,"
"number INTEGER,"
"isBis BOOLEAN,"
"count INTEGER,"
"volume TEXT,"
"storyArc TEXT,"
"arcNumber INTEGER,"
"arcCount INTEGER,"
"volume TEXT,"
"storyArc TEXT,"
"arcNumber INTEGER,"
"arcCount INTEGER,"
"genere TEXT,"
"genere TEXT,"
"writer TEXT,"
"penciller TEXT,"
"inker TEXT,"
"colorist TEXT,"
"letterer TEXT,"
"coverArtist TEXT,"
"writer TEXT,"
"penciller TEXT,"
"inker TEXT,"
"colorist TEXT,"
"letterer TEXT,"
"coverArtist TEXT,"
"date TEXT," //dd/mm/yyyy --> se mostrará en 3 campos diferentes
"publisher TEXT,"
"format TEXT,"
"color BOOLEAN,"
"ageRating BOOLEAN,"
"date TEXT," //dd/mm/yyyy --> se mostrará en 3 campos diferentes
"publisher TEXT,"
"format TEXT,"
"color BOOLEAN,"
"ageRating BOOLEAN,"
"synopsis TEXT,"
"characters TEXT,"
"notes TEXT,"
"synopsis TEXT,"
"characters TEXT,"
"notes TEXT,"
"hash TEXT UNIQUE NOT NULL,"
"edited BOOLEAN DEFAULT 0,"
"read BOOLEAN DEFAULT 0,"
//new 7.0 fields
"hash TEXT UNIQUE NOT NULL,"
"edited BOOLEAN DEFAULT 0,"
"read BOOLEAN DEFAULT 0,"
//new 7.0 fields
"hasBeenOpened BOOLEAN DEFAULT 0,"
"rating INTEGER DEFAULT 0,"
"currentPage INTEGER DEFAULT 1, "
"bookmark1 INTEGER DEFAULT -1, "
"bookmark2 INTEGER DEFAULT -1, "
"bookmark3 INTEGER DEFAULT -1, "
"brightness INTEGER DEFAULT -1, "
"contrast INTEGER DEFAULT -1, "
"gamma INTEGER DEFAULT -1, "
//new 7.1 fields
"comicVineID TEXT"
"hasBeenOpened BOOLEAN DEFAULT 0,"
"rating INTEGER DEFAULT 0,"
"currentPage INTEGER DEFAULT 1, "
"bookmark1 INTEGER DEFAULT -1, "
"bookmark2 INTEGER DEFAULT -1, "
"bookmark3 INTEGER DEFAULT -1, "
"brightness INTEGER DEFAULT -1, "
"contrast INTEGER DEFAULT -1, "
"gamma INTEGER DEFAULT -1, "
//new 7.1 fields
"comicVineID TEXT,"
//new 9.5 fields
"lastTimeOpened INTEGER,"
"coverSizeRatio REAL,"
"originalCoverSize STRING"//h/w
")");
success = success && queryComicInfo.exec();
//queryComicInfo.finish();
")");
success = success && queryComicInfo.exec();
//queryComicInfo.finish();
//COMIC (representa un cómic en disco, contiene el nombre de fichero)
QSqlQuery queryComic(database);
queryComic.prepare("CREATE TABLE comic (id INTEGER PRIMARY KEY, parentId INTEGER NOT NULL, comicInfoId INTEGER NOT NULL, fileName TEXT NOT NULL, path TEXT, FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE, FOREIGN KEY(comicInfoId) REFERENCES comic_info(id))");
success = success && queryComic.exec();
//queryComic.finish();
//DB INFO
QSqlQuery queryDBInfo(database);
queryDBInfo.prepare("CREATE TABLE db_info (version TEXT NOT NULL)");
success = success && queryDBInfo.exec();
//queryDBInfo.finish();
//FOLDER (representa una carpeta en disco)
QSqlQuery queryFolder(database);
queryFolder.prepare("CREATE TABLE folder ("
"id INTEGER PRIMARY KEY,"
"parentId INTEGER NOT NULL,"
"name TEXT NOT NULL,"
"path TEXT NOT NULL,"
//new 7.1 fields
"finished BOOLEAN DEFAULT 0," //reading
"completed BOOLEAN DEFAULT 1," //collecting
//new 9.5 fields
"numChildren INTEGER,"
"firstChildHash TEXT,"
"customImage TEXT,"
"FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE)");
success = success && queryFolder.exec();
QSqlQuery query("INSERT INTO db_info (version) "
"VALUES ('" VERSION "')",database);
//query.finish();
//COMIC (representa un cómic en disco, contiene el nombre de fichero)
QSqlQuery queryComic(database);
queryComic.prepare("CREATE TABLE comic (id INTEGER PRIMARY KEY, parentId INTEGER NOT NULL, comicInfoId INTEGER NOT NULL, fileName TEXT NOT NULL, path TEXT, FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE, FOREIGN KEY(comicInfoId) REFERENCES comic_info(id))");
success = success && queryComic.exec();
//queryComic.finish();
//DB INFO
QSqlQuery queryDBInfo(database);
queryDBInfo.prepare("CREATE TABLE db_info (version TEXT NOT NULL)");
success = success && queryDBInfo.exec();
//queryDBInfo.finish();
//8.0> tables
success = success && DataBaseManagement::createV8Tables(database);
QSqlQuery query("INSERT INTO db_info (version) "
"VALUES ('" VERSION "')",database);
//query.finish();
//8.0> tables
success = success && DataBaseManagement::createV8Tables(database);
}
return success;
@ -317,7 +328,7 @@ void DataBaseManagement::exportComicsInfo(QString source, QString dest)
//QSqlDatabase sourceDB = loadDatabase(source);
QSqlDatabase destDB = loadDatabaseFromFile(dest);
//sourceDB.open();
{
{
QSqlQuery attach(destDB);
attach.prepare("ATTACH DATABASE '"+QDir().toNativeSeparators(dest) +"' AS dest;");
//attach.bindValue(":dest",QDir().toNativeSeparators(dest));
@ -415,7 +426,12 @@ bool DataBaseManagement::importComicsInfo(QString source, QString dest)
"edited = :edited,"
"comicVineID = :comicVineID"
"comicVineID = :comicVineID,"
"lastTimeOpened = :lastTimeOpened,"
"coverSizeRatio = :coverSizeRatio,"
"originalCoverSize = :originalCoverSize"
" WHERE hash = :hash ");
@ -449,6 +465,8 @@ bool DataBaseManagement::importComicsInfo(QString source, QString dest)
"read,"
"edited,"
"comicVineID,"
"lastTimeOpened,"
"coverSizeRatio,"
"hash)"
"VALUES (:title,"
@ -486,6 +504,11 @@ bool DataBaseManagement::importComicsInfo(QString source, QString dest)
":edited,"
":comicVineID,"
":lastTimeOpened,"
":coverSizeRatio,"
":originalCoverSize,"
":hash )");
QSqlRecord record = newInfo.record();
@ -596,6 +619,11 @@ void DataBaseManagement::bindValuesFromRecord(const QSqlRecord & record, QSqlQue
bindString("comicVineID",record,query);
bindString("lastTimeOpened",record,query);
bindDouble("coverSizeRatio",record,query);
bindString("originalCoverSize",record,query);
bindString("hash",record,query);
}
@ -609,13 +637,30 @@ bool DataBaseManagement::addColumns(const QString &tableName, const QStringList
QSqlQuery alterTable(db);
alterTable.prepare(sql.arg(tableName).arg(columnDef));
//alterTableComicInfo.bindValue(":column_def",columnDef);
alterTable.exec();
returnValue = returnValue && (alterTable.numRowsAffected() > 0);
bool exec = alterTable.exec();
returnValue = returnValue && exec;
if (!exec) {
QLOG_ERROR() << alterTable.lastError().text();
}
//returnValue = returnValue && (alterTable.numRowsAffected() > 0);
}
return returnValue;
}
bool DataBaseManagement::addConstraint(const QString &tableName, const QString &constraint, const QSqlDatabase &db)
{
QString sql = "ALTER TABLE %1 ADD %2";
bool returnValue = true;
QSqlQuery alterTable(db);
alterTable.prepare(sql.arg(tableName).arg(constraint));
alterTable.exec();
returnValue = returnValue && (alterTable.numRowsAffected() > 0);
return returnValue;
}
void DataBaseManagement::bindString(const QString & name, const QSqlRecord & record, QSqlQuery & query)
{
if(!record.value(name).isNull())
@ -631,6 +676,14 @@ void DataBaseManagement::bindInt(const QString & name, const QSqlRecord & record
}
}
void DataBaseManagement::bindDouble(const QString & name, const QSqlRecord & record, QSqlQuery & query)
{
if(!record.value(name).isNull())
{
query.bindValue(":"+name,record.value(name).toDouble());
}
}
QString DataBaseManagement::checkValidDB(const QString & fullPath)
{
QSqlDatabase db = loadDatabaseFromFile(fullPath);
@ -646,7 +699,8 @@ QString DataBaseManagement::checkValidDB(const QString & fullPath)
}
db.close();
QSqlDatabase::removeDatabase(fullPath);
QSqlDatabase::removeDatabase(db.connectionName());
return versionString;
}
@ -681,11 +735,14 @@ int DataBaseManagement::compareVersions(const QString & v1, const QString v2)
return 0;
}
bool DataBaseManagement::updateToCurrentVersion(const QString & fullPath)
bool DataBaseManagement::updateToCurrentVersion(const QString & path)
{
bool pre7 = false;
bool pre7_1 = false;
bool pre8 = false;
bool pre9_5 = false;
QString fullPath = path + "/library.ydb";
if(compareVersions(DataBaseManagement::checkValidDB(fullPath),"7.0.0")<0)
pre7 = true;
@ -693,6 +750,8 @@ bool DataBaseManagement::updateToCurrentVersion(const QString & fullPath)
pre7_1 = true;
if(compareVersions(DataBaseManagement::checkValidDB(fullPath),"8.0.0")<0)
pre8 = true;
if(compareVersions(DataBaseManagement::checkValidDB(fullPath),"9.5.0")<0)
pre9_5 = true;
QSqlDatabase db = loadDatabaseFromFile(fullPath);
bool returnValue = false;
@ -704,7 +763,7 @@ bool DataBaseManagement::updateToCurrentVersion(const QString & fullPath)
updateVersion.bindValue(":version",VERSION);
updateVersion.exec();
if(updateVersion.numRowsAffected() > 0)
if(updateVersion.numRowsAffected() > 0)
returnValue = true;
if(pre7) //TODO: execute only if previous version was < 7.0
@ -721,7 +780,8 @@ bool DataBaseManagement::updateToCurrentVersion(const QString & fullPath)
<< "contrast INTEGER DEFAULT -1"
<< "gamma INTEGER DEFAULT -1";
returnValue = returnValue && addColumns("comic_info", columnDefs, db);
bool successAddingColumns = addColumns("comic_info", columnDefs, db);
returnValue = returnValue && successAddingColumns;
}
//TODO update hasBeenOpened value
@ -731,24 +791,83 @@ bool DataBaseManagement::updateToCurrentVersion(const QString & fullPath)
QStringList columnDefs;
columnDefs << "finished BOOLEAN DEFAULT 0"
<< "completed BOOLEAN DEFAULT 1";
returnValue = returnValue && addColumns("folder", columnDefs, db);
bool successAddingColumns = addColumns("folder", columnDefs, db);
returnValue = returnValue && successAddingColumns;
}
{//comic_info
QStringList columnDefs;
columnDefs << "comicVineID TEXT DEFAULT NULL";
returnValue = returnValue && addColumns("comic_info", columnDefs, db);
bool successAddingColumns = addColumns("comic_info", columnDefs, db);
returnValue = returnValue && successAddingColumns;
}
}
if(pre8)
{
returnValue = returnValue && createV8Tables(db);
bool successCreatingNewTables = createV8Tables(db);
returnValue = returnValue && successCreatingNewTables;
}
if(pre9_5)
{
{//folder
QStringList columnDefs;
//a full library update is needed after updating the table
columnDefs << "numChildren INTEGER";
columnDefs << "firstChildHash TEXT";
columnDefs << "customImage TEXT";
bool successAddingColumns = addColumns("folder", columnDefs, db);
returnValue = returnValue && successAddingColumns;
}
{//comic_info
QStringList columnDefs;
columnDefs << "lastTimeOpened INTEGER";
columnDefs << "coverSizeRatio REAL";
columnDefs << "originalCoverSize TEXT";
bool successAddingColumns = addColumns("comic_info", columnDefs, db);
returnValue = returnValue && successAddingColumns;
QSqlQuery queryIndexLastTimeOpened(db);
bool successCreatingIndex = queryIndexLastTimeOpened.exec("CREATE INDEX last_time_opened_index ON comic_info (lastTimeOpened)");
returnValue = returnValue && successCreatingIndex;
}
//update folders info
{
DBHelper::updateChildrenInfo(db);
}
{
QSqlQuery selectQuery(db);
selectQuery.prepare("SELECT id, hash FROM comic_info");
selectQuery.exec();
db.transaction();
QSqlQuery updateCoverInfo(db);
updateCoverInfo.prepare("UPDATE comic_info SET coverSizeRatio = :coverSizeRatio WHERE id = :id");
QImageReader thumbnail;
while (selectQuery.next())
{
thumbnail.setFileName(path % "/covers/" % selectQuery.value(1).toString() % ".jpg");
float coverSizeRatio = static_cast<float>(thumbnail.size().width()) / thumbnail.size().height();
updateCoverInfo.bindValue(":coverSizeRatio", coverSizeRatio);
updateCoverInfo.bindValue(":id", selectQuery.value(0));
updateCoverInfo.exec();
}
db.commit();
}
}
}
db.close();
QSqlDatabase::removeDatabase(fullPath);
QSqlDatabase::removeDatabase(db.connectionName());
return returnValue;
}

View File

@ -35,9 +35,11 @@ private:
QList<QString> dataBasesList;
static void bindString(const QString & name, const QSqlRecord & record, QSqlQuery & query);
static void bindInt(const QString & name, const QSqlRecord & record, QSqlQuery & query);
static void bindDouble(const QString & name, const QSqlRecord & record, QSqlQuery & query);
static void bindValuesFromRecord(const QSqlRecord & record, QSqlQuery & query);
static bool addColumns(const QString & tableName, const QStringList & columnDefs, const QSqlDatabase & db);
static bool addConstraint(const QString &tableName, const QString & constraint, const QSqlDatabase & db);
public:
DataBaseManagement();

View File

@ -184,6 +184,9 @@ QVariant FolderModel::data(const QModelIndex &index, int role) const
if(role == FolderModel::FinishedRole)
return item->data(FolderModel::Finished);
if(role == FolderModel::IdRole)
return item->id;
if (role != Qt::DisplayRole)
return QVariant();
@ -303,7 +306,7 @@ void FolderModel::setupModelData(QString path)
}
//selectQuery.finish();
db.close();
QSqlDatabase::removeDatabase(path);
QSqlDatabase::removeDatabase(db.connectionName());
endResetModel();
}
@ -315,7 +318,7 @@ void FolderModel::setupModelData(QSqlQuery &sqlquery, FolderItem *parent)
//el diccionario permitir<69> encontrar cualquier nodo del <20>rbol r<>pidamente, de forma que a<>adir un hijo a un padre sea O(1)
items.clear();
//se a<>ade el nodo 0
items.insert(parent->id,parent);
items.insert(parent->id,parent);
QSqlRecord record = sqlquery.record();
@ -425,7 +428,7 @@ void FolderModel::updateFolderCompletedStatus(const QModelIndexList &list, bool
}
db.commit();
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
emit dataChanged(index(list.first().row(),FolderModel::Name),index(list.last().row(),FolderModel::Completed));
}
@ -445,7 +448,7 @@ void FolderModel::updateFolderFinishedStatus(const QModelIndexList &list, bool s
}
db.commit();
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
emit dataChanged(index(list.first().row(),FolderModel::Name),index(list.last().row(),FolderModel::Completed));
}
@ -466,7 +469,7 @@ QStringList FolderModel::getSubfoldersNames(const QModelIndex &mi)
db.commit();
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
//TODO sort result))
qSort(result.begin(),result.end(),naturalSortLessThanCI);
@ -543,7 +546,7 @@ void FolderModel::fetchMoreFromDB(const QModelIndex &parent)
db.close();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
}
QModelIndex FolderModel::addFolderAtParent(const QString &folderName, const QModelIndex &parent)
@ -562,7 +565,8 @@ QModelIndex FolderModel::addFolderAtParent(const QString &folderName, const QMod
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
newFolder.id = DBHelper::insert(&newFolder, db);
QSqlDatabase::removeDatabase(_databasePath);
DBHelper::updateChildrenInfo(parentItem->id, db);
QSqlDatabase::removeDatabase(db.connectionName());
int destRow = 0;
@ -600,11 +604,18 @@ void FolderModel::deleteFolder(const QModelIndex &mi)
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
DBHelper::removeFromDB(&f,db);
QSqlDatabase::removeDatabase(_databasePath);
DBHelper::updateChildrenInfo(item->parent()->id, db);
QSqlDatabase::removeDatabase(db.connectionName());
endRemoveRows();
}
void FolderModel::updateFolderChildrenInfo(qulonglong folderId)
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
DBHelper::updateChildrenInfo(folderId, db);
QSqlDatabase::removeDatabase(db.connectionName());
}
//PROXY
@ -718,7 +729,7 @@ void FolderModelProxy::setupFilteredModelData()
}
//selectQuery.finish();
db.close();
QSqlDatabase::removeDatabase(model->_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
endResetModel();
}

View File

@ -127,11 +127,13 @@ public:
enum Roles {
FinishedRole = Qt::UserRole + 1,
CompletedRole
CompletedRole,
IdRole
};
public slots:
void deleteFolder(const QModelIndex & mi);
void updateFolderChildrenInfo(qulonglong folderId);
private:
void setupModelData( QSqlQuery &sqlquery, FolderItem *parent);

View File

@ -0,0 +1,44 @@
#include "reading_list.h"
ReadingList::ReadingList(const QString &name, qulonglong id, int ordering)
:name(name), id(id), ordering(ordering)
{
}
qulonglong ReadingList::getId() const
{
return id;
}
QString ReadingList::getName() const
{
return name;
}
int ReadingList::getOrdering() const
{
return ordering;
}
Label::Label(const QString &name, qulonglong id, YACReader::LabelColors colorid)
:name(name), id(id), colorid(colorid)
{
}
YACReader::LabelColors Label::getColorID() const
{
return colorid;
}
QString Label::getName() const
{
return name;
}
qulonglong Label::getId() const
{
return id;
}

View File

@ -0,0 +1,36 @@
#ifndef READING_LIST_H
#define READING_LIST_H
#include "yacreader_global.h"
class ReadingList
{
public:
ReadingList(const QString &name, qulonglong id, int ordering);
qulonglong getId() const;
QString getName() const;
int getOrdering() const;
private:
QString name;
qulonglong id;
int ordering;
};
class Label
{
public:
Label(const QString &name, qulonglong id, YACReader::LabelColors colorid);
YACReader::LabelColors getColorID() const;
QString getName() const;
qulonglong getId() const;
private:
QString name;
qulonglong id;
YACReader::LabelColors colorid;
};
#endif // READING_LIST_H

View File

@ -396,7 +396,7 @@ void ReadingListModel::addNewLabel(const QString &name, YACReader::LabelColors c
endInsertRows();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
}
void ReadingListModel::addReadingList(const QString &name)
@ -423,7 +423,7 @@ void ReadingListModel::addReadingList(const QString &name)
endInsertRows();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
}
void ReadingListModel::addReadingListAt(const QString &name, const QModelIndex &mi)
@ -452,7 +452,7 @@ void ReadingListModel::addReadingListAt(const QString &name, const QModelIndex &
endInsertRows();
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
}
bool ReadingListModel::isEditable(const QModelIndex &mi)
@ -523,7 +523,7 @@ void ReadingListModel::rename(const QModelIndex &mi, const QString &name)
emit dataChanged(index(mi.row(), 0), index(mi.row(), 0));
}
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
}
void ReadingListModel::deleteItem(const QModelIndex &mi)
@ -557,7 +557,7 @@ void ReadingListModel::deleteItem(const QModelIndex &mi)
DBHelper::removeLabelFromDB(item->getId(), db);
}
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
endRemoveRows();
}
@ -746,7 +746,7 @@ void ReadingListModel::reorderingChildren(QList<ReadingListItem *> children)
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
DBHelper::reasignOrderToSublists(childrenIds, db);
QSqlDatabase::removeDatabase(_databasePath);
QSqlDatabase::removeDatabase(db.connectionName());
}
bool ReadingListModel::rowIsSpecialList(int row, const QModelIndex &parent) const

View File

@ -14,6 +14,7 @@
#include <limits>
#include "reading_list.h"
#include "library_item.h"
#include "comic_db.h"
#include "data_base_management.h"
@ -39,7 +40,7 @@ QList<LibraryItem *> DBHelper::getFolderSubfoldersFromLibrary(qulonglong library
QList<LibraryItem *> list = DBHelper::getFoldersFromParent(folderId,db,false);
db.close();
QSqlDatabase::removeDatabase(libraryPath);
QSqlDatabase::removeDatabase(db.connectionName());
return list;
}
QList<LibraryItem *> DBHelper::getFolderComicsFromLibrary(qulonglong libraryId, qulonglong folderId)
@ -55,9 +56,41 @@ QList<LibraryItem *> DBHelper::getFolderComicsFromLibrary(qulonglong libraryId,
QList<LibraryItem *> list = DBHelper::getComicsFromParent(folderId,db,sort);
db.close();
QSqlDatabase::removeDatabase(libraryPath);
QSqlDatabase::removeDatabase(db.connectionName());
return list;
}
quint32 DBHelper::getNumChildrenFromFolder(qulonglong libraryId, qulonglong folderId)
{
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
quint32 result = 0;
{
QSqlQuery selectQuery(db);
selectQuery.prepare("SELECT count(*) FROM folder WHERE parentId = :parentId and id <> 1");
selectQuery.bindValue(":parentId", folderId);
selectQuery.exec();
result += selectQuery.record().value(0).toULongLong();
}
{
QSqlQuery selectQuery(db);
selectQuery.prepare("SELECT count(*) FROM comic c WHERE c.parentId = :parentId");
selectQuery.bindValue(":parentId", folderId);
selectQuery.exec();
result += selectQuery.record().value(0).toULongLong();
}
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
return result;
}
qulonglong DBHelper::getParentFromComicFolderId(qulonglong libraryId, qulonglong id)
{
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
@ -66,7 +99,7 @@ qulonglong DBHelper::getParentFromComicFolderId(qulonglong libraryId, qulonglong
Folder f = DBHelper::loadFolder(id,db);
db.close();
QSqlDatabase::removeDatabase(libraryPath);
QSqlDatabase::removeDatabase(db.connectionName());
return f.parentId;
}
ComicDB DBHelper::getComicInfo(qulonglong libraryId, qulonglong id)
@ -77,7 +110,7 @@ ComicDB DBHelper::getComicInfo(qulonglong libraryId, qulonglong id)
ComicDB comic = DBHelper::loadComic(id,db);
db.close();
QSqlDatabase::removeDatabase(libraryPath);
QSqlDatabase::removeDatabase(db.connectionName());
return comic;
}
@ -88,7 +121,7 @@ QList<ComicDB> DBHelper::getSiblings(qulonglong libraryId, qulonglong parentId)
QList<ComicDB> comics = DBHelper::getSortedComicsFromParent(parentId,db);
db.close();
QSqlDatabase::removeDatabase(libraryPath);
QSqlDatabase::removeDatabase(db.connectionName());
return comics;
}
@ -107,13 +140,12 @@ QString DBHelper::getFolderName(qulonglong libraryId, qulonglong id)
if(selectQuery.next())
{
QSqlRecord record = selectQuery.record();
name = record.value(0).toString();
name = selectQuery.value(0).toString();
}
}
db.close();
QSqlDatabase::removeDatabase(libraryPath);
QSqlDatabase::removeDatabase(db.connectionName());
return name;
}
QList<QString> DBHelper::getLibrariesNames()
@ -126,14 +158,235 @@ QString DBHelper::getLibraryName(int id)
{
return getLibraries().getName(id);
}
QList<ComicDB> DBHelper::getLabelComics(qulonglong libraryId, qulonglong labelId)
{
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
QList<ComicDB> list;
{
QSqlQuery selectQuery(db);
selectQuery.prepare("SELECT c.id,c.fileName,ci.title,ci.currentPage,ci.numPages,ci.hash,ci.read "
"FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) "
"INNER JOIN comic_label cl ON (c.id == cl.comic_id) "
"WHERE cl.label_id = :parentLabelId "
"ORDER BY cl.ordering");
selectQuery.bindValue(":parentLabelId", labelId);
selectQuery.exec();
while (selectQuery.next())
{
ComicDB comic;
comic.id = selectQuery.value(0).toULongLong();
comic.parentId = labelId;
comic.name = selectQuery.value(1).toString();
comic.info.title = selectQuery.value(2).toString();
comic.info.currentPage = selectQuery.value(3).toInt();
comic.info.numPages = selectQuery.value(4).toInt();
comic.info.hash = selectQuery.value(5).toString();
comic.info.read = selectQuery.value(6).toBool();
list.append(comic);
}
db.close();
}
//TODO ?
//QSqlDatabase::removeDatabase(db.connectionName());
return list;
}
QList<ComicDB> DBHelper::getFavorites(qulonglong libraryId)
{
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
QList<ComicDB> list;
const int FAV_ID = 1;
{
QSqlQuery selectQuery(db);
selectQuery.prepare("SELECT c.id,c.fileName,ci.title,ci.currentPage,ci.numPages,ci.hash,ci.read "
"FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) "
"INNER JOIN comic_default_reading_list cdrl ON (c.id == cdrl.comic_id) "
"WHERE cdrl.default_reading_list_id = :parentDefaultListId "
"ORDER BY cdrl.ordering");
selectQuery.bindValue(":parentDefaultListId", FAV_ID);
selectQuery.exec();
while (selectQuery.next())
{
ComicDB comic;
comic.id = selectQuery.value(0).toULongLong();
comic.parentId = FAV_ID;
comic.name = selectQuery.value(1).toString();
comic.info.title = selectQuery.value(2).toString();
comic.info.currentPage = selectQuery.value(3).toInt();
comic.info.numPages = selectQuery.value(4).toInt();
comic.info.hash = selectQuery.value(5).toString();
comic.info.read = selectQuery.value(6).toBool();
list.append(comic);
}
db.close();
}
//TODO ?
//QSqlDatabase::removeDatabase(db.connectionName());
return list;
}
QList<ComicDB> DBHelper::getReading(qulonglong libraryId)
{
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
QList<ComicDB> list;
{
QSqlQuery selectQuery(db);
selectQuery.prepare("SELECT c.id,c.parentId,c.fileName,ci.title,ci.currentPage,ci.numPages,ci.hash,ci.read,ci.coverSizeRatio "
"FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) "
"WHERE ci.hasBeenOpened = 1 AND ci.read = 0 "
"ORDER BY ci.lastTimeOpened DESC");
selectQuery.exec();
while (selectQuery.next())
{
ComicDB comic;
comic.id = selectQuery.value(0).toULongLong();
comic.parentId = selectQuery.value(1).toULongLong();
comic.name = selectQuery.value(2).toString();
comic.info.title = selectQuery.value(3).toString();
comic.info.currentPage = selectQuery.value(4).toInt();
comic.info.numPages = selectQuery.value(5).toInt();
comic.info.hash = selectQuery.value(6).toString();
comic.info.read = selectQuery.value(7).toBool();
comic.info.coverSizeRatio = selectQuery.value(8).toFloat();
list.append(comic);
}
db.close();
}
//TODO ?
//QSqlDatabase::removeDatabase(db.connectionName());
return list;
}
QList<ReadingList> DBHelper::getReadingLists(qulonglong libraryId)
{
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
QList<ReadingList> list;
QSqlQuery selectQuery("SELECT * from reading_list WHERE parentId IS NULL ORDER BY name DESC",db);
selectQuery.exec();
QSqlRecord record = selectQuery.record();
int name = record.indexOf("name");
int id = record.indexOf("id");
int ordering = record.indexOf("ordering");
while (selectQuery.next())
{
ReadingList item(selectQuery.value(name).toString(), selectQuery.value(id).toLongLong(),selectQuery.value(ordering).toInt());
if(list.isEmpty())
{
list.append(item);
}
else
{
int i= 0;
while(i<list.length() && naturalSortLessThanCI(list.at(i).getName(),item.getName()))
i++;
list.insert(i,item);
}
}
//TODO ?
//QSqlDatabase::removeDatabase(db.connectionName());
return list;
}
QList<ComicDB> DBHelper::getReadingListFullContent(qulonglong libraryId, qulonglong readingListId)
{
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
QList<ComicDB> list;
{
QList<qulonglong> ids;
ids << readingListId;
QSqlQuery subfolders(db);
subfolders.prepare("SELECT id "
"FROM reading_list "
"WHERE parentId = :parentId "
"ORDER BY ordering ASC");
subfolders.bindValue(":parentId", readingListId);
subfolders.exec();
while(subfolders.next())
ids << subfolders.value(0).toULongLong();
foreach(qulonglong id, ids)
{
QSqlQuery selectQuery(db);
selectQuery.prepare("SELECT c.id,c.parentId,c.fileName,ci.title,ci.currentPage,ci.numPages,ci.hash,ci.read "
"FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) "
"INNER JOIN comic_reading_list crl ON (c.id == crl.comic_id) "
"WHERE crl.reading_list_id = :parentReadingList "
"ORDER BY crl.ordering");
selectQuery.bindValue(":parentReadingList", id);
selectQuery.exec();
while (selectQuery.next())
{
ComicDB comic;
comic.id = selectQuery.value(0).toULongLong();
comic.parentId = selectQuery.value(1).toULongLong();
comic.name = selectQuery.value(2).toString();
comic.info.title = selectQuery.value(3).toString();
comic.info.currentPage = selectQuery.value(4).toInt();
comic.info.numPages = selectQuery.value(5).toInt();
comic.info.hash = selectQuery.value(6).toString();
comic.info.read = selectQuery.value(7).toBool();
list.append(comic);
}
}
}
//TODO ?
//QSqlDatabase::removeDatabase(db.connectionName());
return list;
}
//objects management
//deletes
void DBHelper::removeFromDB(LibraryItem * item, QSqlDatabase & db)
{
if(item->isDir())
DBHelper::removeFromDB(dynamic_cast<Folder *>(item),db);
DBHelper::removeFromDB(dynamic_cast<Folder *>(item),db);
else
DBHelper::removeFromDB(dynamic_cast<ComicDB *>(item),db);
DBHelper::removeFromDB(dynamic_cast<ComicDB *>(item),db);
}
void DBHelper::removeFromDB(Folder * folder, QSqlDatabase & db)
{
@ -238,7 +491,7 @@ void DBHelper::update(qulonglong libraryId, ComicInfo & comicInfo)
DBHelper::update(&comicInfo,db);
db.close();
QSqlDatabase::removeDatabase(libraryPath);
QSqlDatabase::removeDatabase(db.connectionName());
}
void DBHelper::update(ComicInfo * comicInfo, QSqlDatabase & db)
@ -296,7 +549,13 @@ void DBHelper::update(ComicInfo * comicInfo, QSqlDatabase & db)
"rating = :rating,"
//new 7.1 fields
"comicVineID = :comicVineID"
"comicVineID = :comicVineID,"
//new 9.5 fields
"lastTimeOpened = :lastTimeOpened,"
"coverSizeRatio = :coverSizeRatio,"
"originalCoverSize = :originalCoverSize"
//--
" WHERE id = :id ");
@ -351,6 +610,11 @@ void DBHelper::update(ComicInfo * comicInfo, QSqlDatabase & db)
updateComicInfo.bindValue(":comicVineID", comicInfo->comicVineID);
updateComicInfo.bindValue(":lastTimeOpened", comicInfo->lastTimeOpened);
updateComicInfo.bindValue(":coverSizeRatio", comicInfo->coverSizeRatio);
updateComicInfo.bindValue(":originalCoverSize", comicInfo->originalCoverSize);
updateComicInfo.exec();
}
@ -379,6 +643,51 @@ void DBHelper::update(const Folder & folder, QSqlDatabase &db)
updateFolderInfo.exec();
}
void DBHelper::updateChildrenInfo(const Folder & folder, QSqlDatabase & db)
{
QSqlQuery updateFolderInfo(db);
updateFolderInfo.prepare("UPDATE folder SET "
"numChildren = :numChildren, "
"firstChildHash = :firstChildHash "
"WHERE id = :id ");
updateFolderInfo.bindValue(":numChildren", folder.getNumChildren());
updateFolderInfo.bindValue(":firstChildHash", folder.getFirstChildHash());
updateFolderInfo.bindValue(":id", folder.id);
updateFolderInfo.exec();
}
void DBHelper::updateChildrenInfo(qulonglong folderId, QSqlDatabase & db)
{
QList<LibraryItem *> subfolders = DBHelper::getFoldersFromParent(folderId,db,false);
QList<LibraryItem *> comics = DBHelper::getComicsFromParent(folderId,db,true);
ComicDB * firstComic = NULL;
if(comics.count() > 0)
firstComic = static_cast<ComicDB *>(comics.first());
QSqlQuery updateFolderInfo(db);
updateFolderInfo.prepare("UPDATE folder SET "
"numChildren = :numChildren, "
"firstChildHash = :firstChildHash "
"WHERE id = :id ");
updateFolderInfo.bindValue(":numChildren", subfolders.count() + comics.count());
updateFolderInfo.bindValue(":firstChildHash", firstComic != NULL ? firstComic->info.hash : "");
updateFolderInfo.bindValue(":id", folderId);
updateFolderInfo.exec();
}
void DBHelper::updateChildrenInfo(QSqlDatabase & db)
{
QSqlQuery selectQuery(db); //TODO check
selectQuery.prepare("SELECT id FROM folder");
selectQuery.exec();
while (selectQuery.next())
{
DBHelper::updateChildrenInfo(selectQuery.value(0).toULongLong(), db);
}
}
void DBHelper::updateProgress(qulonglong libraryId, const ComicInfo &comicInfo)
{
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
@ -386,13 +695,28 @@ void DBHelper::updateProgress(qulonglong libraryId, const ComicInfo &comicInfo)
ComicDB comic = DBHelper::loadComic(comicInfo.id,db);
comic.info.currentPage = comicInfo.currentPage;
comic.info.hasBeenOpened = comicInfo.currentPage > 0 || comic.info.hasBeenOpened;
comic.info.read = comic.info.read || comic.info.currentPage == comic.info.numPages;
DBHelper::updateReadingRemoteProgress(comic.info,db);
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
}
void DBHelper::setComicAsReading(qulonglong libraryId, const ComicInfo &comicInfo)
{
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
ComicDB comic = DBHelper::loadComic(comicInfo.id,db);
comic.info.hasBeenOpened = true;
comic.info.read = comic.info.read || comic.info.currentPage == comic.info.numPages;
DBHelper::updateReadingRemoteProgress(comic.info,db);
db.close();
QSqlDatabase::removeDatabase(libraryPath);
QSqlDatabase::removeDatabase(db.connectionName());
}
void DBHelper::updateReadingRemoteProgress(const ComicInfo &comicInfo, QSqlDatabase &db)
@ -402,12 +726,14 @@ void DBHelper::updateReadingRemoteProgress(const ComicInfo &comicInfo, QSqlDatab
"read = :read, "
"currentPage = :currentPage, "
"hasBeenOpened = :hasBeenOpened, "
"lastTimeOpened = :lastTimeOpened, "
"rating = :rating"
" WHERE id = :id ");
updateComicInfo.bindValue(":read", comicInfo.read?1:0);
updateComicInfo.bindValue(":currentPage", comicInfo.currentPage);
updateComicInfo.bindValue(":hasBeenOpened", comicInfo.hasBeenOpened?1:0);
updateComicInfo.bindValue(":lastTimeOpened", QDateTime::currentSecsSinceEpoch());
updateComicInfo.bindValue(":id", comicInfo.id);
updateComicInfo.bindValue(":rating", comicInfo.rating);
updateComicInfo.exec();
@ -427,12 +753,15 @@ void DBHelper::updateFromRemoteClient(qulonglong libraryId,const ComicInfo & com
{
if(comicInfo.currentPage > 0)
{
comic.info.currentPage = comicInfo.currentPage;
if(comic.info.currentPage == comic.info.numPages)
comic.info.read = true;
comic.info.currentPage = comicInfo.currentPage;
comic.info.hasBeenOpened = true;
if (comic.info.lastTimeOpened.toULongLong() < comicInfo.lastTimeOpened.toULongLong())
comic.info.lastTimeOpened = comicInfo.lastTimeOpened;
}
if(comicInfo.rating > 0)
@ -442,7 +771,43 @@ void DBHelper::updateFromRemoteClient(qulonglong libraryId,const ComicInfo & com
}
db.close();
QSqlDatabase::removeDatabase(libraryPath);
QSqlDatabase::removeDatabase(db.connectionName());
}
void DBHelper::updateFromRemoteClientWithHash(const ComicInfo & comicInfo)
{
YACReaderLibraries libraries = DBHelper::getLibraries();
QStringList names = libraries.getNames();
foreach (QString name, names) {
QString libraryPath = DBHelper::getLibraries().getPath(libraries.getId(name));
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
ComicInfo info = loadComicInfo(comicInfo.hash, db);
if(comicInfo.currentPage > 0)
{
info.currentPage = comicInfo.currentPage;
if(info.currentPage == info.numPages)
info.read = true;
info.hasBeenOpened = true;
if (info.lastTimeOpened.toULongLong() < comicInfo.lastTimeOpened.toULongLong())
info.lastTimeOpened = comicInfo.lastTimeOpened;
}
if(comicInfo.rating > 0)
info.rating = comicInfo.rating;
DBHelper::update(&info, db);
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
}
}
void DBHelper::renameLabel(qulonglong id, const QString &name, QSqlDatabase &db)
@ -492,7 +857,7 @@ void DBHelper::reasignOrderToComicsInFavorites(QList<qulonglong> comicIds, QSqlD
QSqlQuery updateOrdering(db);
updateOrdering.prepare("UPDATE comic_default_reading_list SET "
"ordering = :ordering "
"WHERE comic_id = :comic_id AND default_reading_list_id = 0");
"WHERE comic_id = :comic_id AND default_reading_list_id = 1");
db.transaction();
int order = 0;
foreach(qulonglong id, comicIds)
@ -554,6 +919,7 @@ qulonglong DBHelper::insert(Folder * folder, QSqlDatabase & db)
query.bindValue(":name", folder->name);
query.bindValue(":path", folder->path);
query.exec();
return query.lastInsertId().toULongLong();
}
@ -562,10 +928,12 @@ qulonglong DBHelper::insert(ComicDB * comic, QSqlDatabase & db)
if(!comic->info.existOnDb)
{
QSqlQuery comicInfoInsert(db);
comicInfoInsert.prepare("INSERT INTO comic_info (hash,numPages) "
"VALUES (:hash,:numPages)");
comicInfoInsert.prepare("INSERT INTO comic_info (hash,numPages,coverSizeRatio,originalCoverSize) "
"VALUES (:hash,:numPages,:coverSizeRatio,:originalCoverSize)");
comicInfoInsert.bindValue(":hash", comic->info.hash);
comicInfoInsert.bindValue(":numPages", comic->info.numPages);
comicInfoInsert.bindValue(":coverSizeRatio", comic->info.coverSizeRatio);
comicInfoInsert.bindValue(":originalCoverSize", comic->info.originalCoverSize);
comicInfoInsert.exec();
comic->info.id =comicInfoInsert.lastInsertId().toULongLong();
comic->_hasCover = false;
@ -581,6 +949,7 @@ qulonglong DBHelper::insert(ComicDB * comic, QSqlDatabase & db)
query.bindValue(":name", comic->name);
query.bindValue(":path", comic->path);
query.exec();
return query.lastInsertId().toULongLong();
}
@ -638,6 +1007,8 @@ void DBHelper::insertComicsInFavorites(const QList<ComicDB> &comicsList, QSqlDat
query.exec();
}
QLOG_TRACE() << query.lastError();
db.commit();
}
@ -662,6 +1033,8 @@ void DBHelper::insertComicsInLabel(const QList<ComicDB> &comicsList, qulonglong
query.exec();
}
QLOG_TRACE() << query.lastError();
db.commit();
}
@ -703,13 +1076,22 @@ QList<LibraryItem *> DBHelper::getFoldersFromParent(qulonglong parentId, QSqlDat
int name = record.indexOf("name");
int path = record.indexOf("path");
int id = record.indexOf("id");
int numChildren = record.indexOf("numChildren");
int firstChildHash = record.indexOf("firstChildHash");
int customImage = record.indexOf("customImage");
Folder * currentItem;
while (selectQuery.next())
{
//TODO sort by sort indicator and name
currentItem = new Folder(selectQuery.value(id).toULongLong(),parentId,selectQuery.value(name).toString(),selectQuery.value(path).toString());
int lessThan = 0;
currentItem = new Folder(selectQuery.value(id).toULongLong(),parentId,selectQuery.value(name).toString(),selectQuery.value(path).toString());
if(!selectQuery.value(numChildren).isNull() && selectQuery.value(numChildren).isValid())
currentItem->setNumChildren(selectQuery.value(numChildren).toInt());
currentItem->setFirstChildHash(selectQuery.value(firstChildHash).toString());
currentItem->setCustomImage(selectQuery.value(customImage).toString());
int lessThan = 0;
if(list.isEmpty() || !sort)
list.append(currentItem);
@ -721,7 +1103,7 @@ QList<LibraryItem *> DBHelper::getFoldersFromParent(qulonglong parentId, QSqlDat
QList<LibraryItem *>::iterator i;
i = list.end();
i--;
while ((0 > (lessThan = naturalSortLessThanCI(nameCurrent,nameLast))) && i != list.begin())
while ((0 > (lessThan = naturalCompare(nameCurrent,nameLast,Qt::CaseInsensitive))) && i != list.begin())
{
i--;
nameLast = (*i)->name;
@ -806,6 +1188,11 @@ QList<ComicDB> DBHelper::getSortedComicsFromParent(qulonglong parentId, QSqlData
int comicVineID = record.indexOf("comicVineID");
int lastTimeOpened = record.indexOf("lastTimeOpened");
int coverSizeRatio = record.indexOf("coverSizeRatio");
int originalCoverSize = record.indexOf("originalCoverSize");
ComicDB currentItem;
while (selectQuery.next())
{
@ -866,6 +1253,11 @@ QList<ComicDB> DBHelper::getSortedComicsFromParent(qulonglong parentId, QSqlData
currentItem.info.comicVineID = selectQuery.value(comicVineID);
currentItem.info.lastTimeOpened = selectQuery.value(lastTimeOpened);
currentItem.info.coverSizeRatio = selectQuery.value(coverSizeRatio);
currentItem.info.originalCoverSize = selectQuery.value(originalCoverSize);
currentItem.info.existOnDb = true;
list.append(currentItem);
@ -929,6 +1321,63 @@ QList<LibraryItem *> DBHelper::getComicsFromParent(qulonglong parentId, QSqlData
return list;
}
QList<Label> DBHelper::getLabels(qulonglong libraryId)
{
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
QSqlQuery selectQuery("SELECT * FROM label ORDER BY ordering,name",db); //TODO add some kind of
QList<Label> labels;
QSqlRecord record = selectQuery.record();
int name = record.indexOf("name");
int color = record.indexOf("color");
int id = record.indexOf("id");
int ordering = record.indexOf("ordering");
while(selectQuery.next())
{
Label item(selectQuery.value(name).toString(),
selectQuery.value(id).toLongLong(),
static_cast<YACReader::LabelColors>(selectQuery.value(ordering).toInt()));
if(labels.isEmpty())
{
labels << item;
}
else
{
int i = 0;
while (i < labels.count() && (labels.at(i).getColorID() < item.getColorID()) )
i++;
if(i < labels.count())
{
if(labels.at(i).getColorID() == item.getColorID()) //sort by name
{
while( i < labels.count() && labels.at(i).getColorID() == item.getColorID() && naturalSortLessThanCI(labels.at(i).getName(),item.getName()))
i++;
}
}
if(i >= labels.count())
{
labels << item;
}
else
{
labels.insert(i,item);
}
}
}
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
return labels;
}
//loads
Folder DBHelper::loadFolder(qulonglong id, QSqlDatabase & db)
{
@ -948,6 +1397,9 @@ Folder DBHelper::loadFolder(qulonglong id, QSqlDatabase & db)
int path = record.indexOf("path");
int finished = record.indexOf("finished");
int completed = record.indexOf("completed");
int numChildren = record.indexOf("numChildren");
int firstChildHash = record.indexOf("firstChildHash");
int customImage = record.indexOf("customImage");
if(query.next())
{
@ -955,9 +1407,16 @@ Folder DBHelper::loadFolder(qulonglong id, QSqlDatabase & db)
folder.name = query.value(name).toString();
folder.path = query.value(path).toString();
folder.knownId = true;
//new 7.1
folder.setFinished(query.value(finished).toBool());
folder.setCompleted(query.value(completed).toBool());
//new 9.5
if(!query.value(numChildren).isNull() && query.value(numChildren).isValid())
folder.setNumChildren(query.value(numChildren).toInt());
folder.setFirstChildHash(query.value(firstChildHash).toString());
folder.setCustomImage(query.value(customImage).toString());
}
return folder;
@ -980,6 +1439,9 @@ Folder DBHelper::loadFolder(const QString &folderName, qulonglong parentId, QSql
int path = record.indexOf("path");
int finished = record.indexOf("finished");
int completed = record.indexOf("completed");
int numChildren = record.indexOf("numChildren");
int firstChildHash = record.indexOf("firstChildHash");
int customImage = record.indexOf("customImage");
folder.parentId = parentId;
if(query.next())
@ -988,9 +1450,16 @@ Folder DBHelper::loadFolder(const QString &folderName, qulonglong parentId, QSql
folder.name = query.value(name).toString();
folder.path = query.value(path).toString();
folder.knownId = true;
//new 7.1
folder.setFinished(query.value(finished).toBool());
folder.setCompleted(query.value(completed).toBool());
//new 9.5
if(!query.value(numChildren).isNull() && query.value(numChildren).isValid())
folder.setNumChildren(query.value(numChildren).toInt());
folder.setFirstChildHash(query.value(firstChildHash).toString());
folder.setCustomImage(query.value(customImage).toString());
}
return folder;
@ -1108,6 +1577,11 @@ ComicInfo DBHelper::loadComicInfo(QString hash, QSqlDatabase & db)
int comicVineID = record.indexOf("comicVineID");
int lastTimeOpened = record.indexOf("lastTimeOpened");
int coverSizeRatio = record.indexOf("coverSizeRatio");
int originalCoverSize = record.indexOf("originalCoverSize");
if(findComicInfo.next())
{
comicInfo.hash = hash;
@ -1126,7 +1600,6 @@ ComicInfo DBHelper::loadComicInfo(QString hash, QSqlDatabase & db)
comicInfo.gamma = findComicInfo.value(gamma).toInt();
comicInfo.rating = findComicInfo.value(rating).toInt();
//--
comicInfo.title = findComicInfo.value(title);
comicInfo.numPages = findComicInfo.value(numPages);
@ -1162,6 +1635,13 @@ ComicInfo DBHelper::loadComicInfo(QString hash, QSqlDatabase & db)
comicInfo.comicVineID = findComicInfo.value(comicVineID);
//new 9.5 fields
comicInfo.lastTimeOpened = findComicInfo.value(lastTimeOpened);
comicInfo.coverSizeRatio = findComicInfo.value(coverSizeRatio);
comicInfo.originalCoverSize = findComicInfo.value(originalCoverSize);
//--
comicInfo.existOnDb = true;
}
else

View File

@ -9,11 +9,13 @@ class QString;
class ComicDB;
class Folder;
class LibraryItem;
class Label;
class QSqlDatabase;
class ComicInfo;
class QSqlRecord;
class QSqlQuery;
class YACReaderLibraries;
class ReadingList;
class DBHelper
{
@ -23,18 +25,24 @@ public:
static QList<LibraryItem *> getFolderSubfoldersFromLibrary(qulonglong libraryId, qulonglong folderId);
static QList<LibraryItem *> getFolderComicsFromLibrary(qulonglong libraryId, qulonglong folderId);
static QList<LibraryItem *> getFolderComicsFromLibrary(qulonglong libraryId, qulonglong folderId, bool sort);
static quint32 getNumChildrenFromFolder(qulonglong libraryId, qulonglong folderId);
static qulonglong getParentFromComicFolderId(qulonglong libraryId, qulonglong id);
static ComicDB getComicInfo(qulonglong libraryId, qulonglong id);
static QList<ComicDB> getSiblings(qulonglong libraryId, qulonglong parentId);
static QString getFolderName(qulonglong libraryId, qulonglong id);
static QList<QString> getLibrariesNames();
static QString getLibraryName(int id);
static QList<ComicDB> getLabelComics(qulonglong libraryId, qulonglong labelId);
static QList<ComicDB> getFavorites(qulonglong libraryId);
static QList<ComicDB> getReading(qulonglong libraryId);
static QList<ReadingList> getReadingLists(qulonglong libraryId);
static QList<ComicDB> getReadingListFullContent(qulonglong libraryId, qulonglong readingListId);
//objects management
//deletes
static void removeFromDB(LibraryItem * item, QSqlDatabase & db);
static void removeFromDB(Folder * folder, QSqlDatabase & db);
static void removeFromDB(ComicDB * comic, QSqlDatabase & db);
static void removeFromDB(LibraryItem * item, QSqlDatabase & db);
static void removeFromDB(Folder * folder, QSqlDatabase & db);
static void removeFromDB(ComicDB * comic, QSqlDatabase & db);
static void removeLabelFromDB(qulonglong id, QSqlDatabase & db);
static void removeListFromDB(qulonglong id, QSqlDatabase & db);
//logic deletes
@ -42,8 +50,8 @@ public:
static void deleteComicsFromLabel(const QList<ComicDB> & comicsList, qulonglong labelId, QSqlDatabase & db);
static void deleteComicsFromReadingList(const QList<ComicDB> & comicsList, qulonglong readingListId, QSqlDatabase & db);
//inserts
static qulonglong insert(Folder * folder, QSqlDatabase & db);
static qulonglong insert(ComicDB * comic, QSqlDatabase & db);
static qulonglong insert(Folder * folder, QSqlDatabase & db);
static qulonglong insert(ComicDB * comic, QSqlDatabase & db);
static qulonglong insertLabel(const QString & name, YACReader::LabelColors color , QSqlDatabase & db);
static qulonglong insertReadingList(const QString & name, QSqlDatabase & db);
static qulonglong insertReadingSubList(const QString & name, qulonglong parentId, int ordering, QSqlDatabase & db);
@ -56,9 +64,14 @@ public:
static void update(ComicInfo * comicInfo, QSqlDatabase & db);
static void updateRead(ComicInfo * comicInfo, QSqlDatabase & db);
static void update(const Folder & folder, QSqlDatabase & db);
static void updateChildrenInfo(const Folder & folder, QSqlDatabase & db);
static void updateChildrenInfo(qulonglong folderId, QSqlDatabase & db);
static void updateChildrenInfo(QSqlDatabase & db);
static void updateProgress(qulonglong libraryId,const ComicInfo & comicInfo);
static void setComicAsReading(qulonglong libraryId, const ComicInfo &comicInfo);
static void updateReadingRemoteProgress(const ComicInfo & comicInfo, QSqlDatabase & db);
static void updateFromRemoteClient(qulonglong libraryId,const ComicInfo & comicInfo);
static void updateFromRemoteClientWithHash(const ComicInfo & comicInfo);
static void renameLabel(qulonglong id, const QString & name, QSqlDatabase & db);
static void renameList(qulonglong id, const QString & name, QSqlDatabase & db);
static void reasignOrderToSublists(QList<qulonglong> ids, QSqlDatabase & db);
@ -69,7 +82,9 @@ public:
static QList<LibraryItem *> getFoldersFromParent(qulonglong parentId, QSqlDatabase & db, bool sort = true);
static QList<ComicDB> getSortedComicsFromParent(qulonglong parentId, QSqlDatabase & db);
static QList<LibraryItem *> getComicsFromParent(qulonglong parentId, QSqlDatabase & db, bool sort = true);
//load
static QList<Label> getLabels(qulonglong libraryId);
//load
static Folder loadFolder(qulonglong id, QSqlDatabase & db);
static Folder loadFolder(const QString & folderName, qulonglong parentId, QSqlDatabase & db);
static ComicDB loadComic(qulonglong id, QSqlDatabase & db);

View File

@ -11,6 +11,7 @@
#include "comic_db.h"
#include "yacreader_comics_selection_helper.h"
#include "yacreader_comic_info_helper.h"
#include "current_comic_view_helper.h"
//values relative to visible cells
const unsigned int YACREADER_MIN_GRID_ZOOM_WIDTH = 156;
@ -30,7 +31,7 @@ const unsigned int YACREADER_MIN_ITEM_WIDTH = YACREADER_MIN_COVER_WIDTH;
GridComicsView::GridComicsView(QWidget *parent) :
ComicsView(parent)
ComicsView(parent), filterEnabled(false)
{
settings = new QSettings(YACReader::getSettingsPath()+"/YACReaderLibrary.ini", QSettings::IniFormat, this);
settings->beginGroup("libraryConfig");
@ -161,6 +162,7 @@ GridComicsView::GridComicsView(QWidget *parent) :
ctxt->setContextProperty("dummyValue", true);
ctxt->setContextProperty("dragManager", this);
ctxt->setContextProperty("dropManager", this);
ctxt->setContextProperty("comicOpener", this);
bool showInfo = settings->value(COMICS_GRID_SHOW_INFO, false).toBool();
ctxt->setContextProperty("showInfo", showInfo);
@ -247,6 +249,8 @@ void GridComicsView::setModel(ComicModel *model)
ComicsView::setModel(model);
setCurrentComicIfNeeded();
selectionHelper->setModel(model);
comicInfoHelper->setModel(model);
@ -265,12 +269,18 @@ void GridComicsView::setModel(ComicModel *model)
updateBackgroundConfig();
selectionHelper->clear();
if(model->rowCount()>0)
{
setCurrentIndex(model->index(0,0));
if(showInfoAction->isChecked())
updateInfoForIndex(0);
}
//If the currentComicView was hidden before showing it sometimes the scroll view doesn't show it
//this is a hacky solution...
QTimer::singleShot(0, this, SLOT(resetScroll()));
}
void GridComicsView::updateBackgroundConfig()
@ -370,7 +380,16 @@ void GridComicsView::updateConfig(QSettings *settings)
void GridComicsView::enableFilterMode(bool enabled)
{
Q_UNUSED(enabled);
filterEnabled = enabled;
QQmlContext *ctxt = view->rootContext();
if (enabled) {
ctxt->setContextProperty("showCurrentComic", false);
ctxt->setContextProperty("currentComic", nullptr);
} else {
setCurrentComicIfNeeded();
}
}
void GridComicsView::selectAll()
@ -383,6 +402,11 @@ void GridComicsView::selectIndex(int index)
selectionHelper->selectIndex(index);
}
void GridComicsView::triggerOpenCurrentComic()
{
emit openComic(currentComic);
}
void GridComicsView::rate(int index, int rating)
{
model->updateRating(rating,model->index(index,0));
@ -424,6 +448,36 @@ void GridComicsView::dummyUpdater()
ctxt->setContextProperty("dummyValue", true);
}
void GridComicsView::setCurrentComicIfNeeded()
{
bool found;
currentComic = currentComicFromModel(model, found);
QQmlContext *ctxt = view->rootContext();
if (found && filterEnabled == false) {
ctxt->setContextProperty("currentComic", &currentComic);
ctxt->setContextProperty("currentComicInfo", &(currentComic.info));
ctxt->setContextProperty("showCurrentComic", true);
}
else
{
ctxt->setContextProperty("currentComic", &currentComic);
ctxt->setContextProperty("currentComicInfo", &(currentComic.info));
ctxt->setContextProperty("showCurrentComic", false);
//ctxt->setContextProperty("currentComic", nullptr);
}
}
void GridComicsView::resetScroll()
{
QObject *rootObject = dynamic_cast<QObject*>(view->rootObject());
QObject *scrollView = rootObject->findChild<QObject*>("topScrollView", Qt::FindChildrenRecursively);
QMetaObject::invokeMethod(scrollView, "scrollToOrigin");
}
QSize GridComicsView::sizeHint()
{
return QSize(1280,768);
@ -441,6 +495,11 @@ QByteArray GridComicsView::getMimeDataFromSelection()
return data;
}
void GridComicsView::updateCurrentComicView()
{
setCurrentComicIfNeeded();
}
void GridComicsView::startDrag()
{
QDrag *drag = new QDrag(this);
@ -508,7 +567,7 @@ void GridComicsView::closeEvent(QCloseEvent *event)
toolbar->removeAction(coverSizeSliderAction);
QObject *rootObject = dynamic_cast<QObject*>(view->rootObject());
QObject *infoContainer = rootObject->findChild<QObject*>("infoContainer");
QObject *infoContainer = rootObject->findChild<QObject*>("infoContainer", Qt::FindChildrenRecursively);
int infoWidth = QQmlProperty(infoContainer, "width").read().toInt();

View File

@ -5,6 +5,7 @@
#include <QModelIndex>
#include "comic_db.h"
class QAbstractListModel;
@ -17,7 +18,6 @@ class YACReaderComicsSelectionHelper;
class YACReaderComicInfoHelper;
class GridComicsView : public ComicsView
{
Q_OBJECT
@ -36,12 +36,14 @@ public:
void enableFilterMode(bool enabled);
QSize sizeHint();
QByteArray getMimeDataFromSelection();
void updateCurrentComicView();
public slots:
//ComicsView
void setShowMarks(bool show);
void selectAll();
void selectIndex(int index);
void triggerOpenCurrentComic();
void updateBackgroundConfig();
@ -68,6 +70,13 @@ protected slots:
void dummyUpdater(); //TODO remove this
void setCurrentComicIfNeeded();
void resetScroll();
signals:
void onScrollToOrigin();
private:
QSettings * settings;
QToolBar * toolbar;
@ -79,9 +88,13 @@ private:
QAction * showInfoAction;
QAction * showInfoSeparatorAction;
bool filterEnabled;
YACReaderComicsSelectionHelper * selectionHelper;
YACReaderComicInfoHelper * comicInfoHelper;
ComicDB currentComic;
bool dummy;
void closeEvent ( QCloseEvent * event );
void createCoverSizeSliderWidget();

View File

@ -42,8 +42,6 @@ YACReaderActivityIndicatorWidget::YACReaderActivityIndicatorWidget(QWidget * par
normal->setPixmap(line);
glow->setPixmap(glowLine);
QHBoxLayout * layout = new QHBoxLayout();
layout->addWidget(normal,0,Qt::AlignVCenter);
@ -155,6 +153,7 @@ ImportWidget::ImportWidget(QWidget *parent) :
QPushButton * stop = new QPushButton(tr("stop"));
stop->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Maximum);
stopButton = stop;
QVBoxLayout * layout = new QVBoxLayout(this);
QHBoxLayout * buttonLayout = new QHBoxLayout();
@ -192,7 +191,7 @@ ImportWidget::ImportWidget(QWidget *parent) :
layout->addLayout(buttonLayout,0);
layout->addSpacing(10);
layout->addStretch();
portadasLabel = new QLabel("<font color=\"#565959\">"+tr("Some of the comics being added...")+"</font>");
coversLabel = new QLabel("<font color=\"#565959\">"+tr("Some of the comics being added...")+"</font>");
hideButton = new QToolButton(this);
hideButton->setFixedSize(25,18);
@ -202,7 +201,7 @@ ImportWidget::ImportWidget(QWidget *parent) :
connect(hideButton,SIGNAL(toggled(bool)),this,SLOT(showCovers(bool)));
layout->addWidget(portadasLabel,0,Qt::AlignHCenter);
layout->addWidget(coversLabel,0,Qt::AlignHCenter);
layout->addWidget(coversViewContainer);
//layout->addStretch();
layout->addWidget(currentComicLabel,0,Qt::AlignHCenter);
@ -346,6 +345,11 @@ void ImportWidget::setImportLook()
iconLabel->setPixmap(QPixmap(":/images/importingIcon.png"));
text->setText("<font color=\"#495252\">"+tr("Importing comics")+"</font>");
textDescription->setText("<font color=\"#565959\">"+tr("<p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p>")+"</font>");
stopButton->setVisible(true);
coversLabel->setVisible(true);
coversViewContainer->setVisible(true);
hideButton->setVisible(true);
}
void ImportWidget::setUpdateLook()
@ -353,6 +357,23 @@ void ImportWidget::setUpdateLook()
iconLabel->setPixmap(QPixmap(":/images/updatingIcon.png"));
text->setText("<font color=\"#495252\">"+tr("Updating the library")+"</font>");
textDescription->setText("<font color=\"#565959\">"+tr("<p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p>")+"</font>");
stopButton->setVisible(true);
coversLabel->setVisible(true);
coversViewContainer->setVisible(true);
hideButton->setVisible(true);
}
void ImportWidget::setUpgradeLook()
{
iconLabel->setPixmap(QPixmap(":/images/updatingIcon.png"));
text->setText("<font color=\"#495252\">"+tr("Upgrading the library")+"</font>");
textDescription->setText("<font color=\"#565959\">"+tr("<p>The current library is being upgraded, please wait.</p>")+"</font>");
stopButton->setVisible(false);
coversLabel->setVisible(false);
coversViewContainer->setVisible(false);
hideButton->setVisible(false);
}
void ImportWidget::clearScene()
@ -363,7 +384,7 @@ void ImportWidget::clearScene()
void ImportWidget::showCovers(bool hide)
{
portadasLabel->setHidden(hide);
coversLabel->setHidden(hide);
coversViewContainer->setHidden(hide);
}

View File

@ -1,16 +1,9 @@
#ifndef IMPORT_WIDGET_H
#define IMPORT_WIDGET_H
#include <QWidget>
class QLabel;
class QGraphicsView;
class QGraphicsScene;
class QElapsedTimer;
class QVBoxLayout;
class QToolButton;
class QResizeEvent;
class QPropertyAnimation;
#include <QtWidgets>
class ImportWidget : public QWidget
{
@ -28,11 +21,12 @@ public slots:
void clearScene();
void setImportLook();
void setUpdateLook();
void setUpgradeLook();
void showCovers(bool hide);
private:
QLabel * currentComicLabel;
QLabel * portadasLabel;
QLabel * coversLabel;
QLabel * iconLabel;
QLabel * text;
QLabel * textDescription;
@ -40,6 +34,7 @@ private:
QGraphicsView * coversView;
QGraphicsScene * coversScene;
QPropertyAnimation * scrollAnimation;
QPushButton * stopButton;
int previousWidth;
bool updatingCovers;

View File

@ -212,6 +212,11 @@ void InfoComicsView::selectIndex(int index)
selectionHelper->selectIndex(index);
}
void InfoComicsView::updateCurrentComicView()
{
}
void InfoComicsView::setShowMarks(bool show)
{
QQmlContext *ctxt = view->rootContext();

View File

@ -29,6 +29,7 @@ public:
void updateConfig(QSettings * settings);
void enableFilterMode(bool enabled);
void selectIndex(int index);
void updateCurrentComicView();
public slots:
void setShowMarks(bool show);

View File

@ -150,6 +150,9 @@ void LibraryCreator::run()
_database.transaction();
//se crea la librería
create(QDir(_source));
DBHelper::updateChildrenInfo(_database);
_database.commit();
_database.close();
QSqlDatabase::removeDatabase(_database.connectionName());
@ -187,9 +190,15 @@ void LibraryCreator::run()
{
update(QDir(_source));
}
if(partialUpdate)
DBHelper::updateChildrenInfo(folderDestinationModelIndex.data(FolderModel::IdRole).toULongLong(),_database);
else
DBHelper::updateChildrenInfo(_database);
_database.commit();
_database.close();
QSqlDatabase::removeDatabase(_target);
QSqlDatabase::removeDatabase(_database.databaseName());
//si estabamos en modo creación, se está añadiendo una librería que ya existía y se ha actualizado antes de añadirse.
if(!partialUpdate)
{
@ -231,7 +240,7 @@ qulonglong LibraryCreator::insertFolders()
if(!(i->knownId))
{
i->setFather(currentId);
currentId = DBHelper::insert(&(*i),_database);//insertFolder(currentId,*i);
currentId = DBHelper::insert(&(*i),_database);//insertFolder(currentId,*i);
i->setId(currentId);
}
else
@ -300,12 +309,14 @@ void LibraryCreator::insertComic(const QString & relativePath,const QFileInfo &
QString hash = QString(crypto.result().toHex().constData()) + QString::number(fileInfo.size());
ComicDB comic = DBHelper::loadComic(fileInfo.fileName(),relativePath,hash,_database);
int numPages = 0;
QPair<int,int> originalCoverSize = {0,0};
bool exists = checkCover(hash);
if(! ( comic.hasCover() && exists))
{
ThumbnailCreator tc(QDir::cleanPath(fileInfo.absoluteFilePath()),_target+"/covers/"+hash+".jpg",comic.info.coverPage.toInt());
tc.create();
numPages = tc.getNumPages();
originalCoverSize = tc.getOriginalCoverSize();
if (numPages > 0)
{
emit(comicAdded(relativePath,_target+"/covers/"+hash+".jpg"));
@ -317,6 +328,12 @@ void LibraryCreator::insertComic(const QString & relativePath,const QFileInfo &
//en este punto sabemos que todos los folders que hay en _currentPath, deberían estar añadidos a la base de datos
insertFolders();
comic.info.numPages = numPages;
if(originalCoverSize.second > 0)
{
comic.info.originalCoverSize = QString("%1x%2").arg(originalCoverSize.first).arg(originalCoverSize.second);
comic.info.coverSizeRatio = static_cast<float>(originalCoverSize.first) / originalCoverSize.second;
}
comic.parentId = _currentPathFolders.last().id;
DBHelper::insert(&comic,_database);
}
@ -631,6 +648,7 @@ void ThumbnailCreator::create()
QImage p = pdfComic->page(_coverPage-1)->renderToImage(72,72);
#endif //
_cover = p;
_coverSize = QPair<int,int>(p.width(), p.height());
if(_target!="")
{
QImage scaled;
@ -642,7 +660,7 @@ void ThumbnailCreator::create()
{
scaled = p.scaledToWidth(480,Qt::SmoothTransformation);
}
scaled.save(_target,0,75);
scaled.save(_target,0,75);
}
else if(_target!="")
{
@ -708,6 +726,7 @@ void ThumbnailCreator::create()
QImage p;
if(p.loadFromData(archive.getRawDataAtIndex(index)))
{
_coverSize = QPair<int,int>(p.width(), p.height());
QImage scaled;
if(p.width()>p.height()) //landscape??
{

View File

@ -78,6 +78,7 @@
QString _target;
QString _currentName;
int _numPages;
QPair<int,int> _coverSize;
QImage _cover;
int _coverPage;
static bool crash;
@ -86,6 +87,7 @@
void create();
int getNumPages(){return _numPages;}
QPixmap getCover(){return QPixmap::fromImage(_cover);}
QPair<int,int> getOriginalCoverSize(){return _coverSize;}
signals:
void openingError(QProcess::ProcessError error);

View File

@ -19,6 +19,8 @@
#include <iterator>
#include <typeinfo>
#include <thread>
#include <future>
#include "data_base_management.h"
#include "yacreader_global.h"
@ -1124,6 +1126,15 @@ void LibraryWindow::createConnections()
//save covers
connect(saveCoversToAction,SIGNAL(triggered()),this,SLOT(saveSelectedCoversTo()));
//upgrade library
connect(this, SIGNAL(libraryUpgraded(QString)), this, SLOT(loadLibrary(QString)), Qt::QueuedConnection);
connect(this, SIGNAL(errorUpgradingLibrary(QString)), this, SLOT(showErrorUpgradingLibrary(QString)), Qt::QueuedConnection);
}
void LibraryWindow::showErrorUpgradingLibrary(const QString & path)
{
QMessageBox::critical(this,tr("Upgrade failed"), tr("There were errors during library upgrade in: ") + path+"/library.ydb");
}
void LibraryWindow::loadLibrary(const QString & name)
@ -1139,29 +1150,39 @@ void LibraryWindow::loadLibrary(const QString & name)
if(d.exists(path) && d.exists(path+"/library.ydb") && (dbVersion = DataBaseManagement::checkValidDB(path+"/library.ydb")) != "") //si existe en disco la biblioteca seleccionada, y es válida..
{
int comparation = DataBaseManagement::compareVersions(dbVersion,VERSION);
bool updated = false;
if(comparation < 0)
{
int ret = QMessageBox::question(this,tr("Update needed"),tr("This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now?"),QMessageBox::Yes,QMessageBox::No);
if(ret == QMessageBox::Yes)
{
updated = DataBaseManagement::updateToCurrentVersion(path+"/library.ydb");
if(!updated)
QMessageBox::critical(this,tr("Update failed"), tr("The current library can't be udpated. Check for write write permissions on: ") + path+"/library.ydb");
}
else
{
comicsViewsManager->comicsView->setModel(NULL);
foldersView->setModel(NULL);
listsView->setModel(NULL);
disableAllActions();//TODO comprobar que se deben deshabilitar
//será possible renombrar y borrar estas bibliotecas
renameLibraryAction->setEnabled(true);
removeLibraryAction->setEnabled(true);
}
}
if(comparation == 0 || updated) //en caso de que la versión se igual que la actual
if(comparation < 0)
{
int ret = QMessageBox::question(this,tr("Update needed"),tr("This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now?"),QMessageBox::Yes,QMessageBox::No);
if(ret == QMessageBox::Yes)
{
importWidget->setUpgradeLook();
showImportingWidget();
upgradeLibraryFuture = std::async(std::launch::async, [this, name, path] {
bool updated = DataBaseManagement::updateToCurrentVersion(path);
if(!updated)
emit errorUpgradingLibrary(path);
emit libraryUpgraded(name);
});
return;
}
else
{
comicsViewsManager->comicsView->setModel(NULL);
foldersView->setModel(NULL);
listsView->setModel(NULL);
disableAllActions();//TODO comprobar que se deben deshabilitar
//será possible renombrar y borrar estas bibliotecas
renameLibraryAction->setEnabled(true);
removeLibraryAction->setEnabled(true);
}
}
if(comparation == 0) //en caso de que la versión se igual que la actual
{
foldersModel->setupModelData(path);
foldersModelProxy->setSourceModel(foldersModel);
@ -1242,7 +1263,7 @@ void LibraryWindow::loadLibrary(const QString & name)
if(d.exists(path+"/library.ydb"))
{
QSqlDatabase db = DataBaseManagement::loadDatabase(path);
QSqlDatabase db = DataBaseManagement::loadDatabase(path);
manageOpeningLibraryError(db.lastError().databaseText() + "-" + db.lastError().driverText());
//será possible renombrar y borrar estas bibliotecas
renameLibraryAction->setEnabled(true);
@ -1771,14 +1792,12 @@ void LibraryWindow::checkEmptyFolder()
}
}
void LibraryWindow::openComic()
void LibraryWindow::openComic(const ComicDB &comic)
{
if(!importedCovers)
{
ComicDB comic = comicsModel->getComic(comicsViewsManager->comicsView->currentIndex());
if(!importedCovers) {
QList<ComicDB> siblings = comicsModel->getAllComics();
//TODO generate IDS for libraries...
//TODO generate IDS for libraries...
quint64 libraryId = libraries.getId(selectedLibrary->currentText());
bool yacreaderFound = false;
@ -1801,26 +1820,36 @@ void LibraryWindow::openComic()
#ifdef Q_OS_WIN
QStringList parameters {currentPath(), QString("--comicId=%1").arg(comic.id), QString("--libraryId=%1").arg(libraryId)};
yacreaderFound = QProcess::startDetached(QDir::cleanPath(QCoreApplication::applicationDirPath()), parameters);
yacreaderFound = QProcess::startDetached(QDir::cleanPath(QCoreApplication::applicationDirPath()+"/YACReader.exe"), parameters);
#endif
#if defined Q_OS_UNIX && !defined Q_OS_MAC
QStringList parameters {currentPath(), QString("--comicId=%1").arg(comic.id), QString("--libraryId=%1").arg(libraryId)};
yacreaderFound = QProcess::startDetached(QStringLiteral("YACReader"), parameters);
yacreaderFound = QProcess::startDetached(QStringLiteral("YACReader"), parameters);
#endif
if(!yacreaderFound)
{
#ifdef Q_OS_WIN
#ifdef Q_OS_WIN
QMessageBox::critical(this,tr("YACReader not found"),tr("YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary."));
#else
#else
QMessageBox::critical(this,tr("YACReader not found"),tr("YACReader not found. There might be a problem with your YACReader installation."));
#endif
#endif
}
}
}
void LibraryWindow::openComic()
{
if(!importedCovers)
{
ComicDB comic = comicsModel->getComic(comicsViewsManager->comicsView->currentIndex());
openComic(comic);
}
}
void LibraryWindow::setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus) {
comicsModel->setComicsRead(getSelectedComics(),readStatus);
comicsViewsManager->updateCurrentComicView();
}
void LibraryWindow::setCurrentComicReaded() {
@ -2487,7 +2516,7 @@ void LibraryWindow::deleteComicsFromDisk()
QLOG_TRACE() << comic.parentId;
}
ComicsRemover * remover = new ComicsRemover(indexList,paths);
ComicsRemover * remover = new ComicsRemover(indexList,paths,comics.at(0).parentId);
QThread * thread = NULL;
thread = new QThread(this);
@ -2500,6 +2529,8 @@ void LibraryWindow::deleteComicsFromDisk()
connect(remover, SIGNAL(remove(int)), comicsModel, SLOT(remove(int)));
connect(remover, SIGNAL(removeError()),this,SLOT(setRemoveError()));
connect(remover, SIGNAL(finished()), comicsModel, SLOT(finishTransaction()));
connect(remover, SIGNAL(finished()), comicsModel, SLOT(finishTransaction()));
connect(remover, SIGNAL(removedItemsFromFolder(qulonglong)), foldersModel, SLOT(updateFolderChildrenInfo(qulonglong)));
connect(remover, SIGNAL(finished()),this,SLOT(checkEmptyFolder()));
connect(remover, SIGNAL(finished()),this,SLOT(checkRemoveError()));
@ -2595,5 +2626,6 @@ void LibraryWindow::updateComicsView(quint64 libraryId, const ComicDB & comic)
{
if(libraryId == libraries.getId(selectedLibrary->currentText())) {
comicsModel->reload(comic);
comicsViewsManager->updateCurrentComicView();
}
}

View File

@ -12,6 +12,8 @@
#include "yacreader_navigation_controller.h"
#include <future>
#ifdef Q_OS_MAC
#include "yacreader_macosx_toolbar.h"
#endif
@ -286,11 +288,15 @@ protected:
public:
LibraryWindow();
signals:
void libraryUpgraded(const QString & libraryName);
void errorUpgradingLibrary(const QString & path);
public slots:
void loadLibrary(const QString & path);
void selectSubfolder(const QModelIndex & mi, int child);
void checkEmptyFolder();
void openComic();
void openComic(const ComicDB & comic);
void createLibrary();
void create(QString source,QString dest, QString name);
void showAddLibrary();
@ -377,6 +383,7 @@ public slots:
void setToolbarTitle(const QModelIndex & modelIndex);
void saveSelectedCoversTo();
void checkMaxNumLibraries();
void showErrorUpgradingLibrary(const QString & path);
void changeEvent(QEvent *event);
@ -385,10 +392,11 @@ private:
Qt::WindowFlags previousWindowFlags;
QPoint previousPos;
QSize previousSize;
std::future<void> upgradeLibraryFuture;
QSystemTrayIcon trayIcon;
private slots:
void trayActivation(QSystemTrayIcon::ActivationReason reason);
};
#endif

View File

@ -101,7 +101,7 @@ int main( int argc, char ** argv )
QDir().mkpath(YACReader::getSettingsPath());
Logger& logger = Logger::instance();
logger.setLoggingLevel(QsLogging::InfoLevel);
logger.setLoggingLevel(QsLogging::TraceLevel);
DestinationPtr fileDestination(DestinationFactory::MakeFileDestination(
destLog, EnableLogRotation, MaxSizeBytes(1048576), MaxOldLogCount(2)));

View File

@ -757,15 +757,24 @@ void PropertiesDialog::save()
itr->info.edited = edited;
}
updateComics();
if(comics.count() == 1)
{
if(coverChanged)// && coverPageEdit->text().toInt() != *comics[0].info.coverPage)
{
ThumbnailCreator tc(basePath+comics[0].path,basePath+"/.yacreaderlibrary/covers/"+comics[0].info.hash+".jpg", comics[0].info.coverPage.toInt());
tc.create();
if(tc.getOriginalCoverSize().second > 0)
{
comics[0].info.originalCoverSize = QString("%1x%2").arg(tc.getOriginalCoverSize().first).arg(tc.getOriginalCoverSize().second);
comics[0].info.coverSizeRatio = static_cast<float>(tc.getOriginalCoverSize().first) / tc.getOriginalCoverSize().second;
}
}
}
updateComics();
close();
emit(accepted());
}

View File

@ -114,6 +114,8 @@ class QToolButton;
void updateCoverPageNumberLabel(int n);
bool coverChanged;
float coverSizeRatio;
QString originalCoverSize;
public:
PropertiesDialog(QWidget * parent = 0);

View File

@ -15,7 +15,7 @@
<file>qml/info-indicator-light@2x.png</file>
<file>qml/info-shadow-light@2x.png</file>
<file>qml/info-top-shadow.png</file>
<file>qml/ComicInfo.qml</file>
<file>qml/ComicInfoView.qml</file>
<file>qml/info-favorites.png</file>
<file>qml/info-favorites@2x.png</file>
<file>qml/info-rating.png</file>

View File

@ -1,13 +1,16 @@
import QtQuick 2.3
import QtQuick 2.9
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.2
import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.0
import QtQuick.Controls.Styles 1.4
import com.yacreader.ComicModel 1.0
import com.yacreader.ComicInfo 1.0
import com.yacreader.ComicDB 1.0
SplitView {
anchors.fill: parent
orientation: Qt.Horizontal
@ -171,7 +174,6 @@ Rectangle {
}
onPressed: {
var ci = grid.currentIndex; //save current index
/*if(mouse.button != Qt.RightButton && !(mouse.modifiers & Qt.ControlModifier || mouse.modifiers & Qt.ShiftModifier))
@ -385,12 +387,18 @@ Rectangle {
}
}
YACReaderScrollView {
__wheelAreaScrollSpeed: grid.cellHeight * 0.30
ScrollView {
__wheelAreaScrollSpeed: grid.cellHeight * 0.40
id: scrollView
objectName: "topScrollView"
anchors.fill: parent
anchors.margins: 0
function scrollToOrigin() {
flickableItem.contentY = showCurrentComic ? -270 : -20
flickableItem.contentX = 0
}
style: YACReaderScrollViewStyle {
transientScrollBars: false
incrementControl: Item {}
@ -456,22 +464,243 @@ Rectangle {
}
}
Component {
id: currentComicView
Rectangle {
id: currentComicViewTopView
color: "#00000000"
height: showCurrentComic ? 270 : 20
Rectangle {
color: (Qt.platform.os === "osx") ? "#88FFFFFF" : "#88000000"
id: currentComicVisualView
width: main.width
height: 250
visible: showCurrentComic
//cover
Image {
id: currentCoverElement
anchors.fill: parent
anchors.leftMargin: 15
anchors.topMargin: 15
anchors.bottomMargin: 15
anchors.rightMargin: 15
horizontalAlignment: Image.AlignLeft
anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0}
source: comicsList.getCoverUrlPathForComicHash(currentComicInfo.hash.toString())
fillMode: Image.PreserveAspectFit
smooth: true
mipmap: true
asynchronous : true
cache: false //TODO clear cache only when it is needed
}
DropShadow {
anchors.fill: currentCoverElement
horizontalOffset: 0
verticalOffset: 0
radius: 8.0
samples: 17
color: "#FF000000"
source: currentCoverElement
visible: (Qt.platform.os === "osx") ? false : true;
}
ColumnLayout
{
id: currentComicInfoView
x: currentCoverElement.anchors.rightMargin + currentCoverElement.paintedWidth + currentCoverElement.anchors.rightMargin
//y: currentCoverElement.anchors.topMargin
anchors.top: currentCoverElement.top
anchors.right: parent.right
anchors.left: readButton.left
spacing: 9
Text {
Layout.topMargin: 7
Layout.fillWidth: true
Layout.rightMargin: 20
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
id: currentComicInfoTitleView
color: infoTitleColor
font.family: "Arial"
font.bold: true
font.pixelSize: 21
wrapMode: Text.WordWrap
text: currentComic.getTitleIncludingNumber()
}
Flow {
spacing: 0
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
Layout.fillWidth: true
Layout.fillHeight: false
id: currentComicDetailsFlowView
property font infoFont: Qt.font({
family: "Arial",
pixelSize: 14
});
property string infoFlowTextColor: infoTextColor
Text {
id: currentComicInfoVolume
color: currentComicDetailsFlowView.infoFlowTextColor
font: currentComicDetailsFlowView.infoFont
text: currentComicInfo.volume ? currentComicInfo.volume : ""
rightPadding: 20
visible: currentComicInfo.volume ? true : false
}
Text {
id: currentComicInfoNumbering
color: currentComicDetailsFlowView.infoFlowTextColor
font: currentComicDetailsFlowView.infoFont
text: currentComicInfo.number + "/" + currentComicInfo.count
rightPadding: 20
visible : currentComicInfo.number ? true : false
}
Text {
id: currentComicInfoGenre
color: currentComicDetailsFlowView.infoFlowTextColor
font: currentComicDetailsFlowView.infoFont
text: currentComicInfo.genere ? currentComicInfo.genere : ""
rightPadding: 20
visible: currentComicInfo.genere ? true : false
}
Text {
id: currentComicInfoDate
color: currentComicDetailsFlowView.infoFlowTextColor
font: currentComicDetailsFlowView.infoFont
text: currentComicInfo.date ? currentComicInfo.date : ""
rightPadding: 20
visible: currentComicInfo.date ? true : false
}
Text {
id: currentComicInfoPages
color: currentComicDetailsFlowView.infoFlowTextColor
font: currentComicDetailsFlowView.infoFont
text: (currentComicInfo.numPages ? currentComicInfo.numPages : "") + " pages"
rightPadding: 20
visible: currentComicInfo.numPages ? true : false
}
Text {
id: currentComicInfoShowInComicVine
font: currentComicDetailsFlowView.infoFont
color: "#ffcc00"
text: "Show in Comic Vine"
visible: currentComicInfo.comicVineID ? true : false
MouseArea {
anchors.fill: parent
onClicked: {
Qt.openUrlExternally("http://www.comicvine.com/comic/4000-%1/".arg(comicInfo.comicVineID));
}
}
}
}
Text {
Layout.topMargin: 6
Layout.rightMargin: 30
Layout.bottomMargin: 5
Layout.fillWidth: true
Layout.maximumHeight: (currentComicVisualView.height * 0.32)
Layout.maximumWidth: 960
id: currentComicInfoSinopsis
color: infoTitleColor
font.family: "Arial"
font.pixelSize: 14
wrapMode: Text.WordWrap
elide: Text.ElideRight
horizontalAlignment: Text.AlignJustify
text: currentComicInfo.synopsis ? currentComicInfo.synopsis : ""
visible: currentComicInfo.synopsis ? true : false
}
}
Button {
text: "Read"
id: readButton
x: currentCoverElement.anchors.rightMargin + currentCoverElement.paintedWidth + currentCoverElement.anchors.rightMargin
anchors.bottom: currentCoverElement.bottom
anchors.bottomMargin: 15
onClicked: comicOpener.triggerOpenCurrentComic()
style: ButtonStyle {
background: Rectangle {
implicitWidth: 100
implicitHeight: 30
border.width: control.activeFocus ? 2 : 1
border.color: "#FFCC00"
radius: height / 2
color: "#FFCC00"
}
label: Text {
renderType: Text.NativeRendering
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.family: "Arial"
font.pointSize: 12
font.bold: true
color: "white"
text: control.text
}
}
}
DropShadow {
anchors.fill: readButton
horizontalOffset: 0
verticalOffset: 0
radius: 8.0
samples: 17
color: "#AA000000"
source: readButton
visible: ((Qt.platform.os === "osx") ? false : true) && !readButton.pressed
}
}
}
}
GridView {
id:grid
objectName: "grid"
anchors.fill: parent
cellHeight: cellCustomHeight
header: currentComicView
//highlight: appHighlight
focus: true
model: comicsList
delegate: appDelegate
anchors.topMargin: 20
anchors.topMargin: 0 //showCurrentComic ? 0 : 20
anchors.bottomMargin: 20
anchors.leftMargin: 10
anchors.rightMargin: 10
anchors.leftMargin: 0
anchors.rightMargin: 0
pixelAligned: true
//flickDeceleration: -2000
currentIndex: 0
cacheBuffer: 0
@ -620,7 +849,7 @@ Rectangle {
}
}
ComicInfo {
ComicInfoView {
width: info_container.width
}
}

View File

@ -91,7 +91,7 @@ Rectangle {
}
}
ComicInfo {
ComicInfoView {
width: info_container.width - 14
}
}

View File

@ -50,7 +50,7 @@ Style {
id: root
/*! The \l ScrollView this style is attached to. */
readonly property YACReaderScrollView control: __control
readonly property ScrollView control: __control
/*! This property controls the frame border padding of the scrollView. */
padding {left: 1; top: 1; right: 1; bottom: 1}

View File

@ -1,62 +0,0 @@
/**
@file
@author Stefan Frings
*/
#include "dumpcontroller.h"
#include <QVariant>
#include <QDateTime>
DumpController::DumpController(){}
void DumpController::service(HttpRequest& request, HttpResponse& response) {
response.setHeader("Content-Type", "text/html; charset=ISO-8859-1");
response.setCookie(HttpCookie("firstCookie","hello",600));
response.setCookie(HttpCookie("secondCookie","world",600));
QByteArray body("<html><body>");
body.append("<b>Request:</b>");
body.append("<br>Method: ");
body.append(request.getMethod());
body.append("<br>Path: ");
body.append(request.getPath());
body.append("<br>Version: ");
body.append(request.getVersion());
body.append("<p><b>Headers:</b>");
QMapIterator<QByteArray,QByteArray> i(request.getHeaderMap());
while (i.hasNext()) {
i.next();
body.append("<br>");
body.append(i.key());
body.append("=");
body.append(i.value());
}
body.append("<p><b>Parameters:</b>");
i=QMapIterator<QByteArray,QByteArray>(request.getParameterMap());
while (i.hasNext()) {
i.next();
body.append("<br>");
body.append(i.key());
body.append("=");
body.append(i.value());
}
body.append("<p><b>Cookies:</b>");
i=QMapIterator<QByteArray,QByteArray>(request.getCookieMap());
while (i.hasNext()) {
i.next();
body.append("<br>");
body.append(i.key());
body.append("=");
body.append(i.value());
}
body.append("<p><b>Body:</b><br>");
body.append(request.getBody());
body.append("</body></html>");
response.write(body,true);
}

View File

@ -1,29 +0,0 @@
/**
@file
@author Stefan Frings
*/
#ifndef DUMPCONTROLLER_H
#define DUMPCONTROLLER_H
#include "httprequest.h"
#include "httpresponse.h"
#include "httprequesthandler.h"
/**
This controller dumps the received HTTP request in the response.
*/
class DumpController : public HttpRequestHandler {
Q_OBJECT
Q_DISABLE_COPY(DumpController);
public:
/** Constructor */
DumpController();
/** Generates the response */
void service(HttpRequest& request, HttpResponse& response);
};
#endif // DUMPCONTROLLER_H

View File

@ -1,38 +0,0 @@
/**
@file
@author Stefan Frings
*/
#include "fileuploadcontroller.h"
FileUploadController::FileUploadController() {}
void FileUploadController::service(HttpRequest& request, HttpResponse& response) {
if (request.getParameter("action")=="show") {
response.setHeader("Content-Type", "image/jpeg");
QTemporaryFile* file=request.getUploadedFile("file1");
if (file) {
while (!file->atEnd() && !file->error()) {
QByteArray buffer=file->read(65536);
response.write(buffer);
}
}
else {
response.write("upload failed");
}
}
else {
response.setHeader("Content-Type", "text/html; charset=ISO-8859-1");
response.write("<html><body>");
response.write("Upload a JPEG image file<p>");
response.write("<form method=\"post\" enctype=\"multipart/form-data\">");
response.write(" <input type=\"hidden\" name=\"action\" value=\"show\">");
response.write(" File: <input type=\"file\" name=\"file1\"><br>");
response.write(" <input type=\"submit\">");
response.write("</form>");
response.write("</body></html>",true);
}
}

View File

@ -1,30 +0,0 @@
/**
@file
@author Stefan Frings
*/
#ifndef FILEUPLOADCONTROLLER_H
#define FILEUPLOADCONTROLLER_H
#include "httprequest.h"
#include "httpresponse.h"
#include "httprequesthandler.h"
/**
This controller displays a HTML form for file upload and recieved the file.
*/
class FileUploadController : public HttpRequestHandler {
Q_OBJECT
Q_DISABLE_COPY(FileUploadController);
public:
/** Constructor */
FileUploadController();
/** Generates the response */
void service(HttpRequest& request, HttpResponse& response);
};
#endif // FILEUPLOADCONTROLLER_H

View File

@ -1,64 +0,0 @@
/**
@file
@author Stefan Frings
*/
#include "formcontroller.h"
#include <QStringList>
FormController::FormController() {}
void FormController::service(HttpRequest& request, HttpResponse& response) {
response.setHeader("Content-Type", "text/html; charset=utf-8");
QString data(request.getBody());
QStringList list = data.split("\n");
response.write("<html><body>");
response.writeText("á é í ó ú ñ -> \\ /Device type: "+list.first());
//test background proccesing
/*int i=0;
int j=0;
while(i<1000000000)
{
if(request.getBody().length()>1)
j++;
else
i++;
if(i%1000000 == 0)
response.write("<p> lista </p>");
}*/
response.write("<p> lista </p>");
response.write("<ul>");
for(int i=1;i<list.length();i++)
{
response.writeText("<li>"+list.at(i)+"</li>");
}
response.write("</ul></body></html>",true);
/*if (request.getParameter("action")=="show") {
response.write("<html><body>");
response.write("Name = ");
response.write(request.getParameter("name"));
response.write("<br>City = ");
response.write(request.getParameter("city"));
response.write("</body></html>",true);
}
else {
response.write("<html><body>");
response.write("<form method=\"post\">");
response.write(" <input type=\"hidden\" name=\"action\" value=\"show\">");
response.write(" Name: <input type=\"text\" name=\"name\"><br>");
response.write(" City: <input type=\"text\" name=\"city\"><br>");
response.write(" <input type=\"submit\">");
response.write("</form>");
response.write("</body></html>",true);
}*/
}

View File

@ -1,40 +0,0 @@
#include "librariescontroller.h"
#include "db_helper.h" //get libraries
#include "yacreader_libraries.h"
#include "template.h"
#include "../static.h"
#include "QsLog.h"
LibrariesController::LibrariesController() {}
void LibrariesController::service(HttpRequest& request, HttpResponse& response)
{
HttpSession session=Static::sessionStore->getSession(request,response,false);
response.setHeader("Content-Type", "text/html; charset=utf-8");
response.setHeader("Connection","close");
session.clearNavigationPath();
Template t=Static::templateLoader->getTemplate("libraries_"+session.getDeviceType(),request.getHeader("Accept-Language"));
t.enableWarnings();
YACReaderLibraries libraries = DBHelper::getLibraries();
QList<QString> names = DBHelper::getLibrariesNames();
t.loop("library",names.length());
int currentId = 0;
int i = 0;
foreach (QString name,names) {
currentId = libraries.getId(name);
t.setVariable(QString("library%1.name").arg(i),QString::number(currentId));
t.setVariable(QString("library%1.label").arg(i),name);
i++;
}
response.setStatus(200,"OK");
response.writeText(t,true);
}

View File

@ -1,96 +0,0 @@
#include "pagecontroller.h"
#include "../static.h"
#include "comic.h"
#include "comiccontroller.h"
#include <QDataStream>
#include <QPointer>
#include <QsLog.h>
#include "db_helper.h"
PageController::PageController() {}
void PageController::service(HttpRequest& request, HttpResponse& response)
{
HttpSession session=Static::sessionStore->getSession(request,response,false);
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
bool remote = path.endsWith("remote");
//QByteArray path2=request.getPath();
//qDebug("PageController: request to -> %s ",path2.data());
QStringList pathElements = path.split('/');
QString libraryName = DBHelper::getLibraryName(pathElements.at(2).toInt());
qulonglong comicId = pathElements.at(4).toULongLong();
unsigned int page = pathElements.at(6).toUInt();
//qDebug("lib name : %s",pathElements.at(2).data());
Comic * comicFile;
qulonglong currentComicId;
if(remote)
{
QLOG_TRACE() << "se recupera comic remoto para servir páginas";
comicFile = session.getCurrentRemoteComic();
currentComicId = session.getCurrentRemoteComicId();
}
else
{
QLOG_TRACE() << "se recupera comic para servir páginas";
comicFile = session.getCurrentComic();
currentComicId = session.getCurrentComicId();
}
if(currentComicId != 0 && !QPointer<Comic>(comicFile).isNull())
{
if(comicId == currentComicId && page < comicFile->numPages())
{
if(comicFile->pageIsLoaded(page))
{
//qDebug("PageController: La página estaba cargada -> %s ",path.data());
response.setHeader("Content-Type", "image/jpeg");
response.setHeader("Transfer-Encoding","chunked");
QByteArray pageData = comicFile->getRawPage(page);
QDataStream data(pageData);
char buffer[4096];
while (!data.atEnd()) {
int len = data.readRawData(buffer,4096);
response.write(QByteArray(buffer,len));
}
//response.write(pageData,true);
response.write(QByteArray(),true);
}
else
{
//qDebug("PageController: La página NO estaba cargada 404 -> %s ",path.data());
response.setStatus(404,"not found"); //TODO qué mensaje enviar
response.write("404 not found",true);
}
}
else
{
if(comicId != currentComicId)
{
//delete comicFile;
if(remote)
session.dismissCurrentRemoteComic();
else
session.dismissCurrentComic();
}
response.setStatus(404,"not found"); //TODO qué mensaje enviar
response.write("404 not found",true);
}
}
else
{
response.setStatus(404,"not found");
response.write("404 not found",true);
}
//response.write(t.toLatin1(),true);
}

View File

@ -1,29 +0,0 @@
/**
@file
@author Stefan Frings
*/
#ifndef SESSIONCONTROLLER_H
#define SESSIONCONTROLLER_H
#include "httprequest.h"
#include "httpresponse.h"
#include "httprequesthandler.h"
/**
This controller demonstrates how to use sessions.
*/
class SessionController : public HttpRequestHandler {
Q_OBJECT
Q_DISABLE_COPY(SessionController);
public:
/** Constructor */
SessionController();
/** Generates the response */
void service(HttpRequest& request, HttpResponse& response);
};
#endif // SESSIONCONTROLLER_H

View File

@ -1,31 +0,0 @@
/**
@file
@author Stefan Frings
*/
#include "templatecontroller.h"
#include "template.h"
#include "../static.h"
TemplateController::TemplateController(){}
void TemplateController::service(HttpRequest& request, HttpResponse& response) {
response.setHeader("Content-Type", "text/html; charset=ISO-8859-1");
Template t=Static::templateLoader->getTemplate("demo",request.getHeader("Accept-Language"));
t.enableWarnings();
t.setVariable("path",request.getPath());
QMap<QByteArray,QByteArray> headers=request.getHeaderMap();
QMapIterator<QByteArray,QByteArray> iterator(headers);
t.loop("header",headers.size());
int i=0;
while (iterator.hasNext()) {
iterator.next();
t.setVariable(QString("header%1.name").arg(i),QString(iterator.key()));
t.setVariable(QString("header%1.value").arg(i),QString(iterator.value()));
++i;
}
response.write(t.toLatin1(),true);
}

View File

@ -1,30 +0,0 @@
/**
@file
@author Stefan Frings
*/
#ifndef TEMPLATECONTROLLER_H
#define TEMPLATECONTROLLER_H
#include "httprequest.h"
#include "httpresponse.h"
#include "httprequesthandler.h"
/**
This controller generates a website using the template engine.
It generates a Latin1 (ISO-8859-1) encoded website from a UTF-8 encoded template file.
*/
class TemplateController : public HttpRequestHandler {
Q_OBJECT
Q_DISABLE_COPY(TemplateController);
public:
/** Constructor */
TemplateController();
/** Generates the response */
void service(HttpRequest& request, HttpResponse& response);
};
#endif // TEMPLATECONTROLLER_H

View File

@ -0,0 +1,124 @@
#include "comiccontroller.h"
#include "db_helper.h"
#include "yacreader_libraries.h"
#include "yacreader_http_session.h"
#include "template.h"
#include "../static.h"
#include "comic_db.h"
#include "comic.h"
#include "QsLog.h"
#include <typeinfo>
ComicController::ComicController() {}
void ComicController::service(HttpRequest& request, HttpResponse& response)
{
HttpSession session=Static::sessionStore->getSession(request,response,false);
YACReaderHttpSession *ySession = Static::yacreaderSessionStore->getYACReaderSessionHttpSession(session.getId());
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
QStringList pathElements = path.split('/');
qulonglong libraryId = pathElements.at(2).toLongLong();
QString libraryName = DBHelper::getLibraryName(libraryId);
qulonglong comicId = pathElements.at(4).toULongLong();
bool remoteComic = path.endsWith("remote");
//TODO
//if(pathElements.size() == 6)
//{
// QString action = pathElements.at(5);
// if(!action.isEmpty() && (action == "close"))
// {
// session.dismissCurrentComic();
// response.write("",true);
// return;
// }
//}
YACReaderLibraries libraries = DBHelper::getLibraries();
ComicDB comic = DBHelper::getComicInfo(libraryId, comicId);
if(!remoteComic)
ySession->setDownloadedComic(comic.info.hash);
Comic * comicFile = FactoryComic::newComic(libraries.getPath(libraryId)+comic.path);
if(comicFile != NULL)
{
QThread * thread = NULL;
thread = new QThread();
comicFile->moveToThread(thread);
connect(comicFile, SIGNAL(errorOpening()), thread, SLOT(quit()));
connect(comicFile, SIGNAL(errorOpening(QString)), thread, SLOT(quit()));
connect(comicFile, SIGNAL(imagesLoaded()), thread, SLOT(quit()));
connect(thread, SIGNAL(started()), comicFile, SLOT(process()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
comicFile->load(libraries.getPath(libraryId)+comic.path);
if(thread != NULL)
thread->start();
if(remoteComic)
{
QLOG_TRACE() << "remote comic requested";
ySession->setCurrentRemoteComic(comic.id, comicFile);
}
else
{
QLOG_TRACE() << "comic requested";
ySession->setCurrentComic(comic.id, comicFile);
}
response.setHeader("Content-Type", "text/plain; charset=utf-8");
//TODO this field is not used by the client!
response.write(QString("library:%1\r\n").arg(libraryName).toUtf8());
response.write(QString("libraryId:%1\r\n").arg(libraryId).toUtf8());
if(remoteComic) //send previous and next comics id
{
QList<LibraryItem *> siblings = DBHelper::getFolderComicsFromLibrary(libraryId, comic.parentId, true);
bool found = false;
int i;
for(i = 0; i < siblings.length(); i++)
{
if (siblings.at(i)->id == comic.id)
{
found = true;
break;
}
}
if(found)
{
if(i>0)
response.write(QString("previousComic:%1\r\n").arg(siblings.at(i-1)->id).toUtf8());
if(i<siblings.length()-1)
response.write(QString("nextComic:%1\r\n").arg(siblings.at(i+1)->id).toUtf8());
}
else
{
//ERROR
}
qDeleteAll(siblings);
}
response.write(comic.toTXT().toUtf8(),true);
}
else
{
//delete comicFile;
response.setStatus(404,"not found");
response.write("404 not found",true);
}
//response.write(t.toLatin1(),true);
}

View File

@ -10,7 +10,7 @@ ComicDownloadInfoController::ComicDownloadInfoController() {}
void ComicDownloadInfoController::service(HttpRequest& request, HttpResponse& response)
{
response.setHeader("Content-Type", "plain/text; charset=utf-8");
response.setHeader("Content-Type", "text/plain; charset=utf-8");
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
QStringList pathElements = path.split('/');
@ -21,6 +21,6 @@ void ComicDownloadInfoController::service(HttpRequest& request, HttpResponse& re
ComicDB comic = DBHelper::getComicInfo(libraryId, comicId);
//TODO: check if the comic wasn't found;
response.writeText(QString("fileName:%1\r\n").arg(comic.getFileName()));
response.writeText(QString("fileSize:%1\r\n").arg(comic.getFileSize()),true);
response.write(QString("fileName:%1\r\n").arg(comic.getFileName()).toUtf8());
response.write(QString("fileSize:%1\r\n").arg(comic.getFileSize()).toUtf8(),true);
}

View File

@ -0,0 +1,89 @@
#include "covercontroller.h"
#include "db_helper.h" //get libraries
#include "yacreader_libraries.h"
#include "yacreader_http_session.h"
#include "template.h"
#include "../static.h"
CoverController::CoverController() {}
void CoverController::service(HttpRequest& request, HttpResponse& response)
{
HttpSession session=Static::sessionStore->getSession(request,response,false);
YACReaderHttpSession *ySession = Static::yacreaderSessionStore->getYACReaderSessionHttpSession(session.getId());
response.setHeader("Content-Type", "image/jpeg");
response.setHeader("Connection","close");
//response.setHeader("Content-Type", "plain/text; charset=ISO-8859-1");
YACReaderLibraries libraries = DBHelper::getLibraries();
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
QStringList pathElements = path.split('/');
QString libraryName = DBHelper::getLibraryName(pathElements.at(2).toInt());
QString fileName = pathElements.at(4);
bool folderCover = request.getParameter("folderCover").length()>0;
//response.writeText(path+"<br/>");
//response.writeText(libraryName+"<br/>");
//response.writeText(libraries.value(libraryName)+"/.yacreaderlibrary/covers/"+fileName+"<br/>");
//QFile file(libraries.value(libraryName)+"/.yacreaderlibrary/covers/"+fileName);
//if (file.exists()) {
// if (file.open(QIODevice::ReadOnly))
// {
// qDebug("StaticFileController: Open file %s",qPrintable(file.fileName()));
// // Return the file content, do not store in cache
// while (!file.atEnd() && !file.error()) {
// response.write(file.read(131072));
// }
// }
// file.close();
//}
QImage img(libraries.getPath(libraryName)+"/.yacreaderlibrary/covers/"+fileName);
if (!img.isNull()) {
int width = 80, height = 120;
if(ySession->getDisplayType()=="@2x")
{
width = 160;
height = 240;
}
if(float(img.width())/img.height() < 0.66666)
img = img.scaledToWidth(width,Qt::SmoothTransformation);
else
img = img.scaledToHeight(height,Qt::SmoothTransformation);
QImage destImg(width,height,QImage::Format_RGB32);
destImg.fill(Qt::black);
QPainter p(&destImg);
p.drawImage((width-img.width())/2,(height-img.height())/2,img);
if(folderCover)
{
if(ySession->getDisplayType()=="@2x")
p.drawImage(0,0,QImage(":/images/f_overlayed_retina.png"));
else
p.drawImage(0,0,QImage(":/images/f_overlayed.png"));
}
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
destImg.save(&buffer, "JPG");
response.write(ba,true);
}
//DONE else, hay que devolver un 404
else
{
response.setStatus(404,"not found");
response.write("404 not found",true);
}
}

View File

@ -1,5 +1,7 @@
#include "foldercontroller.h"
#include "controllers/errorcontroller.h"
#include "controllers/v1/errorcontroller.h"
#include "yacreader_http_session.h"
#include "db_helper.h" //get libraries
#include "comic_db.h"
@ -32,6 +34,7 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
bool showlessInfoPerFolder = settings->value(REMOTE_BROWSE_PERFORMANCE_WORKAROUND,false).toBool();
HttpSession session=Static::sessionStore->getSession(request,response,false);
YACReaderHttpSession *ySession = Static::yacreaderSessionStore->getYACReaderSessionHttpSession(session.getId());
response.setHeader("Content-Type", "text/html; charset=utf-8");
response.setHeader("Connection","close");
@ -39,7 +42,7 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
//QString y = session.get("xxx").toString();
//response.writeText(QString("session xxx : %1 <br/>").arg(y));
Template t=Static::templateLoader->getTemplate("folder_"+session.getDeviceType(),request.getHeader("Accept-Language"));
Template t=Static::templateLoader->getTemplate("folder_"+ySession->getDeviceType(),request.getHeader("Accept-Language"));
t.enableWarnings();
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
QStringList pathElements = path.split('/');
@ -91,17 +94,17 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
if(folderId == 1)
{
session.clearNavigationPath();
session.pushNavigationItem(QPair<qulonglong,quint32>(folderId,page));
ySession->clearNavigationPath();
ySession->pushNavigationItem(QPair<qulonglong,quint32>(folderId,page));
t.setVariable(QString("upurl"),"/");
}
else
{
if(fromUp)
session.popNavigationItem();
ySession->popNavigationItem();
else //drill down or direct access
{
QStack<QPair<qulonglong, quint32> > path = session.getNavigationPath();
QStack<QPair<qulonglong, quint32> > path = ySession->getNavigationPath();
bool found=false;
for(QStack<QPair<qulonglong, quint32> >::const_iterator itr = path.begin(); itr!=path.end(); itr++)
if(itr->first == folderId)
@ -112,16 +115,16 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
if(found)
{
while(session.topNavigationItem().first != folderId)
session.popNavigationItem();
while(ySession->topNavigationItem().first != folderId)
ySession->popNavigationItem();
session.updateTopItem(QPair<qulonglong,quint32>(folderId,page));
ySession->updateTopItem(QPair<qulonglong,quint32>(folderId,page));
}
else
session.pushNavigationItem(QPair<qulonglong,quint32>(folderId,page));
ySession->pushNavigationItem(QPair<qulonglong,quint32>(folderId,page));
}
QStack<QPair<qulonglong, quint32> > path = session.getNavigationPath();
QStack<QPair<qulonglong, quint32> > path = ySession->getNavigationPath();
if(path.count()>1)
{
QPair<qulonglong, quint32> parentItem = path.at(path.count()-2);
@ -152,7 +155,7 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
int numFoldersAtCurrentPage = qMax(0,qMin(numFolders - indexCurrentPage, elementsPerPage));
//PATH
QStack<QPair<qulonglong,quint32> > foldersPath = session.getNavigationPath();
QStack<QPair<qulonglong,quint32> > foldersPath = ySession->getNavigationPath();
t.setVariable(QString("library.name"),libraryName);
t.setVariable(QString("library.url"),QString("/library/%1/folder/1").arg(libraryId));
t.loop("path",foldersPath.count()-1);
@ -208,9 +211,9 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
const ComicDB * comic = (ComicDB *)item;
t.setVariable(QString("element%1.browse").arg(i),"");
//t.setVariable(QString("element%1.downloadurl").arg(i),"/library/"+libraryName+"/comic/"+QString("%1").arg(comic->id));
if(!session.isComicOnDevice(comic->info.hash) && !session.isComicDownloaded(comic->info.hash))
if(!ySession->isComicOnDevice(comic->info.hash) && !ySession->isComicDownloaded(comic->info.hash))
t.setVariable(QString("element%1.download").arg(i),QString("<a onclick=\"this.innerHTML='IMPORTING';this.className='importedButton';\" class =\"importButton\" href=\"%1\">IMPORT</a>").arg("/library/"+QString::number(libraryId)+"/comic/"+QString("%1").arg(comic->id)));
else if (session.isComicOnDevice(comic->info.hash))
else if (ySession->isComicOnDevice(comic->info.hash))
t.setVariable(QString("element%1.download").arg(i),QString("<div class=\"importedButton\">IMPORTED</div>"));
else
t.setVariable(QString("element%1.download").arg(i),QString("<div class=\"importedButton\">IMPORTING</div>"));
@ -329,6 +332,6 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
t.setVariable("page",QString("%1").arg(page+1));
t.setVariable("pages",QString("%1").arg(numPages));
response.writeText(t, true);
response.write(t.toUtf8(), true);
}

View File

@ -12,17 +12,17 @@ FolderInfoController::FolderInfoController() {}
void FolderInfoController::service(HttpRequest& request, HttpResponse& response)
{
response.setHeader("Content-Type", "plain/text; charset=utf-8");
response.setHeader("Content-Type", "text/plain; charset=utf-8");
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
QStringList pathElements = path.split('/');
int libraryId = pathElements.at(2).toInt();
QString libraryName = DBHelper::getLibraryName(libraryId);
qulonglong parentId = pathElements.at(4).toULongLong();
QStringList pathElements = path.split('/');
int libraryId = pathElements.at(2).toInt();
QString libraryName = DBHelper::getLibraryName(libraryId);
qulonglong parentId = pathElements.at(4).toULongLong();
serviceComics(libraryId, parentId, response);
response.writeText("",true);
response.write("",true);
}
void FolderInfoController::serviceComics(const int &library, const qulonglong &folderId, HttpResponse &response)
@ -34,7 +34,7 @@ void FolderInfoController::serviceComics(const int &library, const qulonglong &f
for(QList<LibraryItem *>::const_iterator itr = folderComics.constBegin();itr!=folderComics.constEnd();itr++)
{
currentComic = (ComicDB *)(*itr);
response.writeText(QString("/library/%1/comic/%2:%3:%4\r\n").arg(library).arg(currentComic->id).arg(currentComic->getFileName()).arg(currentComic->getFileSize()));
response.write(QString("/library/%1/comic/%2:%3:%4\r\n").arg(library).arg(currentComic->id).arg(currentComic->getFileName()).arg(currentComic->getFileSize()).toUtf8());
delete currentComic;
}

View File

@ -0,0 +1,42 @@
#include "librariescontroller.h"
#include "db_helper.h" //get libraries
#include "yacreader_libraries.h"
#include "yacreader_http_session.h"
#include "template.h"
#include "../static.h"
#include "QsLog.h"
LibrariesController::LibrariesController() {}
void LibrariesController::service(HttpRequest& request, HttpResponse& response)
{
HttpSession session=Static::sessionStore->getSession(request,response,false);
YACReaderHttpSession *ySession = Static::yacreaderSessionStore->getYACReaderSessionHttpSession(session.getId());
response.setHeader("Content-Type", "text/html; charset=utf-8");
response.setHeader("Connection","close");
ySession->clearNavigationPath();
Template t=Static::templateLoader->getTemplate("libraries_"+ySession->getDeviceType(),request.getHeader("Accept-Language"));
t.enableWarnings();
YACReaderLibraries libraries = DBHelper::getLibraries();
QList<QString> names = DBHelper::getLibrariesNames();
t.loop("library",names.length());
int currentId = 0;
int i = 0;
foreach (QString name,names) {
currentId = libraries.getId(name);
t.setVariable(QString("library%1.name").arg(i),QString::number(currentId));
t.setVariable(QString("library%1.label").arg(i),name);
i++;
}
response.setStatus(200,"OK");
response.write(t.toUtf8(),true);
}

View File

@ -0,0 +1,99 @@
#include "pagecontroller.h"
#include "../static.h"
#include "comic.h"
#include "comiccontroller.h"
#include "yacreader_http_session.h"
#include <QDataStream>
#include <QPointer>
#include <QsLog.h>
#include "db_helper.h"
PageController::PageController() {}
void PageController::service(HttpRequest& request, HttpResponse& response)
{
HttpSession session=Static::sessionStore->getSession(request,response,false);
YACReaderHttpSession *ySession = Static::yacreaderSessionStore->getYACReaderSessionHttpSession(session.getId());
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
bool remote = path.endsWith("remote");
//QByteArray path2=request.getPath();
//qDebug("PageController: request to -> %s ",path2.data());
QStringList pathElements = path.split('/');
QString libraryName = DBHelper::getLibraryName(pathElements.at(2).toInt());
qulonglong comicId = pathElements.at(4).toULongLong();
unsigned int page = pathElements.at(6).toUInt();
//qDebug("lib name : %s",pathElements.at(2).data());
Comic * comicFile;
qulonglong currentComicId;
if(remote)
{
QLOG_TRACE() << "se recupera comic remoto para servir páginas";
comicFile = ySession->getCurrentRemoteComic();
currentComicId = ySession->getCurrentRemoteComicId();
}
else
{
QLOG_TRACE() << "se recupera comic para servir páginas";
comicFile = ySession->getCurrentComic();
currentComicId = ySession->getCurrentComicId();
}
if(currentComicId != 0 && !QPointer<Comic>(comicFile).isNull())
{
if(comicId == currentComicId && page < comicFile->numPages())
{
if(comicFile->pageIsLoaded(page))
{
//qDebug("PageController: La página estaba cargada -> %s ",path.data());
response.setHeader("Content-Type", "image/jpeg");
response.setHeader("Transfer-Encoding","chunked");
QByteArray pageData = comicFile->getRawPage(page);
QDataStream data(pageData);
char buffer[4096];
while (!data.atEnd()) {
int len = data.readRawData(buffer,4096);
response.write(QByteArray(buffer,len));
}
//response.write(pageData,true);
response.write(QByteArray(),true);
}
else
{
//qDebug("PageController: La página NO estaba cargada 404 -> %s ",path.data());
response.setStatus(404,"not found"); //TODO qué mensaje enviar
response.write("404 not found",true);
}
}
else
{
if(comicId != currentComicId)
{
//delete comicFile;
if(remote)
ySession->dismissCurrentRemoteComic();
else
ySession->dismissCurrentComic();
}
response.setStatus(404,"not found"); //TODO qué mensaje enviar
response.write("404 not found",true);
}
}
else
{
response.setStatus(404,"not found");
response.write("404 not found",true);
}
//response.write(t.toLatin1(),true);
}

View File

@ -55,7 +55,7 @@ void SyncController::service(HttpRequest &request, HttpResponse &response)
else
{
response.setStatus(412,"No comic info received");
response.writeText("",true);
response.write("",true);
return;
}

View File

@ -9,7 +9,7 @@
class SyncController : public HttpRequestHandler {
Q_OBJECT
Q_DISABLE_COPY(SyncController);
Q_DISABLE_COPY(SyncController)
public:
/** Constructor */
SyncController();

View File

@ -38,7 +38,7 @@ void UpdateComicController::service(HttpRequest &request, HttpResponse &response
else
{
response.setStatus(412,"No comic info received");
response.writeText("",true);
response.write("",true);
return;
}

View File

@ -1,7 +1,8 @@
#include "comiccontroller.h"
#include "comiccontroller_v2.h"
#include "db_helper.h"
#include "yacreader_libraries.h"
#include "yacreader_http_session.h"
#include "template.h"
#include "../static.h"
@ -13,17 +14,24 @@
#include <typeinfo>
ComicController::ComicController() {}
void ComicController::service(HttpRequest& request, HttpResponse& response)
{
HttpSession session=Static::sessionStore->getSession(request,response,false);
ComicControllerV2::ComicControllerV2() {}
void ComicControllerV2::service(HttpRequest& request, HttpResponse& response)
{
QByteArray token = request.getHeader("x-request-id");
YACReaderHttpSession *ySession = Static::yacreaderSessionStore->getYACReaderSessionHttpSession(token);
if (ySession == nullptr) {
response.setStatus(404,"not found");
response.write("404 not found",true);
return;
}
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
QStringList pathElements = path.split('/');
qulonglong libraryId = pathElements.at(2).toLongLong();
qulonglong libraryId = pathElements.at(3).toLongLong();
QString libraryName = DBHelper::getLibraryName(libraryId);
qulonglong comicId = pathElements.at(4).toULongLong();
qulonglong comicId = pathElements.at(5).toULongLong();
bool remoteComic = path.endsWith("remote");
@ -43,9 +51,6 @@ void ComicController::service(HttpRequest& request, HttpResponse& response)
ComicDB comic = DBHelper::getComicInfo(libraryId, comicId);
if(!remoteComic)
session.setDownloadedComic(comic.info.hash);
Comic * comicFile = FactoryComic::newComic(libraries.getPath(libraryId)+comic.path);
if(comicFile != NULL)
@ -70,19 +75,19 @@ void ComicController::service(HttpRequest& request, HttpResponse& response)
if(remoteComic)
{
QLOG_TRACE() << "remote comic requested";
session.setCurrentRemoteComic(comic.id, comicFile);
ySession->setCurrentRemoteComic(comic.id, comicFile);
}
else
{
QLOG_TRACE() << "comic requested";
session.setCurrentComic(comic.id, comicFile);
ySession->setCurrentComic(comic.id, comicFile);
}
response.setHeader("Content-Type", "plain/text; charset=utf-8");
response.setHeader("Content-Type", "text/plain; charset=utf-8");
//TODO this field is not used by the client!
response.writeText(QString("library:%1\r\n").arg(libraryName));
response.writeText(QString("libraryId:%1\r\n").arg(libraryId));
response.write(QString("library:%1\r\n").arg(libraryName).toUtf8());
response.write(QString("libraryId:%1\r\n").arg(libraryId).toUtf8());
if(remoteComic) //send previous and next comics id
{
QList<LibraryItem *> siblings = DBHelper::getFolderComicsFromLibrary(libraryId, comic.parentId, true);
@ -99,9 +104,9 @@ void ComicController::service(HttpRequest& request, HttpResponse& response)
if(found)
{
if(i>0)
response.writeText(QString("previousComic:%1\r\n").arg(siblings.at(i-1)->id));
response.write(QString("previousComic:%1\r\n").arg(siblings.at(i-1)->id).toUtf8());
if(i<siblings.length()-1)
response.writeText(QString("nextComic:%1\r\n").arg(siblings.at(i+1)->id));
response.write(QString("nextComic:%1\r\n").arg(siblings.at(i+1)->id).toUtf8());
}
else
{
@ -109,7 +114,7 @@ void ComicController::service(HttpRequest& request, HttpResponse& response)
}
qDeleteAll(siblings);
}
response.writeText(comic.toTXT(),true);
response.write(comic.toTXT().toUtf8(),true);
}
else
{

View File

@ -0,0 +1,23 @@
#ifndef COMICCONTROLLER_V2_H
#define COMICCONTROLLER_V2_H
#include "httprequest.h"
#include "httpresponse.h"
#include "httprequesthandler.h"
#include <QThread>
class Comic;
class QString;
class ComicControllerV2 : public HttpRequestHandler {
Q_OBJECT
Q_DISABLE_COPY(ComicControllerV2)
public:
/** Constructor */
ComicControllerV2();
/** Generates the response */
void service(HttpRequest& request, HttpResponse& response);
};
#endif // COMICCONTROLLER_H

View File

@ -0,0 +1,27 @@
#include "comicdownloadinfocontroller_v2.h"
#include "db_helper.h"
#include "yacreader_libraries.h"
#include "comic_db.h"
ComicDownloadInfoControllerV2::ComicDownloadInfoControllerV2() {}
void ComicDownloadInfoControllerV2::service(HttpRequest& request, HttpResponse& response)
{
response.setHeader("Content-Type", "text/plain; charset=utf-8");
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
QStringList pathElements = path.split('/');
qulonglong libraryId = pathElements.at(3).toLongLong();
qulonglong comicId = pathElements.at(5).toULongLong();
ComicDB comic = DBHelper::getComicInfo(libraryId, comicId);
//TODO: check if the comic wasn't found;
response.write(QString("fileName:%1\r\n").arg(comic.getFileName()).toUtf8());
response.write(QString("fileSize:%1\r\n").arg(comic.getFileSize()).toUtf8());
response.write(QString("hash:%1\r\n").arg(comic.info.hash).toUtf8(),true);
}

View File

@ -0,0 +1,19 @@
#ifndef COMICDOWNLOADINFOCONTROLLER_V2_H
#define COMICDOWNLOADINFOCONTROLLER_V2_H
#include "httprequest.h"
#include "httpresponse.h"
#include "httprequesthandler.h"
class ComicDownloadInfoControllerV2 : public HttpRequestHandler {
Q_OBJECT
Q_DISABLE_COPY(ComicDownloadInfoControllerV2)
public:
/** Constructor **/
ComicDownloadInfoControllerV2();
/** Generates the response */
void service(HttpRequest& request, HttpResponse& response);
};
#endif // COMICDOWNLOADINFOCONTROLLER_H

View File

@ -0,0 +1,46 @@
#include "comicfullinfocontroller_v2.h"
#include <QUrl>
#include "db_helper.h"
#include "comic_db.h"
#include "folder.h"
#include "yacreader_server_data_helper.h"
#include "qnaturalsorting.h"
#include <ctime>
using namespace std;
ComicFullinfoController_v2::ComicFullinfoController_v2() {}
void ComicFullinfoController_v2::service(HttpRequest& request, HttpResponse& response)
{
response.setHeader("Content-Type", "application/json");
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
QStringList pathElements = path.split('/');
int libraryId = pathElements.at(3).toInt();
qulonglong comicId = pathElements.at(5).toULongLong();
serviceContent(libraryId, comicId, response);
response.setStatus(200,"OK");
response.write("",true);
}
void ComicFullinfoController_v2::serviceContent(const int &libraryId, const qulonglong &comicId, HttpResponse &response)
{
ComicDB comic = DBHelper::getComicInfo(libraryId, comicId);
QJsonObject json = YACReaderServerDataHelper::fullComicToJSON(libraryId, comic);
QJsonDocument output(json);
response.write(output.toJson(QJsonDocument::Compact));
}

View File

@ -0,0 +1,24 @@
#ifndef COMICFULLINFOCONTROLLER_V2_H
#define COMICFULLINFOCONTROLLER_V2_H
#include "httprequest.h"
#include "httpresponse.h"
#include "httprequesthandler.h"
class ComicFullinfoController_v2 : public HttpRequestHandler {
Q_OBJECT
Q_DISABLE_COPY(ComicFullinfoController_v2)
public:
ComicFullinfoController_v2();
void service(HttpRequest& request, HttpResponse& response);
private:
void serviceContent(const int &library, const qulonglong &comicId, HttpResponse &response);
};
#endif // COMICFULLINFOCONTROLLER_V2_H

View File

@ -1,17 +1,15 @@
#include "covercontroller.h"
#include "covercontroller_v2.h"
#include "db_helper.h" //get libraries
#include "yacreader_libraries.h"
#include "yacreader_http_session.h"
#include "template.h"
#include "../static.h"
CoverController::CoverController() {}
CoverControllerV2::CoverControllerV2() {}
void CoverController::service(HttpRequest& request, HttpResponse& response)
void CoverControllerV2::service(HttpRequest& request, HttpResponse& response)
{
HttpSession session=Static::sessionStore->getSession(request,response,false);
response.setHeader("Content-Type", "image/jpeg");
response.setHeader("Connection","close");
//response.setHeader("Content-Type", "plain/text; charset=ISO-8859-1");
@ -20,10 +18,8 @@ void CoverController::service(HttpRequest& request, HttpResponse& response)
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
QStringList pathElements = path.split('/');
QString libraryName = DBHelper::getLibraryName(pathElements.at(2).toInt());
QString fileName = pathElements.at(4);
bool folderCover = request.getParameter("folderCover").length()>0;
QString libraryName = DBHelper::getLibraryName(pathElements.at(3).toInt());
QString fileName = pathElements.at(5);
//response.writeText(path+"<br/>");
//response.writeText(libraryName+"<br/>");
@ -46,8 +42,8 @@ void CoverController::service(HttpRequest& request, HttpResponse& response)
QImage img(libraries.getPath(libraryName)+"/.yacreaderlibrary/covers/"+fileName);
if (!img.isNull()) {
int width = 80, height = 120;
if(session.getDisplayType()=="@2x")
/*int width = 80, height = 120;
if(ySession->getDisplayType()=="@2x")
{
width = 160;
height = 240;
@ -66,16 +62,16 @@ void CoverController::service(HttpRequest& request, HttpResponse& response)
if(folderCover)
{
if(session.getDisplayType()=="@2x")
if(ySession->getDisplayType()=="@2x")
p.drawImage(0,0,QImage(":/images/f_overlayed_retina.png"));
else
p.drawImage(0,0,QImage(":/images/f_overlayed.png"));
}
*/
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
destImg.save(&buffer, "JPG");
img.save(&buffer, "JPG");
response.write(ba,true);
}
//DONE else, hay que devolver un 404

View File

@ -0,0 +1,20 @@
#ifndef COVERCONTROLLER_V2_H
#define COVERCONTROLLER_V2_H
#include "httprequest.h"
#include "httpresponse.h"
#include "httprequesthandler.h"
class CoverControllerV2 : public HttpRequestHandler {
Q_OBJECT
Q_DISABLE_COPY(CoverControllerV2)
public:
/** Constructor */
CoverControllerV2();
/** Generates the response */
void service(HttpRequest& request, HttpResponse& response);
};
#endif // COVERCONTROLLER_H

View File

@ -0,0 +1,26 @@
#include "errorcontroller_v2.h"
#include "template.h"
#include "../static.h"
ErrorControllerV2::ErrorControllerV2(int errorCode)
:error(errorCode)
{}
void ErrorControllerV2::service(HttpRequest& request, HttpResponse& response)
{
Q_UNUSED(request)
switch(error)
{
case 300:
response.setStatus(300,"redirect");
response.write("<html> <head> <meta http-equiv=\"refresh\" content=\"0; URL=/\"> </head> <body> </body> </html>", true);
break;
case 404:
response.setStatus(404,"not found");
response.write("404 not found",true);
break;
}
}

View File

@ -0,0 +1,22 @@
#ifndef ERRORCONTROLLER_V2_H
#define ERRORCONTROLLER_V2_H
#include "httprequest.h"
#include "httpresponse.h"
#include "httprequesthandler.h"
class ErrorControllerV2 : public HttpRequestHandler {
Q_OBJECT
Q_DISABLE_COPY(ErrorControllerV2)
public:
/** Constructor */
ErrorControllerV2(int errorCode);
/** Generates the response */
void service(HttpRequest& request, HttpResponse& response);
private:
int error;
};
#endif // ERRORCONTROLLER_H

View File

@ -0,0 +1,39 @@
#include "favoritescontroller_v2.h"
#include "db_helper.h"
#include "comic_db.h"
#include "yacreader_server_data_helper.h"
FavoritesControllerV2::FavoritesControllerV2() {}
void FavoritesControllerV2::service(HttpRequest &request, HttpResponse &response)
{
response.setHeader("Content-Type", "text/plain; charset=utf-8");
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
QStringList pathElements = path.split('/');
int libraryId = pathElements.at(3).toInt();
serviceContent(libraryId, response);
response.write("",true);
}
void FavoritesControllerV2::serviceContent(const int library, HttpResponse &response)
{
QList<ComicDB> comics = DBHelper::getFavorites(library);
QJsonArray items;
for(const ComicDB &comic : comics)
{
items.append(YACReaderServerDataHelper::comicToJSON(library, comic));
}
QJsonDocument output(items);
response.write(output.toJson(QJsonDocument::Compact));
}

View File

@ -0,0 +1,21 @@
#ifndef FAVORITESCONTROLLER_V2_H
#define FAVORITESCONTROLLER_V2_H
#include "httprequest.h"
#include "httpresponse.h"
#include "httprequesthandler.h"
class FavoritesControllerV2 : public HttpRequestHandler {
Q_OBJECT
Q_DISABLE_COPY(FavoritesControllerV2)
public:
FavoritesControllerV2();
void service(HttpRequest& request, HttpResponse& response);
private:
void serviceContent(const int library, HttpResponse &response);
};
#endif // FAVORITESCONTROLLER_H

View File

@ -0,0 +1,83 @@
#include "foldercontentcontroller_v2.h"
#include <QUrl>
#include "db_helper.h"
#include "comic_db.h"
#include "folder.h"
#include "yacreader_server_data_helper.h"
#include "qnaturalsorting.h"
#include "QsLog.h"
#include <ctime>
using namespace std;
struct LibraryItemSorter
{
bool operator()(const LibraryItem * a,const LibraryItem * b) const
{
return naturalSortLessThanCI(a->name,b->name);
}
};
FolderContentControllerV2::FolderContentControllerV2() {}
void FolderContentControllerV2::service(HttpRequest& request, HttpResponse& response)
{
response.setHeader("Content-Type", "application/json");
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
QStringList pathElements = path.split('/');
int libraryId = pathElements.at(3).toInt();
qulonglong parentId = pathElements.at(5).toULongLong();
serviceContent(libraryId, parentId, response);
response.setStatus(200,"OK");
response.write("",true);
}
void FolderContentControllerV2::serviceContent(const int &library, const qulonglong &folderId, HttpResponse &response)
{
#ifdef QT_DEBUG
auto started = std::chrono::high_resolution_clock::now();
#endif
QList<LibraryItem *> folderContent = DBHelper::getFolderSubfoldersFromLibrary(library,folderId);
QList<LibraryItem *> folderComics = DBHelper::getFolderComicsFromLibrary(library,folderId);
folderContent.append(folderComics);
qSort(folderContent.begin(),folderContent.end(),LibraryItemSorter());
folderComics.clear();
QJsonArray items;
ComicDB * currentComic;
Folder * currentFolder;
for(QList<LibraryItem *>::const_iterator itr = folderContent.constBegin();itr!=folderContent.constEnd();itr++)
{
if((*itr)->isDir())
{
currentFolder = (Folder *)(*itr);
items.append(YACReaderServerDataHelper::folderToJSON(library, *currentFolder));
}
else
{
currentComic = (ComicDB *)(*itr);
items.append(YACReaderServerDataHelper::comicToJSON(library, *currentComic));
}
}
QJsonDocument output(items);
response.write(output.toJson(QJsonDocument::Compact));
#ifdef QT_DEBUG
auto done = std::chrono::high_resolution_clock::now();
QLOG_TRACE() << "num items = " << items.count();
QLOG_TRACE() << std::chrono::duration_cast<std::chrono::milliseconds>(done-started).count();
#endif
}

View File

@ -0,0 +1,22 @@
#ifndef FOLDERCONTENTCONTROLLER_V2_H
#define FOLDERCONTENTCONTROLLER_V2_H
#include "httprequest.h"
#include "httpresponse.h"
#include "httprequesthandler.h"
class FolderContentControllerV2 : public HttpRequestHandler {
Q_OBJECT
Q_DISABLE_COPY(FolderContentControllerV2)
public:
/** Constructor */
FolderContentControllerV2();
/** Generates the response */
void service(HttpRequest& request, HttpResponse& response);
private:
void serviceContent(const int &library, const qulonglong &folderId, HttpResponse &response);
};
#endif // FOLDERCONTENTCONTROLLER_H

View File

@ -0,0 +1,55 @@
#include "folderinfocontroller_v2.h"
#include "db_helper.h" //get libraries
#include "folder.h"
#include "comic_db.h"
#include "template.h"
#include "../static.h"
FolderInfoControllerV2::FolderInfoControllerV2() {}
void FolderInfoControllerV2::service(HttpRequest& request, HttpResponse& response)
{
response.setHeader("Content-Type", "text/plain; charset=utf-8");
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
QStringList pathElements = path.split('/');
int libraryId = pathElements.at(3).toInt();
QString libraryName = DBHelper::getLibraryName(libraryId);
qulonglong parentId = pathElements.at(5).toULongLong();
serviceComics(libraryId, parentId, response);
response.write("",true);
}
void FolderInfoControllerV2::serviceComics(const int &library, const qulonglong &folderId, HttpResponse &response)
{
QList<LibraryItem *> folderContent = DBHelper::getFolderSubfoldersFromLibrary(library,folderId);
QList<LibraryItem *> folderComics = DBHelper::getFolderComicsFromLibrary(library,folderId);
ComicDB * currentComic;
for(QList<LibraryItem *>::const_iterator itr = folderComics.constBegin();itr!=folderComics.constEnd();itr++)
{
currentComic = (ComicDB *)(*itr);
response.write(QString("/v2/library/%1/comic/%2:%3:%4:%5:%6\r\n")
.arg(library)
.arg(currentComic->id)
.arg(currentComic->getFileName())
.arg(currentComic->getFileSize())
.arg(currentComic->info.read ? 1 : 0)
.arg(currentComic->info.hash)
.toUtf8());
delete currentComic;
}
Folder * currentFolder;
for(QList<LibraryItem *>::const_iterator itr = folderContent.constBegin();itr!=folderContent.constEnd();itr++)
{
currentFolder = (Folder *)(*itr);
serviceComics(library, currentFolder->id, response);
delete currentFolder;
}
}

View File

@ -0,0 +1,23 @@
#ifndef FOLDERINFOCONTROLLER_V2_H
#define FOLDERINFOCONTROLLER_V2_H
#include "httprequest.h"
#include "httpresponse.h"
#include "httprequesthandler.h"
class FolderInfoControllerV2 : public HttpRequestHandler {
Q_OBJECT
Q_DISABLE_COPY(FolderInfoControllerV2)
public:
/** Constructor */
FolderInfoControllerV2();
/** Generates the response */
void service(HttpRequest& request, HttpResponse& response);
private:
void serviceComics(const int &library, const qulonglong & folderId, HttpResponse& response);
};
#endif // FOLDERINFOCONTROLLER_H

View File

@ -0,0 +1,37 @@
#include "librariescontroller_v2.h"
#include "db_helper.h" //get libraries
#include "yacreader_libraries.h"
#include "template.h"
#include "../static.h"
#include "QsLog.h"
LibrariesControllerV2::LibrariesControllerV2() {}
void LibrariesControllerV2::service(HttpRequest& request, HttpResponse& response)
{
response.setHeader("Content-Type", "application/json");
response.setHeader("Connection","close");
YACReaderLibraries libraries = DBHelper::getLibraries();
QList<QString> names = DBHelper::getLibrariesNames();
QJsonArray librariesJson;
int currentId = 0;
foreach (QString name,names) {
currentId = libraries.getId(name);
QJsonObject library;
library["name"] = name;
library["id"] = currentId;
librariesJson.append(library);
}
QJsonDocument output(librariesJson);
response.setStatus(200,"OK");
response.write(output.toJson(QJsonDocument::Compact),true);
}

View File

@ -1,10 +1,5 @@
/**
@file
@author Stefan Frings
*/
#ifndef FORMCONTROLLER_H
#define FORMCONTROLLER_H
#ifndef LIBRARIESCONTROLLER_V2_H
#define LIBRARIESCONTROLLER_V2_H
#include "httprequest.h"
#include "httpresponse.h"
@ -15,16 +10,16 @@
*/
class FormController : public HttpRequestHandler {
class LibrariesControllerV2 : public HttpRequestHandler {
Q_OBJECT
Q_DISABLE_COPY(FormController);
Q_DISABLE_COPY(LibrariesControllerV2)
public:
/** Constructor */
FormController();
LibrariesControllerV2();
/** Generates the response */
void service(HttpRequest& request, HttpResponse& response);
};
#endif // FORMCONTROLLER_H
#endif // LIBRARIESCONTROLLER_H

View File

@ -0,0 +1,111 @@
#include "pagecontroller_v2.h"
#include "../static.h"
#include "comic.h"
#include "comiccontroller.h"
#include "yacreader_http_session.h"
#include <QDataStream>
#include <QPointer>
#include <QsLog.h>
#include "db_helper.h"
PageControllerV2::PageControllerV2() {}
void PageControllerV2::service(HttpRequest& request, HttpResponse& response)
{
QByteArray token = request.getHeader("x-request-id");
YACReaderHttpSession *ySession = Static::yacreaderSessionStore->getYACReaderSessionHttpSession(token);
if (ySession == nullptr) {
response.setStatus(424,"no session for this comic");
response.write("424 no session for this comic",true);
return;
}
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
bool remote = path.endsWith("remote");
QStringList pathElements = path.split('/');
QString libraryName = DBHelper::getLibraryName(pathElements.at(2).toInt());
qulonglong comicId = pathElements.at(5).toULongLong();
unsigned int page = pathElements.at(7).toUInt();
Comic * comicFile;
qulonglong currentComicId;
if(remote)
{
QLOG_TRACE() << "se recupera comic remoto para servir páginas";
comicFile = ySession->getCurrentRemoteComic();
currentComicId = ySession->getCurrentRemoteComicId();
}
else
{
QLOG_TRACE() << "se recupera comic para servir páginas";
comicFile = ySession->getCurrentComic();
currentComicId = ySession->getCurrentComicId();
}
if (comicFile->hasBeenAnErrorOpening()) {
//delete comicFile;
if(remote)
ySession->dismissCurrentRemoteComic();
else
ySession->dismissCurrentComic();
response.setStatus(404,"not found");
response.write("404 not found",true);
return;
}
if(currentComicId != 0 && !QPointer<Comic>(comicFile).isNull())
{
if (comicFile->numPages() == 0) {
response.setStatus(412,"opening file");
response.write("412 opening file",true);
} else {
if(comicId == currentComicId && page < comicFile->numPages())
{
if(comicFile->pageIsLoaded(page))
{
response.setHeader("Content-Type", "image/jpeg");
response.setHeader("Transfer-Encoding","chunked");
QByteArray pageData = comicFile->getRawPage(page);
QDataStream data(pageData);
char buffer[100000];
while (!data.atEnd()) {
int len = data.readRawData(buffer,100000);
response.write(QByteArray(buffer,len));
}
response.write(QByteArray(),true);
}
else
{
response.setStatus(412,"loading page");
response.write("412 loading page",true);
}
}
else
{
if(comicId != currentComicId)
{
//delete comicFile;
if(remote)
ySession->dismissCurrentRemoteComic();
else
ySession->dismissCurrentComic();
}
response.setStatus(404,"not found");
response.write("404 not found",true);
}
}
}
else
{
response.setStatus(404,"not found");
response.write("404 not found",true);
}
}

View File

@ -0,0 +1,20 @@
#ifndef PAGECONTROLLER_V2_H
#define PAGECONTROLLER_V2_H
#include "httprequest.h"
#include "httpresponse.h"
#include "httprequesthandler.h"
class PageControllerV2 : public HttpRequestHandler {
Q_OBJECT
Q_DISABLE_COPY(PageControllerV2)
public:
/** Constructor */
PageControllerV2();
/** Generates the response */
void service(HttpRequest& request, HttpResponse& response);
};
#endif // PAGECONTROLLER_H

View File

@ -0,0 +1,41 @@
#include "readingcomicscontroller_v2.h"
#include "db_helper.h"
#include "comic_db.h"
#include "yacreader_server_data_helper.h"
ReadingComicsControllerV2::ReadingComicsControllerV2()
{
}
void ReadingComicsControllerV2::service(HttpRequest &request, HttpResponse &response)
{
response.setHeader("Content-Type", "application/json");
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
QStringList pathElements = path.split('/');
int libraryId = pathElements.at(3).toInt();
serviceContent(libraryId, response);
response.setStatus(200,"OK");
response.write("",true);
}
void ReadingComicsControllerV2::serviceContent(const int &library, HttpResponse &response)
{
QList<ComicDB> readingComics = DBHelper::getReading(library);
QJsonArray comics;
for(const ComicDB &comic : readingComics)
{
comics.append(YACReaderServerDataHelper::comicToJSON(library, comic));
}
QJsonDocument output(comics);
response.write(output.toJson(QJsonDocument::Compact));
}

View File

@ -0,0 +1,20 @@
#ifndef READINGCOMICSCONTROLLER_V2_H
#define READINGCOMICSCONTROLLER_V2_H
#include "httprequest.h"
#include "httpresponse.h"
#include "httprequesthandler.h"
class ReadingComicsControllerV2 : public HttpRequestHandler {
Q_OBJECT
Q_DISABLE_COPY(ReadingComicsControllerV2)
public:
ReadingComicsControllerV2();
void service(HttpRequest& request, HttpResponse& response);
private:
void serviceContent(const int &library, HttpResponse &response);
};
#endif // READINGCOMICSCONTROLLER_H

View File

@ -0,0 +1,41 @@
#include "readinglistcontentcontroller_v2.h"
#include "db_helper.h"
#include "comic_db.h"
#include "yacreader_server_data_helper.h"
ReadingListContentControllerV2::ReadingListContentControllerV2()
{
}
void ReadingListContentControllerV2::service(HttpRequest &request, HttpResponse &response)
{
response.setHeader("Content-Type", "text/plain; charset=utf-8");
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
QStringList pathElements = path.split('/');
int libraryId = pathElements.at(3).toInt();
qulonglong readingListId = pathElements.at(5).toULongLong();
serviceContent(libraryId, readingListId, response);
response.write("",true);
}
void ReadingListContentControllerV2::serviceContent(const int &library, const qulonglong &readingListId, HttpResponse &response)
{
QList<ComicDB> comics = DBHelper::getReadingListFullContent(library, readingListId);
QJsonArray items;
for(const ComicDB &comic : comics)
{
items.append(YACReaderServerDataHelper::comicToJSON(library, comic));
}
QJsonDocument output(items);
response.write(output.toJson(QJsonDocument::Compact));
}

Some files were not shown because too many files have changed in this diff Show More