First semi-working implementation in c++ of remote Danbooru calls
This commit is contained in:
parent
c0cf369b92
commit
fc691a9301
9 changed files with 1341 additions and 0 deletions
340
src/libdanbooru/danbooruservice.cpp
Normal file
340
src/libdanbooru/danbooruservice.cpp
Normal file
|
@ -0,0 +1,340 @@
|
|||
/*
|
||||
* <one line to give the library's name and an idea of what it does.>
|
||||
* Copyright 2013 Luca Beltrame <lbeltrame@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <qjson/parser.h>
|
||||
|
||||
#include <KIO/Job>
|
||||
#include <KIO/Scheduler>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include "danbooruservice.h"
|
||||
#include "danboorupost.h"
|
||||
#include "danboorupool.h"
|
||||
|
||||
|
||||
namespace Danbooru {
|
||||
|
||||
using KIO::StoredTransferJob;
|
||||
|
||||
const QString DanbooruService::POST_URL ="post/index.json" ;
|
||||
const QString DanbooruService::TAG_URL = "tag/index.json";
|
||||
const QString DanbooruService::POOL_URL = "pool/index.json";
|
||||
const QString DanbooruService::ARTIST_URL = "artist/index.json";
|
||||
const QString DanbooruService::POOL_DATA_URL = "pool/show.xml";
|
||||
const QString DanbooruService::RELATED_TAG_URL = "tag/related.json";
|
||||
const QMap<QString, QStringList> DanbooruService::RATINGS = initRatings();
|
||||
|
||||
DanbooruService::DanbooruService(KUrl& boardUrl, QString username,
|
||||
QString password,
|
||||
QObject* parent):
|
||||
QObject(parent),
|
||||
m_url(boardUrl),
|
||||
m_username(username),
|
||||
m_password(password),
|
||||
m_maxRating("Safe"),
|
||||
m_currentPosts(0)
|
||||
{
|
||||
}
|
||||
|
||||
DanbooruService::~DanbooruService()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const QMap< QString, QStringList > DanbooruService::initRatings()
|
||||
{
|
||||
QMap<QString, QStringList> map;
|
||||
|
||||
QStringList safeRatings;
|
||||
safeRatings.append(QString("Safe"));
|
||||
|
||||
QStringList questionableRatings = QStringList(safeRatings);
|
||||
questionableRatings.append(QString("Questionable"));
|
||||
|
||||
QStringList explicitRatings = QStringList(questionableRatings);
|
||||
explicitRatings.append(QString("Explicit"));
|
||||
|
||||
map.insert("Safe", safeRatings);
|
||||
map.insert("Questionable", questionableRatings);
|
||||
map.insert("Explicit", explicitRatings);
|
||||
|
||||
return map;
|
||||
|
||||
}
|
||||
|
||||
void DanbooruService::getPostList(int page, QStringList tags, int limit)
|
||||
{
|
||||
|
||||
// We can't fetch more than 100 items, API limitation
|
||||
|
||||
limit = limit > 100 ? 100: limit;
|
||||
|
||||
QMap<QString, QString> map;
|
||||
|
||||
map.insert("limit", QString::number(limit));
|
||||
map.insert("page", QString::number(page));
|
||||
|
||||
KUrl danbooruUrl = requestUrl(m_url, POST_URL, m_username,
|
||||
m_password, map, tags);
|
||||
|
||||
qDebug() << "Final constructed URL" << danbooruUrl.url();
|
||||
|
||||
KIO::StoredTransferJob* job = KIO::storedGet(danbooruUrl, KIO::NoReload,
|
||||
KIO::HideProgressInfo);
|
||||
|
||||
connect(job, SIGNAL(result(KJob*)), this,
|
||||
SLOT(processPostList(KJob*)));
|
||||
|
||||
}
|
||||
|
||||
void DanbooruService::getTagList(int limit, QString name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DanbooruService::getPool(int poolId, int page)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DanbooruService::getPoolList(int page)
|
||||
{
|
||||
|
||||
KUrl danbooruUrl;
|
||||
|
||||
if (page == 0) {
|
||||
danbooruUrl = requestUrl(m_url, POOL_URL, m_username, m_password);
|
||||
} else {
|
||||
QMap<QString, QString> map;
|
||||
map.insert("page", QString::number(page));
|
||||
|
||||
danbooruUrl = requestUrl(m_url, POOL_URL, m_username,
|
||||
m_password, map);
|
||||
}
|
||||
|
||||
qDebug() << "Final constructed URL" << danbooruUrl.url();
|
||||
|
||||
KIO::StoredTransferJob* job = KIO::storedGet(danbooruUrl, KIO::NoReload,
|
||||
KIO::HideProgressInfo);
|
||||
|
||||
connect(job, SIGNAL(result(KJob*)), this,
|
||||
SLOT(processPoolList(KJob*)));
|
||||
|
||||
}
|
||||
|
||||
void DanbooruService::getRelatedTags(QStringList tags,
|
||||
Danbooru::TagType tagType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
|
||||
QStringList DanbooruService::blacklist() const
|
||||
{
|
||||
return m_blacklist;
|
||||
}
|
||||
|
||||
const QStringList DanbooruService::allowedRatings() const
|
||||
{
|
||||
return RATINGS.value(m_maxRating);
|
||||
}
|
||||
|
||||
void DanbooruService::setMaximumAllowedRating(QString rating)
|
||||
{
|
||||
if (RATINGS.contains(rating)) {
|
||||
m_maxRating = rating;
|
||||
}
|
||||
}
|
||||
|
||||
const QString DanbooruService::maximumAllowedRating() const
|
||||
{
|
||||
return m_maxRating;
|
||||
}
|
||||
|
||||
// Slots
|
||||
|
||||
void DanbooruService::processPostList(KJob* job)
|
||||
{
|
||||
|
||||
qDebug() << "Got post data OK";
|
||||
|
||||
if (job->error()) {
|
||||
Q_EMIT(downloadError(job->errorString()));
|
||||
}
|
||||
|
||||
StoredTransferJob* jobResult = qobject_cast<StoredTransferJob*>(job);
|
||||
|
||||
if (jobResult == 0) {
|
||||
Q_EMIT(downloadError(QString("Internal error")));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
QByteArray data = jobResult->data();
|
||||
|
||||
QJson::Parser parser;
|
||||
|
||||
bool ok;
|
||||
|
||||
QVariant result = parser.parse(data, &ok);
|
||||
|
||||
if (!ok) {
|
||||
Q_EMIT(downloadError(QString("Unable to decode data")));
|
||||
return;
|
||||
}
|
||||
|
||||
QList<QVariant> postList = result.toList();
|
||||
|
||||
// How many posts do we have to fetch?
|
||||
|
||||
m_currentPosts = postList.length();
|
||||
|
||||
Q_FOREACH(QVariant element, postList) {
|
||||
|
||||
QVariantMap map = element.toMap();
|
||||
|
||||
DanbooruPost* post = new DanbooruPost(map);
|
||||
|
||||
StoredTransferJob* pixmapJob = KIO::storedGet(post->thumbnailUrl(),
|
||||
KIO::NoReload, KIO::HideProgressInfo);
|
||||
|
||||
// We don't want to overload the servers, so set some rational
|
||||
// priority
|
||||
|
||||
KIO::Scheduler::setJobPriority(static_cast<KIO::SimpleJob*>(job),
|
||||
1);
|
||||
|
||||
QVariant variant;
|
||||
|
||||
variant.setValue(post);
|
||||
|
||||
pixmapJob->setProperty("danbooruPost", variant);
|
||||
connect(pixmapJob, SIGNAL(result(KJob*)), this,
|
||||
SLOT(downloadThumbnail(KJob*)));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DanbooruService::processRelatedTagList(KJob* job)
|
||||
{
|
||||
Q_UNUSED(job)
|
||||
}
|
||||
|
||||
void DanbooruService::processPoolList(KJob* job)
|
||||
{
|
||||
|
||||
qDebug() << "Got pool data OK";
|
||||
|
||||
if (job->error()) {
|
||||
Q_EMIT(downloadError(job->errorString()));
|
||||
}
|
||||
|
||||
StoredTransferJob* jobResult = qobject_cast<StoredTransferJob*>(job);
|
||||
|
||||
if (jobResult == 0) {
|
||||
Q_EMIT(downloadError(QString("Internal error")));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
QByteArray data = jobResult->data();
|
||||
|
||||
QJson::Parser parser;
|
||||
|
||||
bool ok;
|
||||
|
||||
QVariant result = parser.parse(data, &ok);
|
||||
|
||||
if (!ok) {
|
||||
Q_EMIT(downloadError(QString("Unable to decode data")));
|
||||
return;
|
||||
}
|
||||
|
||||
QList<QVariant> poolList = result.toList();
|
||||
|
||||
int currentPools = poolList.length();
|
||||
|
||||
Q_FOREACH(QVariant element, poolList) {
|
||||
QVariantMap map = element.toMap();
|
||||
|
||||
DanbooruPool* pool = new DanbooruPool(map);
|
||||
Q_EMIT(poolDownloaded(pool));
|
||||
}
|
||||
|
||||
qDebug() << "Pool download finished!";
|
||||
Q_EMIT(poolDownloadFinished());
|
||||
|
||||
}
|
||||
|
||||
void DanbooruService::downloadAllTags(KJob* job)
|
||||
{
|
||||
Q_UNUSED(job)
|
||||
}
|
||||
|
||||
void DanbooruService::downloadThumbnail(KJob* job)
|
||||
{
|
||||
|
||||
if (job->error()) {
|
||||
Q_EMIT(downloadError(job->errorString()));
|
||||
}
|
||||
|
||||
QVariant postData = job->property("danbooruPost");
|
||||
|
||||
DanbooruPost* post = postData.value<DanbooruPost*>();
|
||||
QPixmap* pix = new QPixmap();
|
||||
|
||||
StoredTransferJob* jobResult = qobject_cast<StoredTransferJob*>(job);
|
||||
|
||||
if (jobResult == 0) {
|
||||
Q_EMIT(downloadError(QString("Internal error")));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
bool ok = pix->loadFromData(jobResult->data());
|
||||
|
||||
if (!ok) {
|
||||
Q_EMIT(downloadError(QString("Pixmap data could not be loaded")));
|
||||
return;
|
||||
}
|
||||
|
||||
post->setPixmap(pix);
|
||||
|
||||
m_currentPosts--; // One less post to do
|
||||
|
||||
qDebug() << "Current posts remaining" << m_currentPosts;
|
||||
Q_EMIT(postDownloaded(post));
|
||||
|
||||
if (m_currentPosts == 0) {
|
||||
qDebug() << "Post download finished";
|
||||
Q_EMIT(postDownloadFinished());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace Danbooru
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue