Skip to content

Commit

Permalink
fix threading issue with network manager, fix download model's thumbn…
Browse files Browse the repository at this point in the history
…ails
  • Loading branch information
mgn-norm committed Nov 26, 2022
1 parent f1e636d commit 971fb49
Show file tree
Hide file tree
Showing 10 changed files with 302 additions and 333 deletions.
12 changes: 5 additions & 7 deletions src/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@
#include <QDir>
#include <qstringbuilder.h>
#include <QQmlContext>
#include <QAuthenticator>

#include "App.h"

App::App(const CommandLine& cmd, QObject * parent)
: QObject(parent)
, _settings(std::make_shared<Settings>())
, _nm(std::make_unique<NetworkManager>(
_settings,
, _nm(_settings,
cmd.isSet(CommandLine::hostname)
? cmd.value(CommandLine::hostname)
: _settings->hostname(),
this))
this)
, _commandLine(cmd)
, _engine(new QQmlApplicationEngine(this))
{
Expand Down Expand Up @@ -54,11 +54,9 @@ void App::reload()
***************************************************************************/
void App::initalize()
{
_nm->create(this);

// Global context variables to inject into QML
const std::pair<const char*, QObject*> contextVars[] = {
{ "networkManager", _nm.get()},
{ "networkManager", &_nm},
{ "settings", _settings.get()},
{ "app", this },
};
Expand All @@ -67,7 +65,7 @@ void App::initalize()
context->setContextProperty(var.first, QVariant::fromValue(var.second));
}

_engine->setNetworkAccessManagerFactory(_nm.get());
_engine->setNetworkAccessManagerFactory(&_nm);
_engine->addImportPath(QStringLiteral("qrc:/"));
_engine->load(makeUrl(QStringLiteral("main.qml")));
}
Expand Down
2 changes: 1 addition & 1 deletion src/App.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class App : public QObject

std::shared_ptr<Settings> _settings;

std::unique_ptr<NetworkManager> _nm;
NetworkManager _nm;

const CommandLine& _commandLine;

Expand Down
47 changes: 27 additions & 20 deletions src/models/DownloadsModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,22 @@ void DownloadsModel::setupWebsocket() {
[=](QAbstractSocket::SocketError error) {
qDebug() << "error: " << error << _webSocket.errorString();
});
auto resolved = NetworkManager::instance().resolvedPath().resolved(QString("api/v1/downloads"));
auto resolved = NetworkManager::instance().resolvedPath().resolved(
QString("api/v1/downloads"));
bool ssl = !resolved.scheme().compare("https", Qt::CaseInsensitive);
resolved.setScheme(ssl ? "wss" : "ws");

QNetworkRequest request;
request.setUrl(resolved);
request.setRawHeader("Authorization",
QString("Basic %1")
.arg(QByteArray(QString("%1:%2")
.arg(NetworkManager::instance().username())
.arg(NetworkManager::instance().password())
.toUtf8())
.toBase64())
.toUtf8());
request.setRawHeader(
"Authorization",
QString("Basic %1")
.arg(QByteArray(QString("%1:%2")
.arg(NetworkManager::instance().username())
.arg(NetworkManager::instance().password())
.toUtf8())
.toBase64())
.toUtf8());

_webSocket.open(request);
}
Expand Down Expand Up @@ -101,8 +103,8 @@ void DownloadsModel::onTextMessageReceived(const QString &message) {
info.progress = entry["progress"].toDouble() * 100;
info.tries = entry["tries"].toInt();
const auto &manga = entry["manga"];
info.title = manga["title"].toString();
info.thumbnailUrl = manga["thumbnailUrl"].toString();
info.title = manga["title"].toString();
info.thumbnailUrl = manga["thumbnailUrl"].toString();

info.chapterInfo.processChapter(entry["chapter"].toObject());
}
Expand Down Expand Up @@ -189,9 +191,7 @@ QVariant DownloadsModel::data(const QModelIndex &index, int role) const {
}

