mirror of
https://github.com/YACReader/yacreader
synced 2025-05-28 03:10:27 -04:00
Merge pull request #155 from YACReader/bidirectional_sync_support
Bidirectional sync support
This commit is contained in:
commit
fef734d132
@ -6,11 +6,12 @@ spanish only. Sorry for the mess.
|
|||||||
|
|
||||||
Version counting is based on semantic versioning (Major.Feature.Patch)
|
Version counting is based on semantic versioning (Major.Feature.Patch)
|
||||||
|
|
||||||
## 9.6.7 (unreleased)
|
## 9.7.0 (unreleased)
|
||||||
|
|
||||||
### YACReaderLibrary
|
### YACReaderLibrary
|
||||||
* update QsLog logger to version 2.1, snapshot 46b643d5bcbc
|
* update QsLog logger to version 2.1, snapshot 46b643d5bcbc
|
||||||
* fix object leaks in database code
|
* fix object leaks in database code
|
||||||
|
* add bidirectional sync support
|
||||||
|
|
||||||
## 9.6.0
|
## 9.6.0
|
||||||
### Reader and Library
|
### Reader and Library
|
||||||
|
@ -798,6 +798,7 @@ QVector<YACReaderComicReadStatus> ComicModel::setComicsRead(QList<QModelIndex> l
|
|||||||
c.info.read = false;
|
c.info.read = false;
|
||||||
c.info.currentPage = 1;
|
c.info.currentPage = 1;
|
||||||
c.info.hasBeenOpened = false;
|
c.info.hasBeenOpened = false;
|
||||||
|
c.info.lastTimeOpened.setValue(QVariant());
|
||||||
DBHelper::update(&(c.info), db);
|
DBHelper::update(&(c.info), db);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -827,10 +827,15 @@ void DBHelper::updateFromRemoteClientWithHash(const ComicInfo &comicInfo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBHelper::updateFromRemoteClient(const QMap<qulonglong, QList<ComicInfo>> &comics)
|
QMap<qulonglong, QList<ComicDB>> DBHelper::updateFromRemoteClient(const QMap<qulonglong, QList<ComicInfo>> &comics)
|
||||||
{
|
{
|
||||||
|
QMap<qulonglong, QList<ComicDB>> moreRecentComics;
|
||||||
|
|
||||||
foreach (qulonglong libraryId, comics.keys()) {
|
foreach (qulonglong libraryId, comics.keys()) {
|
||||||
|
QList<ComicDB> libraryMoreRecentComics;
|
||||||
|
|
||||||
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
|
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
|
||||||
|
|
||||||
QString connectionName = "";
|
QString connectionName = "";
|
||||||
{
|
{
|
||||||
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath + "/.yacreaderlibrary");
|
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath + "/.yacreaderlibrary");
|
||||||
@ -850,37 +855,58 @@ void DBHelper::updateFromRemoteClient(const QMap<qulonglong, QList<ComicInfo>> &
|
|||||||
ComicDB comic = DBHelper::loadComic(comicInfo.id, db);
|
ComicDB comic = DBHelper::loadComic(comicInfo.id, db);
|
||||||
|
|
||||||
if (comic.info.hash == comicInfo.hash) {
|
if (comic.info.hash == comicInfo.hash) {
|
||||||
if (comicInfo.currentPage > 0) {
|
bool isMoreRecent = false;
|
||||||
comic.info.currentPage = comicInfo.currentPage;
|
|
||||||
|
|
||||||
if (comic.info.currentPage == comic.info.numPages)
|
//completion takes precedence over lastTimeOpened, if we just want to synchronize the lastest status we should use only lastTimeOpened
|
||||||
comic.info.read = true;
|
if ((comic.info.currentPage > 1 && comic.info.currentPage > comicInfo.currentPage) || comic.info.hasBeenOpened || (comic.info.read && !comicInfo.read)) {
|
||||||
|
isMoreRecent = true;
|
||||||
comic.info.hasBeenOpened = true;
|
|
||||||
|
|
||||||
if (comic.info.lastTimeOpened.toULongLong() < comicInfo.lastTimeOpened.toULongLong())
|
|
||||||
comic.info.lastTimeOpened = comicInfo.lastTimeOpened;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (comic.info.lastTimeOpened.toULongLong() > 0 && comicInfo.lastTimeOpened.toULongLong() == 0) {
|
||||||
|
isMoreRecent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
comic.info.currentPage = qMax(comic.info.currentPage, comicInfo.currentPage);
|
||||||
|
|
||||||
|
if (comic.info.currentPage == comic.info.numPages)
|
||||||
|
comic.info.read = true;
|
||||||
|
|
||||||
|
comic.info.read = comic.info.read || comicInfo.read;
|
||||||
|
|
||||||
|
comic.info.hasBeenOpened = comic.info.hasBeenOpened || comicInfo.currentPage > 0;
|
||||||
|
|
||||||
|
if (comic.info.lastTimeOpened.toULongLong() < comicInfo.lastTimeOpened.toULongLong() && comicInfo.lastTimeOpened.toULongLong() > 0)
|
||||||
|
comic.info.lastTimeOpened = comicInfo.lastTimeOpened;
|
||||||
|
|
||||||
if (comicInfo.rating > 0)
|
if (comicInfo.rating > 0)
|
||||||
comic.info.rating = comicInfo.rating;
|
comic.info.rating = comicInfo.rating;
|
||||||
|
|
||||||
updateComicInfo.bindValue(":read", comic.info.read ? 1 : 0);
|
updateComicInfo.bindValue(":read", comic.info.read ? 1 : 0);
|
||||||
updateComicInfo.bindValue(":currentPage", comic.info.currentPage);
|
updateComicInfo.bindValue(":currentPage", comic.info.currentPage);
|
||||||
updateComicInfo.bindValue(":hasBeenOpened", comic.info.hasBeenOpened ? 1 : 0);
|
updateComicInfo.bindValue(":hasBeenOpened", comic.info.hasBeenOpened ? 1 : 0);
|
||||||
updateComicInfo.bindValue(":lastTimeOpened", QDateTime::currentMSecsSinceEpoch() / 1000);
|
updateComicInfo.bindValue(":lastTimeOpened", comic.info.lastTimeOpened);
|
||||||
updateComicInfo.bindValue(":id", comic.info.id);
|
updateComicInfo.bindValue(":id", comic.info.id);
|
||||||
updateComicInfo.bindValue(":rating", comic.info.rating);
|
updateComicInfo.bindValue(":rating", comic.info.rating);
|
||||||
updateComicInfo.exec();
|
updateComicInfo.exec();
|
||||||
|
|
||||||
|
if (isMoreRecent) {
|
||||||
|
libraryMoreRecentComics.append(comic);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!libraryMoreRecentComics.isEmpty()) {
|
||||||
|
moreRecentComics[libraryId] = libraryMoreRecentComics;
|
||||||
|
}
|
||||||
|
|
||||||
db.commit();
|
db.commit();
|
||||||
connectionName = db.connectionName();
|
connectionName = db.connectionName();
|
||||||
}
|
}
|
||||||
|
|
||||||
QSqlDatabase::removeDatabase(connectionName);
|
QSqlDatabase::removeDatabase(connectionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return moreRecentComics;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBHelper::updateFromRemoteClientWithHash(const QList<ComicInfo> &comics)
|
void DBHelper::updateFromRemoteClientWithHash(const QList<ComicInfo> &comics)
|
||||||
|
@ -72,7 +72,7 @@ public:
|
|||||||
static void updateFromRemoteClient(qulonglong libraryId, const ComicInfo &comicInfo);
|
static void updateFromRemoteClient(qulonglong libraryId, const ComicInfo &comicInfo);
|
||||||
static void updateFromRemoteClientWithHash(const ComicInfo &comicInfo);
|
static void updateFromRemoteClientWithHash(const ComicInfo &comicInfo);
|
||||||
static void updateReadingRemoteProgress(const ComicInfo &comicInfo, QSqlDatabase &db);
|
static void updateReadingRemoteProgress(const ComicInfo &comicInfo, QSqlDatabase &db);
|
||||||
static void updateFromRemoteClient(const QMap<qulonglong, QList<ComicInfo>> &comics);
|
static QMap<qulonglong, QList<ComicDB>> updateFromRemoteClient(const QMap<qulonglong, QList<ComicInfo>> &comics);
|
||||||
static void updateFromRemoteClientWithHash(const QList<ComicInfo> &comics);
|
static void updateFromRemoteClientWithHash(const QList<ComicInfo> &comics);
|
||||||
static void renameLabel(qulonglong id, const QString &name, QSqlDatabase &db);
|
static void renameLabel(qulonglong id, const QString &name, QSqlDatabase &db);
|
||||||
static void renameList(qulonglong id, const QString &name, QSqlDatabase &db);
|
static void renameList(qulonglong id, const QString &name, QSqlDatabase &db);
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "comic_db.h"
|
#include "comic_db.h"
|
||||||
#include "db_helper.h"
|
#include "db_helper.h"
|
||||||
|
#include "yacreader_server_data_helper.h"
|
||||||
|
|
||||||
using stefanfrings::HttpRequest;
|
using stefanfrings::HttpRequest;
|
||||||
using stefanfrings::HttpResponse;
|
using stefanfrings::HttpResponse;
|
||||||
@ -15,13 +16,13 @@ SyncControllerV2::SyncControllerV2()
|
|||||||
|
|
||||||
void SyncControllerV2::service(HttpRequest &request, HttpResponse &response)
|
void SyncControllerV2::service(HttpRequest &request, HttpResponse &response)
|
||||||
{
|
{
|
||||||
|
response.setHeader("Content-Type", "text/plain; charset=utf-8");
|
||||||
|
|
||||||
QString postData = QString::fromUtf8(request.getBody());
|
QString postData = QString::fromUtf8(request.getBody());
|
||||||
|
|
||||||
QLOG_TRACE() << "POST DATA: " << postData;
|
QLOG_TRACE() << "POST DATA: " << postData;
|
||||||
|
|
||||||
if (postData.length() > 0) {
|
if (postData.length() > 0) {
|
||||||
response.write("OK", true);
|
|
||||||
|
|
||||||
QList<QString> data = postData.split("\n");
|
QList<QString> data = postData.split("\n");
|
||||||
|
|
||||||
qulonglong libraryId;
|
qulonglong libraryId;
|
||||||
@ -35,7 +36,7 @@ void SyncControllerV2::service(HttpRequest &request, HttpResponse &response)
|
|||||||
foreach (QString comicInfo, data) {
|
foreach (QString comicInfo, data) {
|
||||||
QList<QString> comicInfoProgress = comicInfo.split("\t");
|
QList<QString> comicInfoProgress = comicInfo.split("\t");
|
||||||
|
|
||||||
if (comicInfoProgress.length() == 6) {
|
if (comicInfoProgress.length() >= 6) {
|
||||||
if (comicInfoProgress.at(0) != "unknown") {
|
if (comicInfoProgress.at(0) != "unknown") {
|
||||||
libraryId = comicInfoProgress.at(0).toULongLong();
|
libraryId = comicInfoProgress.at(0).toULongLong();
|
||||||
comicId = comicInfoProgress.at(1).toULongLong();
|
comicId = comicInfoProgress.at(1).toULongLong();
|
||||||
@ -52,6 +53,11 @@ void SyncControllerV2::service(HttpRequest &request, HttpResponse &response)
|
|||||||
|
|
||||||
lastTimeOpened = comicInfoProgress.at(5).toULong();
|
lastTimeOpened = comicInfoProgress.at(5).toULong();
|
||||||
info.lastTimeOpened = lastTimeOpened;
|
info.lastTimeOpened = lastTimeOpened;
|
||||||
|
|
||||||
|
if (comicInfoProgress.length() >= 7) {
|
||||||
|
info.read = comicInfoProgress.at(6).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
if (!comics.contains(libraryId)) {
|
if (!comics.contains(libraryId)) {
|
||||||
comics[libraryId] = QList<ComicInfo>();
|
comics[libraryId] = QList<ComicInfo>();
|
||||||
}
|
}
|
||||||
@ -75,11 +81,26 @@ void SyncControllerV2::service(HttpRequest &request, HttpResponse &response)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DBHelper::updateFromRemoteClient(comics);
|
auto moreRecentComicsFound = DBHelper::updateFromRemoteClient(comics);
|
||||||
|
|
||||||
|
QJsonArray items;
|
||||||
|
|
||||||
|
foreach (qulonglong libraryId, moreRecentComicsFound.keys()) {
|
||||||
|
foreach (ComicDB comic, moreRecentComicsFound[libraryId]) {
|
||||||
|
items.append(YACReaderServerDataHelper::comicToJSON(libraryId, comic));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonDocument output(items);
|
||||||
|
|
||||||
|
response.write(output.toJson(QJsonDocument::Compact), true);
|
||||||
|
|
||||||
|
//TODO does it make sense to send these back? The source is not YACReaderLibrary...
|
||||||
DBHelper::updateFromRemoteClientWithHash(comicsWithNoLibrary);
|
DBHelper::updateFromRemoteClientWithHash(comicsWithNoLibrary);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
response.setStatus(412, "No comic info received");
|
response.setStatus(412, "No comic info received");
|
||||||
response.write("", true);
|
response.write("[]", true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ QJsonObject YACReaderServerDataHelper::comicToJSON(const qulonglong libraryId, c
|
|||||||
json["cover_size_ratio"] = comic.info.coverSizeRatio.toFloat();
|
json["cover_size_ratio"] = comic.info.coverSizeRatio.toFloat();
|
||||||
json["title"] = comic.info.title.toString();
|
json["title"] = comic.info.title.toString();
|
||||||
json["number"] = comic.info.number.toInt();
|
json["number"] = comic.info.number.toInt();
|
||||||
|
json["last_time_opened"] = comic.info.lastTimeOpened.toLongLong();
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user