Usability fixes to Comic View scraper, now the dialog can be resized and once a volume is selected all the comics in that volume are fetched, so no more problems trying to scrap info for large numbers of comics.

This commit is contained in:
Luis Ángel San Martín 2017-01-14 14:58:42 +01:00
parent 27f9bff91b
commit 835a072e23
16 changed files with 252 additions and 75 deletions

View File

@ -20,7 +20,8 @@ HEADERS += \
comic_vine/scraper_scroll_label.h \
comic_vine/scraper_results_paginator.h \
comic_vine/scraper_selector.h \
comic_vine/api_key_dialog.h
comic_vine/api_key_dialog.h \
$$PWD/comic_vine_all_volume_comics_retriever.h
SOURCES += \
comic_vine/comic_vine_dialog.cpp \
@ -43,4 +44,5 @@ SOURCES += \
comic_vine/scraper_scroll_label.cpp \
comic_vine/scraper_results_paginator.cpp \
comic_vine/scraper_selector.cpp \
comic_vine/api_key_dialog.cpp
comic_vine/api_key_dialog.cpp \
$$PWD/comic_vine_all_volume_comics_retriever.cpp

View File

@ -0,0 +1,97 @@
#include "comic_vine_all_volume_comics_retriever.h"
#include "http_worker.h"
#include "response_parser.h"
#include <QtScript>
ComicVineAllVolumeComicsRetriever::ComicVineAllVolumeComicsRetriever(const QString &volumeURLString, QObject *parent)
: QObject(parent), volumeURLString(volumeURLString)
{
}
void ComicVineAllVolumeComicsRetriever::getAllVolumeComics()
{
getAllVolumeComics(0);
}
void ComicVineAllVolumeComicsRetriever::getAllVolumeComics(int range)
{
HttpWorker * search = new HttpWorker(volumeURLString.arg(range));
connect(search,SIGNAL(dataReady(const QByteArray &)),this,SLOT(appendVolumeComicsInfo(const QByteArray &)));
connect(search,SIGNAL(timeout()),this,SIGNAL(timeOut()));
connect(search,SIGNAL(timeout()),this,SIGNAL(finished()));
connect(search,SIGNAL(finished()),search,SLOT(deleteLater()));
search->get();
}
void ComicVineAllVolumeComicsRetriever::appendVolumeComicsInfo(const QByteArray &data)
{
QString json(data);
jsonResponses.append(data);
ResponseParser rp;
rp.loadJSONResponse(json);
qint32 currentPage = rp.getCurrentPage();
qint32 totalPages = rp.getTotalPages();
bool isLastResponse = currentPage == totalPages;
if (!isLastResponse) {
getAllVolumeComics(currentPage * 100);
}
else
{
emit allVolumeComicsInfo(consolidateJSON());
emit finished();
}
}
QString ComicVineAllVolumeComicsRetriever::consolidateJSON()
{
QJsonObject consolidatedJSON;
QJsonArray comicsInfo;
foreach (QByteArray json, jsonResponses) {
QJsonDocument doc = QJsonDocument::fromJson(json);
if(doc.isNull() || !doc.isObject() || doc.isEmpty())
{
continue;
}
QJsonObject main = doc.object();
QJsonValue error = main["error"];
if (error.isUndefined() || error.toString() != "OK")
{
continue;
}
else
{
QJsonValue results = main["results"];
if (results.isUndefined() || !results.isArray())
{
continue;
}
QJsonArray resultsArray = results.toArray();
foreach (const QJsonValue & v, resultsArray)
comicsInfo.append(v);
}
}
consolidatedJSON["error"] = "OK";
consolidatedJSON["status_code"] = 1;
consolidatedJSON["number_of_total_results"] = comicsInfo.size();
consolidatedJSON["offset"] = 0;
consolidatedJSON["results"] = comicsInfo;
QJsonDocument doc(consolidatedJSON);
return doc.toJson(QJsonDocument::Compact);
}

View File