case RoleThumbnail: {
qDebug() << "entry url: " << entry.thumbnailUrl;
return NetworkManager::instance().resolvedPath().resolved(
entry.thumbnailUrl);
return NetworkManager::instance().resolvedPath().resolved(entry.thumbnailUrl.mid(1));
}

// case Role
Expand Down Expand Up @@ -237,29 +237,36 @@ QHash<int, QByteArray> DownloadsModel::roleNames() const {
* Method: clear()
*
*****************************************************************************/
void DownloadsModel::clear() { NetworkManager::instance().get("downloads/clear"); }
void DownloadsModel::clear() {
NetworkManager::instance().get("downloads/clear");
}

/******************************************************************************
*
* Method: clear()
*
*****************************************************************************/
void DownloadsModel::pause() { NetworkManager::instance().get("downloads/stop"); }
void DownloadsModel::pause() {
NetworkManager::instance().get("downloads/stop");
}

/******************************************************************************
*
* Method: clear()
*
*****************************************************************************/
void DownloadsModel::start() { NetworkManager::instance().get("downloads/start"); }
void DownloadsModel::start() {
NetworkManager::instance().get("downloads/start");
}

/******************************************************************************
*
* Method: cancel()
*
*****************************************************************************/
void DownloadsModel::cancel(qint32 index) {
NetworkManager::instance().deleteResource(QStringLiteral("download/%1/chapter/%2")
.arg(_queue[index].mangaId)
.arg(_queue[index].chapterIndex));
NetworkManager::instance().deleteResource(
QStringLiteral("download/%1/chapter/%2")
.arg(_queue[index].mangaId)
.arg(_queue[index].chapterIndex));
}
4 changes: 1 addition & 3 deletions src/models/DownloadsModel.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
#pragma once

#include <qqml.h>
#include <QAbstractListModel>
#include <QQmlParserStatus>
#include <QtWebSockets/QtWebSockets>

#include "ChaptersModel.h"
#include "MangaDetailsModel.h"
#include "common_structs.h"

class DownloadsModel : public QAbstractListModel, public QQmlParserStatus {
Expand All @@ -21,7 +20,6 @@ class DownloadsModel : public QAbstractListModel, public QQmlParserStatus {
std::vector<QueueInfo> _queue;

typedef quint32 MangaId;
//QMap<MangaId, MangaDetails> _mangaInfo;

protected:
void classBegin() override;
Expand Down
150 changes: 66 additions & 84 deletions src/models/LibraryModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,31 @@
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <qcoreapplication.h>
#include <QQmlEngine>
#include <QStringBuilder>
#include <qcoreapplication.h>

#include "../networkmanager.h"
/******************************************************************************
*
* LibraryModel
*
*****************************************************************************/
LibraryModel::LibraryModel(QObject* parent)
: QAbstractListModel(parent)
{
}
LibraryModel::LibraryModel(QObject *parent) : QAbstractListModel(parent) {}

/******************************************************************************
*
* classBegin
*
*****************************************************************************/
void LibraryModel::classBegin()
{
refreshLibrary();
}
void LibraryModel::classBegin() { refreshLibrary(); }

/******************************************************************************
*
* componentComplete
*
*****************************************************************************/
void LibraryModel::componentComplete()
{
}

void LibraryModel::componentComplete() {}

/******************************************************************************
*
Expand All @@ -57,37 +48,31 @@ int LibraryModel::rowCount(const QModelIndex &parent) const {
*
*****************************************************************************/
QVariant LibraryModel::data(const QModelIndex &index, int role) const {
if (!((index.isValid()) &&
(index.row() >= 0) &&
(index.row() < rowCount())))
{
if (!((index.isValid()) && (index.row() >= 0) &&
(index.row() < rowCount()))) {
return {};
}

const auto& entry = _entries[index.row()];

switch (role)
{
case RoleTitle:
{
return entry.title;
}
case RoleThumbnail:
{
return NetworkManager::instance().resolvedPath().resolved(entry.thumbnailUrl.mid(1));
}
case RoleId:
{
return entry.id;
}
case RoleUnread:
{
return entry.unread;
}

//case Role
default:
return {};
const auto &entry = _entries[index.row()];

switch (role) {
case RoleTitle: {
return entry.title;
}
case RoleThumbnail: {
return NetworkManager::instance().resolvedPath().resolved(
entry.thumbnailUrl.mid(1));
}
case RoleId: {
return entry.id;
}
case RoleUnread: {
return entry.unread;
}

// case Role
default:
return {};
}

return {};
Expand All @@ -99,10 +84,10 @@ QVariant LibraryModel::data(const QModelIndex &index, int role) const {
*
*****************************************************************************/
QHash<int, QByteArray> LibraryModel::roleNames() const {
static QHash<int, QByteArray> roles = { {RoleTitle, "title"},
{RoleThumbnail, "thumbnailUrl"},
{RoleUnread, "unread"},
{RoleId, "mangaId"} };
static QHash<int, QByteArray> roles = {{RoleTitle, "title"},
{RoleThumbnail, "thumbnailUrl"},
{RoleUnread, "unread"},
{RoleId, "mangaId"}};

return roles;
}
Expand All @@ -112,47 +97,44 @@ QHash<int, QByteArray> LibraryModel::roleNames() const {
* Method: refreshLibrary()
*
*****************************************************************************/
void LibraryModel::refreshLibrary()
{
void LibraryModel::refreshLibrary() {
auto entriesSize = _entries.size();
_entries.clear();
NetworkManager::instance().get(QUrl("category"), this,
[&](const auto& doc)
{
for (const auto& entry_arr : doc.array()) {
const auto& entry = entry_arr.toObject();
NetworkManager::instance().get(QUrl(u"category/"_qs % QString::number(entry["id"].toInt())), this,
[&](const auto& doc1)
{
bool reset = static_cast<quint32>(doc1.array().size()) != entriesSize;
if (reset) {
beginResetModel();
}

for (const auto& entry_arr : doc1.array()) {
const auto& entry = entry_arr.toObject();
auto& info = _entries.emplace_back();
info.id = entry["id"].toInt();
info.sourceId = entry["sourceId"].toString();
info.url = entry["url"].toString();
info.title = entry["title"].toString();
info.thumbnailUrl = entry["thumbnailUrl"].toString();
info.initalized = entry["intialized"].toBool();
info.author = entry["author"].toString();
info.artist = entry["artist"].toString();
info.genre = entry["genre"].toString();
info.status = entry["status"].toString();
info.unread = entry["unreadCount"].toInt();
}

if (reset) {
endResetModel();
}
else {
emit dataChanged(createIndex(0, 0), createIndex(_entries.size(), 0));
}
});
NetworkManager::instance().get(QUrl("category"), this, [&](const auto &doc) {
for (const auto &entry_arr : doc.array()) {
const auto &entry = entry_arr.toObject();
NetworkManager::instance().get(
QUrl(u"category/"_qs % QString::number(entry["id"].toInt())), this,
[&](const auto &doc1) {
bool reset =
static_cast<quint32>(doc1.array().size()) != entriesSize;
if (reset) {
beginResetModel();
}

for (const auto &entry_arr : doc1.array()) {
const auto &entry = entry_arr.toObject();
auto &info = _entries.emplace_back();
info.id = entry["id"].toInt();
info.sourceId = entry["sourceId"].toString();
info.url = entry["url"].toString();
info.title = entry["title"].toString();
info.thumbnailUrl = entry["thumbnailUrl"].toString();
info.initalized = entry["intialized"].toBool();
info.author = entry["author"].toString();
info.artist = entry["artist"].toString();
info.genre = entry["genre"].toString();
info.status = entry["status"].toString();
info.unread = entry["unreadCount"].toInt();
}

if (reset) {
endResetModel();
} else {
emit dataChanged(createIndex(0, 0),
createIndex(_entries.size(), 0));
}
});
}
});
}

Loading

0 comments on commit 971fb49

Please sign in to comment.