mirror of
https://github.com/YACReader/yacreader
synced 2025-05-25 09:50:33 -04:00
246 lines
7.4 KiB
C++
246 lines
7.4 KiB
C++
#include "yacreader_local_server.h"
|
|
|
|
#include <QLocalServer>
|
|
#include <QLocalSocket>
|
|
#include <QPointer>
|
|
|
|
#include "yacreader_global.h"
|
|
#include "db_helper.h"
|
|
|
|
#include "comic_db.h"
|
|
|
|
#include "QsLog.h"
|
|
|
|
using namespace YACReader;
|
|
|
|
QMutex YACReaderClientConnectionWorker::dbMutex;
|
|
// int YACReaderClientConnectionWorker::count = 0;
|
|
YACReaderLocalServer::YACReaderLocalServer(QObject *parent)
|
|
: QObject(parent)
|
|
{
|
|
localServer = new QLocalServer(this);
|
|
QLocalServer::removeServer(YACREADERLIBRARY_GUID);
|
|
if (!localServer->listen(YACREADERLIBRARY_GUID)) {
|
|
QLOG_ERROR() << "Unable to create local server";
|
|
}
|
|
|
|
connect(localServer, &QLocalServer::newConnection, this, &YACReaderLocalServer::sendResponse);
|
|
}
|
|
|
|
bool YACReaderLocalServer::isListening()
|
|
{
|
|
return localServer->isListening();
|
|
}
|
|
|
|
/*void YACReaderLocalServer::run()
|
|
{
|
|
while(1)
|
|
exec();
|
|
}*/
|
|
|
|
void YACReaderLocalServer::sendResponse()
|
|
{
|
|
QLocalSocket *clientConnection = localServer->nextPendingConnection();
|
|
// connect(clientConnection, SIGNAL(disconnected()),clientConnection, SLOT(deleteLater()));
|
|
clientConnection->setParent(0);
|
|
|
|
auto worker = new YACReaderClientConnectionWorker(clientConnection);
|
|
if (worker != 0) {
|
|
clientConnection->moveToThread(worker);
|
|
connect(worker, &YACReaderClientConnectionWorker::comicUpdated, this, &YACReaderLocalServer::comicUpdated);
|
|
connect(worker, &QThread::finished, worker, &QObject::deleteLater);
|
|
worker->start();
|
|
}
|
|
|
|
QLOG_TRACE() << "connection incoming";
|
|
// clientConnection->waitForBytesWritten();*/
|
|
// clientConnection->disconnectFromServer();
|
|
}
|
|
|
|
bool YACReaderLocalServer::isRunning()
|
|
{
|
|
QLocalSocket socket;
|
|
socket.connectToServer(YACREADERLIBRARY_GUID);
|
|
if (socket.waitForConnected(500))
|
|
return true; // Server is running (another instance of YACReaderLibrary has been launched)
|
|
return false;
|
|
}
|
|
|
|
void YACReaderLocalServer::close()
|
|
{
|
|
localServer->close();
|
|
}
|
|
|
|
YACReaderClientConnectionWorker::YACReaderClientConnectionWorker(QLocalSocket *cc)
|
|
: QThread(), clientConnection(cc)
|
|
{
|
|
}
|
|
|
|
YACReaderClientConnectionWorker::~YACReaderClientConnectionWorker()
|
|
{
|
|
}
|
|
/*#include <QFile>
|
|
#include <QTextStream>
|
|
#include <QDateTime>*/
|
|
void YACReaderClientConnectionWorker::run()
|
|
{
|
|
/*{
|
|
QFile f(QString("c:/temp/thread%1.txt").arg(count));
|
|
f.open(QIODevice::Append);
|
|
QTextStream out(&f);
|
|
out << QString("Thread%1 starts").arg(count) << endl;
|
|
f.close();
|
|
}
|
|
uint t1 = QDateTime::currentMSecsSinceEpoch();*/
|
|
|
|
quint64 libraryId;
|
|
ComicDB comic;
|
|
OpenComicSource source = { OpenComicSource::ReadingList, 0 };
|
|
qulonglong nextComicId;
|
|
int tries = 0;
|
|
int dataAvailable = 0;
|
|
QByteArray packageSize;
|
|
clientConnection->waitForReadyRead(1000);
|
|
while (((long unsigned int)packageSize.size() < sizeof(quint32)) && (tries < 20)) {
|
|
packageSize.append(clientConnection->read(sizeof(quint32) - packageSize.size()));
|
|
clientConnection->waitForReadyRead(100);
|
|
if (dataAvailable == packageSize.size()) {
|
|
tries++;
|
|
}
|
|
dataAvailable = packageSize.size();
|
|
}
|
|
if (tries == 20) {
|
|
QLOG_ERROR() << "Local connection: unable to read the message size" << clientConnection->errorString();
|
|
return;
|
|
}
|
|
|
|
QDataStream sizeStream(packageSize);
|
|
sizeStream.setVersion(QDataStream::Qt_4_8);
|
|
quint32 totalSize = 0;
|
|
sizeStream >> totalSize;
|
|
|
|
tries = 0;
|
|
QByteArray data;
|
|
int dataRead = 0;
|
|
while ((quint32)data.size() < totalSize && tries < 200) {
|
|
data.append(clientConnection->readAll());
|
|
if ((quint32)data.length() < totalSize)
|
|
clientConnection->waitForReadyRead(100);
|
|
if (dataRead == data.length()) // no bytes were read
|
|
tries++;
|
|
dataRead = data.length();
|
|
}
|
|
if (tries == 200) {
|
|
QLOG_ERROR() << QString("Local connection: unable to read message (%1,%2)").arg(data.size()).arg(totalSize);
|
|
return;
|
|
}
|
|
QDataStream dataStream(data);
|
|
quint8 msgType;
|
|
dataStream >> msgType;
|
|
|
|
switch (msgType) {
|
|
case YACReader::RequestComicInfo: {
|
|
dataStream >> libraryId;
|
|
dataStream >> source;
|
|
dataStream >> comic;
|
|
|
|
QList<ComicDB> siblings;
|
|
|
|
if (source.source == OpenComicSource::ReadingList) {
|
|
getComicInfoFromReadingList(libraryId, source.sourceId, comic, siblings);
|
|
} else {
|
|
getComicInfo(libraryId, comic, siblings);
|
|
}
|
|
|
|
QByteArray block;
|
|
QDataStream out(&block, QIODevice::WriteOnly);
|
|
out.setVersion(QDataStream::Qt_4_8);
|
|
out << (quint32)0;
|
|
out << comic;
|
|
out << siblings;
|
|
out.device()->seek(0);
|
|
out << (quint32)(block.size() - sizeof(quint32));
|
|
|
|
int written = 0;
|
|
tries = 0;
|
|
while (written != block.size() && tries < 200) {
|
|
int ret = clientConnection->write(block);
|
|
clientConnection->waitForBytesWritten(10);
|
|
if (ret != -1) {
|
|
written += ret;
|
|
clientConnection->flush();
|
|
} else
|
|
tries++;
|
|
}
|
|
if (tries == 200 && written != block.size()) {
|
|
QLOG_ERROR() << QString("Local connection (comic info requested): unable to send response (%1,%2)").arg(written).arg(block.size());
|
|
}
|
|
break;
|
|
}
|
|
case YACReader::SendComicInfo: {
|
|
bool nextComicInfoAvailable;
|
|
|
|
dataStream >> libraryId;
|
|
dataStream >> comic;
|
|
|
|
if (dataStream.atEnd()) {
|
|
nextComicInfoAvailable = false;
|
|
} else {
|
|
nextComicInfoAvailable = true;
|
|
dataStream >> nextComicId;
|
|
}
|
|
|
|
if (nextComicInfoAvailable) {
|
|
updateComic(libraryId, comic, nextComicId);
|
|
} else {
|
|
updateComic(libraryId, comic);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
clientConnection->waitForDisconnected();
|
|
clientConnection->deleteLater();
|
|
/*count++;
|
|
uint t2 = QDateTime::currentMSecsSinceEpoch();
|
|
{
|
|
QFile f(QString("c:/temp/thread%1.txt").arg(count));
|
|
f.open(QIODevice::Append);
|
|
QTextStream out(&f);
|
|
out << QString("Thread%1 ends : time - %2").arg(count).arg(t2-t1) << endl;
|
|
f.close();
|
|
}*/
|
|
}
|
|
|
|
void YACReaderClientConnectionWorker::getComicInfo(quint64 libraryId, ComicDB &comic, QList<ComicDB> &siblings)
|
|
{
|
|
QMutexLocker locker(&dbMutex);
|
|
comic = DBHelper::getComicInfo(libraryId, comic.id);
|
|
siblings = DBHelper::getSiblings(libraryId, comic.parentId);
|
|
}
|
|
|
|
void YACReaderClientConnectionWorker::getComicInfoFromReadingList(quint64 libraryId, unsigned long long readingListId, ComicDB &comic, QList<ComicDB> &siblings)
|
|
{
|
|
QMutexLocker locker(&dbMutex);
|
|
comic = DBHelper::getComicInfo(libraryId, comic.id);
|
|
siblings = DBHelper::getReadingListFullContent(libraryId, readingListId, true);
|
|
}
|
|
|
|
void YACReaderClientConnectionWorker::updateComic(quint64 libraryId, ComicDB &comic)
|
|
{
|
|
QMutexLocker locker(&dbMutex);
|
|
DBHelper::update(libraryId, comic.info);
|
|
emit comicUpdated(libraryId, comic);
|
|
}
|
|
|
|
void YACReaderClientConnectionWorker::updateComic(quint64 libraryId, ComicDB &comic, qulonglong nextComicId)
|
|
{
|
|
QMutexLocker locker(&dbMutex);
|
|
DBHelper::update(libraryId, comic.info);
|
|
ComicInfo nextcomicinfo;
|
|
nextcomicinfo.id = nextComicId;
|
|
DBHelper::setComicAsReading(libraryId, nextcomicinfo);
|
|
|
|
emit comicUpdated(libraryId, comic);
|
|
}
|