@ -0,0 +1,28 @@
#ifndef COMIC_VINE_ALL_VOLUME_COMICS_RETRIEVER_H
#define COMIC_VINE_ALL_VOLUME_COMICS_RETRIEVER_H
#include <QObject>
class ComicVineAllVolumeComicsRetriever : public QObject
{
Q_OBJECT
public:
explicit ComicVineAllVolumeComicsRetriever(const QString &volumeURLString, QObject *parent = 0);
void getAllVolumeComics();
protected:
void getAllVolumeComics(const int range);
signals:
void allVolumeComicsInfo(QString json);
void finished();
void timeOut();
protected slots:
void appendVolumeComicsInfo(const QByteArray &data);
protected:
QString volumeURLString;
QList<QByteArray> jsonResponses;
QString consolidateJSON();
};
#endif // COMIC_VINE_ALL_VOLUME_COMICS_RETRIEVER_H

View File

@ -1,6 +1,8 @@
#include "comic_vine_client.h"
#include "yacreader_global_gui.h"
#include "comic_vine_all_volume_comics_retriever.h"
//this is the API key used by YACReader to access Comic Vine
//please, do not use it in your own software, get one for free at Comic Vine
static const QString CV_API_KEY = "%CV_API_KEY%"; //get from settings
@ -22,7 +24,7 @@ static const QString CV_SERIES_DETAIL = CV_WEB_ADDRESS + "/volume/4050-%1/?api_k
//gets info for comics in a volume id %1
static const QString CV_COMICS_INFO = CV_WEB_ADDRESS + "/issues/?api_key=" + CV_API_KEY +
"&format=json&field_list=name,issue_number,id,image&filter=volume:%1"
"&limit=1000&format=json&field_list=name,issue_number,id,image&filter=volume:%1"
"&sort=cover_date:asc" //sorting by cover_date, because comic vine doesn't use natural sorting (issue_number -> 1 10 11 ... 100 2 20 21....)
"&offset=%2";
@ -115,13 +117,26 @@ void ComicVineClient::getSeriesCover(const QString & url)
//CV_COMIC_IDS
void ComicVineClient::getVolumeComicsInfo(const QString & idVolume, int page)
{
HttpWorker * search = new HttpWorker(QString(CV_COMICS_INFO).replace(CV_WEB_ADDRESS, baseURL).replace(CV_API_KEY,settings->value(COMIC_VINE_API_KEY,CV_API_KEY_DEFAULT).toString()).arg(idVolume).arg((page-1)*100)); //page on works for search, using offset instead
HttpWorker * search = new HttpWorker(QString(CV_COMICS_INFO).replace(CV_WEB_ADDRESS, baseURL).replace(CV_API_KEY,settings->value(COMIC_VINE_API_KEY,CV_API_KEY_DEFAULT).toString()).arg(idVolume).arg((page-1)*100)); //page doesn't work for search, using offset instead
connect(search,SIGNAL(dataReady(const QByteArray &)),this,SLOT(processVolumeComicsInfo(const QByteArray &)));
connect(search,SIGNAL(timeout()),this,SIGNAL(timeOut())); //TODO
connect(search,SIGNAL(finished()),search,SLOT(deleteLater()));
search->get();
}
void ComicVineClient::getAllVolumeComicsInfo(const QString &idVolume)
{
QString url = QString(CV_COMICS_INFO).replace(CV_WEB_ADDRESS, baseURL).replace(CV_API_KEY,settings->value(COMIC_VINE_API_KEY,CV_API_KEY_DEFAULT).toString()).arg(idVolume);
ComicVineAllVolumeComicsRetriever * comicsRetriever = new ComicVineAllVolumeComicsRetriever(url);
connect(comicsRetriever, &ComicVineAllVolumeComicsRetriever::allVolumeComicsInfo, this, &ComicVineClient::volumeComicsInfo);
connect(comicsRetriever, &ComicVineAllVolumeComicsRetriever::finished, this, &ComicVineClient::finished);
connect(comicsRetriever, &ComicVineAllVolumeComicsRetriever::finished, this, &ComicVineAllVolumeComicsRetriever::deleteLater);
connect(comicsRetriever, &ComicVineAllVolumeComicsRetriever::timeOut, this, &ComicVineClient::timeOut);
comicsRetriever->getAllVolumeComics();
}
//CV_COMIC_ID
void ComicVineClient::getComicId(const QString & id, int comicNumber)
{

View File

@ -27,6 +27,7 @@ public slots:
void getSeriesDetail(const QString & id);
void getSeriesCover(const QString & url);
void getVolumeComicsInfo(const QString & idVolume, int page=1);
void getAllVolumeComicsInfo(const QString & idVolume);
QByteArray getComicDetail(const QString & id, bool &outError, bool &outTimeout);
void getComicCover(const QString & url);

View File

@ -1,4 +1,5 @@
#include "comic_vine_dialog.h"
#include <QtWidgets>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
@ -36,6 +37,8 @@
ComicVineDialog::ComicVineDialog(QWidget *parent) :
QDialog(parent)
{
setWindowFlags(Qt::Window);
doLayout();
doStackedWidgets();
doConnections();
@ -75,15 +78,13 @@ void ComicVineDialog::doLayout()
buttonLayout->addWidget(closeButton);
buttonLayout->setContentsMargins(0,0,0,0);
mainLayout->addWidget(titleHeader = new TitleHeader);
mainLayout->addWidget(content);
mainLayout->addStretch();
mainLayout->addLayout(buttonLayout);
mainLayout->addWidget(titleHeader = new TitleHeader, 0);
mainLayout->addWidget(content, 1);
mainLayout->addLayout(buttonLayout, 0);
mainLayout->setContentsMargins(26,16,26,11);
setLayout(mainLayout);
setFixedSize(872,529);
setWindowTitle("Comic Vine Scraper (beta)");
}
@ -200,6 +201,25 @@ void ComicVineDialog::setComics(const QList<ComicDB> & comics)
this->comics = comics;
}
QSize ComicVineDialog::sizeHint() const
{
int heightDesktopResolution = QApplication::desktop()->screenGeometry().height();
int widthDesktopResolution = QApplication::desktop()->screenGeometry().width();
int height,width;
height = qMax(529, static_cast<int>(heightDesktopResolution*0.5));
width = height * 1.65;
if (width > widthDesktopResolution)
return minimumSizeHint();
return QSize(width, height);
}
QSize ComicVineDialog::minimumSizeHint() const
{
return QSize(872, 529);
}
void ComicVineDialog::show()
{
QDialog::show();
@ -698,7 +718,7 @@ void ComicVineDialog::getVolumeComicsInfo(const QString &vID, int page)
QLOG_TRACE() << vID;
comicVineClient->getVolumeComicsInfo(vID,page);
comicVineClient->getAllVolumeComicsInfo(vID);
}
void ComicVineDialog::launchSearchVolume()

View File

@ -30,7 +30,8 @@ public:
QString databasePath;
QString basePath;
void setComics(const QList<ComicDB> & comics);
QSize sizeHint() const;
QSize minimumSizeHint() const;
signals:

View File

@ -50,6 +50,13 @@ void VolumeComicsModel::load(const QString & json)
}
}
/*void VolumeComicsModel::load(const QStringList &jsonList)
{
foreach (QString json, jsonList) {
load(json);
}
}*/
QModelIndex VolumeComicsModel::parent(const QModelIndex &index) const
{
Q_UNUSED(index)

View File

@ -9,6 +9,7 @@ class VolumeComicsModel : public JSONModel
public:
explicit VolumeComicsModel(QObject *parent = 0);
void load(const QString & json);
//void load(const QStringList & jsonList);
QModelIndex parent(const QModelIndex &index) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;

View File

@ -79,17 +79,34 @@ QVariant VolumesModel::data(const QModelIndex &index, int role) const
{
return QVariant();
}
int row = index.row();
int column = index.column();
if (role == Qt::TextAlignmentRole)
{
//TODO
switch(column)
{
case YEAR:
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
case ISSUES:
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
default:
return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
}
}
if(role != Qt::DisplayRole)
return QVariant();
int row = index.row();
int column = index.column();
if (column == YEAR || column == ISSUES)
{
return _data[row][column].toInt();
}
else
{
return _data[row][column];
}
}
Qt::ItemFlags VolumesModel::flags(const QModelIndex &index) const
@ -125,6 +142,8 @@ QVariant VolumesModel::headerData(int section, Qt::Orientation orientation, int
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
case ISSUES:
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
default:
return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
}
}

View File

@ -45,6 +45,9 @@ public:
ID
};
enum Role {
SORT_ROLE = Qt::UserRole
};
};
#endif // VOLUMES_MODEL_H

View File

@ -33,7 +33,6 @@ ScraperTableView::ScraperTableView(QWidget *parent) :
verticalHeader()->setResizeMode(QHeaderView::Fixed);
#endif
//comicView->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
horizontalHeader()->setStretchLastSection(true);
#if QT_VERSION >= 0x050000
horizontalHeader()->setSectionsClickable(false);

View File

@ -20,10 +20,7 @@ SelectComic::SelectComic(QWidget *parent)
QVBoxLayout * l = new QVBoxLayout;
QWidget * leftWidget = new QWidget;
QVBoxLayout * left = new QVBoxLayout;
QVBoxLayout * right = new QVBoxLayout;
QHBoxLayout * content = new QHBoxLayout;
right->setContentsMargins(0,0,0,0);
QGridLayout * content = new QGridLayout;
//widgets
cover = new QLabel();
@ -41,23 +38,22 @@ SelectComic::SelectComic(QWidget *parent)
left->addWidget(cover);
left->addWidget(detailLabel,1);
left->addStretch();
leftWidget->setMaximumWidth(180);
leftWidget->setLayout(left);
left->setContentsMargins(0,0,0,0);
leftWidget->setContentsMargins(0,0,0,0);
right->addWidget(tableComics,0,Qt::AlignRight|Qt::AlignTop);
right->addWidget(paginator);
content->addWidget(leftWidget, 0, 0);
content->addWidget(tableComics, 0, 1);
content->addWidget(paginator, 1, 1);
content->addWidget(leftWidget);
content->addLayout(right);
content->setColumnStretch(1, 1);
content->setRowStretch(0, 1);;
l->addSpacing(15);
l->addWidget(label);
l->addSpacing(5);
l->addLayout(content);
l->addStretch();
l->setContentsMargins(0,0,0,0);
setLayout(l);
@ -70,8 +66,6 @@ void SelectComic::load(const QString &json, const QString & searchString)
tempM->load(json);
tableComics->setModel(tempM);
tableComics->setFixedSize(619,341);
if(model != 0)
delete model;

View File

@ -35,10 +35,7 @@ SelectVolume::SelectVolume(QWidget *parent)
QVBoxLayout * l = new QVBoxLayout;
QWidget * leftWidget = new QWidget;
QVBoxLayout * left = new QVBoxLayout;
QVBoxLayout * right = new QVBoxLayout;
QHBoxLayout * content = new QHBoxLayout;
right->setContentsMargins(0,0,0,0);
QGridLayout * content = new QGridLayout;
//widgets
cover = new QLabel();
@ -46,9 +43,9 @@ SelectVolume::SelectVolume(QWidget *parent)
cover->setAlignment(Qt::AlignTop|Qt::AlignHCenter);
cover->setMinimumSize(168,168*5.0/3);
cover->setStyleSheet("QLabel {background-color: #2B2B2B; color:white; font-size:12px; font-family:Arial; }");
detailLabel = new ScraperScrollLabel(this);
detailLabel = new ScraperScrollLabel();
tableVolumes = new ScraperTableView(this);
tableVolumes = new ScraperTableView();
tableVolumes->setSortingEnabled(true);
#if QT_VERSION >= 0x050000
tableVolumes->horizontalHeader()->setSectionsClickable(true);
@ -64,23 +61,22 @@ SelectVolume::SelectVolume(QWidget *parent)
left->addWidget(cover);
left->addWidget(detailLabel,1);
left->addStretch();
leftWidget->setMaximumWidth(180);
leftWidget->setLayout(left);
left->setContentsMargins(0,0,0,0);
leftWidget->setContentsMargins(0,0,0,0);
right->addWidget(tableVolumes,0,Qt::AlignRight|Qt::AlignTop);
right->addWidget(paginator);
content->addWidget(leftWidget, 0, 0);
content->addWidget(tableVolumes, 0, 1);
content->addWidget(paginator, 1, 1);
content->addWidget(leftWidget);
content->addLayout(right);
content->setColumnStretch(1, 1);
content->setRowStretch(0, 1);
l->addSpacing(15);
l->addWidget(label);
l->addSpacing(5);
l->addLayout(content);
l->addStretch();
l->setContentsMargins(0,0,0,0);
setLayout(l);
@ -98,8 +94,6 @@ void SelectVolume::load(const QString & json, const QString & searchString)
tableVolumes->sortByColumn(0,Qt::AscendingOrder);
tableVolumes->resizeColumnsToContents();
tableVolumes->setFixedSize(619,341);
if(model != 0)
delete model;

View File

@ -38,7 +38,7 @@ SortVolumeComics::SortVolumeComics(QWidget *parent) :
//connect(moveUpButtonIL,SIGNAL(clicked()),this,SLOT(moveDownIL()));
QVBoxLayout * l = new QVBoxLayout;
QHBoxLayout * content = new QHBoxLayout;
QGridLayout * content = new QGridLayout;
QHBoxLayout * sortButtonsLayout = new QHBoxLayout;
tableFiles = new ScraperTableView();
@ -47,10 +47,6 @@ SortVolumeComics::SortVolumeComics(QWidget *parent) :
tableFiles->setSelectionBehavior(QAbstractItemView::SelectRows);
tableFiles->setSelectionMode(QAbstractItemView::ContiguousSelection);
tableFiles->setFixedSize(407,341);
tableVolumeComics->setFixedSize(407,341);
content->addWidget(tableFiles,0,Qt::AlignLeft|Qt::AlignTop);
content->addWidget(tableVolumeComics,0,Qt::AlignRight|Qt::AlignTop);
//content->addWidget(tableVolumes,0,Qt::AlignRight|Qt::AlignTop);
connect(tableVolumeComics->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(synchronizeScroll(int)));
@ -66,22 +62,22 @@ SortVolumeComics::SortVolumeComics(QWidget *parent) :
sortButtonsLayout->addWidget(ScrapperToolButton::getSeparator());
sortButtonsLayout->addWidget(moveDownButtonCL);
sortButtonsLayout->addSpacing(10);
//sortButtonsLayout->addStretch();
sortButtonsLayout->addWidget(sortLabel);
sortButtonsLayout->addStretch();
sortButtonsLayout->addWidget(paginator);
//sortButtonsLayout->addStretch();
//sortButtonsLayout->addWidget(moveUpButtonIL);
//sortButtonsLayout->addWidget(ScrapperToolButton::getSeparator());
//sortButtonsLayout->addWidget(moveDownButtonIL);
sortButtonsLayout->setSpacing(0);
content->addWidget(tableFiles, 0, 0);
content->addWidget(tableVolumeComics, 0, 1);
content->addLayout(sortButtonsLayout, 1, 0);
content->addWidget(paginator, 1, 1);
content->setRowStretch(0, 1);
l->addSpacing(15);
l->addWidget(label);
l->addWidget(label, 0);
l->addSpacing(5);
l->addLayout(content);
l->addLayout(sortButtonsLayout);
l->addStretch();
l->addLayout(content, 1);
l->addLayout(sortButtonsLayout, 0);
l->setContentsMargins(0,0,0,0);
setLayout(l);

View File

@ -67,7 +67,7 @@ public:
signals:
public slots:
void setData(QList<ComicDB> & comics, const QString & json, const QString & vID);
void setData(QList<ComicDB> & comics, const QString &json, const QString & vID);
QList<QPair<ComicDB,QString> > getMatchingInfo();
protected slots: