Run astyle-kdelibs on the source
This commit is contained in:
parent
4b85d63d68
commit
39aac8c95b
22 changed files with 1227 additions and 1264 deletions
|
@ -17,8 +17,6 @@
|
||||||
* along with Danbooru Client. If not, see <http://www.gnu.org/licenses/>.
|
* along with Danbooru Client. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "danbooruclientview.h"
|
#include "danbooruclientview.h"
|
||||||
|
|
||||||
// Own
|
// Own
|
||||||
|
@ -35,54 +33,53 @@
|
||||||
#include <KRun>
|
#include <KRun>
|
||||||
#include <KFileDialog>
|
#include <KFileDialog>
|
||||||
|
|
||||||
namespace Danbooru {
|
namespace Danbooru
|
||||||
|
{
|
||||||
|
|
||||||
DanbooruClientView::DanbooruClientView(QWidget * parent): QWidget(parent),
|
DanbooruClientView::DanbooruClientView(QWidget *parent): QWidget(parent),
|
||||||
m_model(new DanbooruPostModel(this)),
|
m_model(new DanbooruPostModel(this)),
|
||||||
m_delegate(0),
|
m_delegate(0),
|
||||||
m_service(0),
|
m_service(0),
|
||||||
m_timer(0)
|
m_timer(0)
|
||||||
{
|
{
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
|
||||||
m_delegate = new DanbooruPostDelegate(m_listView);
|
m_delegate = new DanbooruPostDelegate(m_listView);
|
||||||
|
|
||||||
m_listView->setFlow(QListView::LeftToRight);
|
m_listView->setFlow(QListView::LeftToRight);
|
||||||
m_listView->setResizeMode(QListView::Adjust);
|
m_listView->setResizeMode(QListView::Adjust);
|
||||||
m_listView->setWrapping(true);
|
m_listView->setWrapping(true);
|
||||||
m_listView->setViewMode(QListView::IconMode);
|
m_listView->setViewMode(QListView::IconMode);
|
||||||
m_listView->setGridSize(QSize(256,256));
|
m_listView->setGridSize(QSize(256, 256));
|
||||||
|
|
||||||
m_listView->setModel(m_model);
|
m_listView->setModel(m_model);
|
||||||
m_listView->setItemDelegate(m_delegate);
|
m_listView->setItemDelegate(m_delegate);
|
||||||
|
|
||||||
// signal-slot connections
|
// signal-slot connections
|
||||||
|
|
||||||
connect(m_delegate, &DanbooruPostDelegate::postDownloadRequested, this, &DanbooruClientView::slotHandleDownload);
|
connect(m_delegate, &DanbooruPostDelegate::postDownloadRequested, this, &DanbooruClientView::slotHandleDownload);
|
||||||
connect(m_delegate, &DanbooruPostDelegate::postViewRequested, this, &DanbooruClientView::slotHandleView);
|
connect(m_delegate, &DanbooruPostDelegate::postViewRequested, this, &DanbooruClientView::slotHandleView);
|
||||||
// connect(m_listView, SIGNAL(clicked(const QModelIndex&)), parent(),
|
// connect(m_listView, SIGNAL(clicked(QModelIndex)), parent(),
|
||||||
// SLOT(displayInfo(const QModelIndex&));
|
// SLOT(displayInfo(QModelIndex));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
DanbooruClientView::~DanbooruClientView()
|
||||||
|
{
|
||||||
|
|
||||||
DanbooruClientView::~DanbooruClientView()
|
}
|
||||||
{
|
|
||||||
|
|
||||||
}
|
void DanbooruClientView::slotHandleDownload(QUrl url)
|
||||||
|
{
|
||||||
void DanbooruClientView::slotHandleDownload(QUrl url)
|
// TODO
|
||||||
{
|
Q_UNUSED(url)
|
||||||
// TODO
|
}
|
||||||
Q_UNUSED(url)
|
|
||||||
}
|
|
||||||
|
|
||||||
void DanbooruClientView::slotHandleView(QUrl url)
|
|
||||||
{
|
|
||||||
KRun* runViewer = new KRun(url, this /*window*/, true /*showProgressInfo*/,
|
|
||||||
"" /*asn*/);
|
|
||||||
runViewer->setAutoDelete(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void DanbooruClientView::slotHandleView(QUrl url)
|
||||||
|
{
|
||||||
|
KRun *runViewer = new KRun(url, this /*window*/, true /*showProgressInfo*/,
|
||||||
|
"" /*asn*/);
|
||||||
|
runViewer->setAutoDelete(true);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Danbooru
|
} // namespace Danbooru
|
||||||
|
|
|
@ -28,47 +28,48 @@
|
||||||
|
|
||||||
class QTimer;
|
class QTimer;
|
||||||
|
|
||||||
namespace Danbooru {
|
namespace Danbooru
|
||||||
|
{
|
||||||
|
|
||||||
class DanbooruPostModel;
|
class DanbooruPostModel;
|
||||||
class DanbooruPostDelegate;
|
class DanbooruPostDelegate;
|
||||||
class DanbooruService;
|
class DanbooruService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the main view class for danbooru_client. Most of the non-menu,
|
||||||
|
* non-toolbar, and non-statusbar (e.g., non frame) GUI code should go
|
||||||
|
* here.
|
||||||
|
*
|
||||||
|
* @short Main view
|
||||||
|
* @author %{AUTHOR} <%{EMAIL}>
|
||||||
|
* @version %{VERSION}
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DanbooruClientView : public QWidget, public Ui::DanbooruClientView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*/
|
||||||
|
DanbooruClientView(QWidget *parent = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the main view class for danbooru_client. Most of the non-menu,
|
* Destructor
|
||||||
* non-toolbar, and non-statusbar (e.g., non frame) GUI code should go
|
|
||||||
* here.
|
|
||||||
*
|
|
||||||
* @short Main view
|
|
||||||
* @author %{AUTHOR} <%{EMAIL}>
|
|
||||||
* @version %{VERSION}
|
|
||||||
*/
|
*/
|
||||||
|
virtual ~DanbooruClientView();
|
||||||
|
|
||||||
class DanbooruClientView : public QWidget, public Ui::DanbooruClientView
|
private Q_SLOTS:
|
||||||
{
|
void slotHandleDownload(QUrl);
|
||||||
Q_OBJECT
|
void slotHandleView(QUrl);
|
||||||
|
|
||||||
public:
|
private:
|
||||||
/**
|
DanbooruPostModel *m_model;
|
||||||
* Default constructor
|
DanbooruPostDelegate *m_delegate;
|
||||||
*/
|
DanbooruService *m_service;
|
||||||
DanbooruClientView(QWidget *parent=0);
|
|
||||||
|
|
||||||
/**
|
QTimer *m_timer;
|
||||||
* Destructor
|
|
||||||
*/
|
|
||||||
virtual ~DanbooruClientView();
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void slotHandleDownload(QUrl);
|
|
||||||
void slotHandleView(QUrl);
|
|
||||||
|
|
||||||
private:
|
|
||||||
DanbooruPostModel* m_model;
|
|
||||||
DanbooruPostDelegate* m_delegate;
|
|
||||||
DanbooruService* m_service;
|
|
||||||
|
|
||||||
QTimer* m_timer;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -27,10 +27,10 @@
|
||||||
|
|
||||||
#include <KWallet>
|
#include <KWallet>
|
||||||
|
|
||||||
|
|
||||||
using KWallet::Wallet;
|
using KWallet::Wallet;
|
||||||
|
|
||||||
namespace Danbooru {
|
namespace Danbooru
|
||||||
|
{
|
||||||
|
|
||||||
const QMap< QUrl, QString > initBoardSalts()
|
const QMap< QUrl, QString > initBoardSalts()
|
||||||
{
|
{
|
||||||
|
@ -38,13 +38,13 @@ const QMap< QUrl, QString > initBoardSalts()
|
||||||
QMap< QUrl, QString > boardSalts;
|
QMap< QUrl, QString > boardSalts;
|
||||||
|
|
||||||
boardSalts.insert(QUrl("http://konachan.com"),
|
boardSalts.insert(QUrl("http://konachan.com"),
|
||||||
QString("So-I-Heard-You-Like-Mupkids-?--%1--"));
|
QString("So-I-Heard-You-Like-Mupkids-?--%1--"));
|
||||||
boardSalts.insert(QUrl("http://konachan.net"),
|
boardSalts.insert(QUrl("http://konachan.net"),
|
||||||
QString("So-I-Heard-You-Like-Mupkids-?--%1--"));
|
QString("So-I-Heard-You-Like-Mupkids-?--%1--"));
|
||||||
boardSalts.insert(QUrl("http://yande.re"),
|
boardSalts.insert(QUrl("http://yande.re"),
|
||||||
QString("choujin-steiner--%1--"));
|
QString("choujin-steiner--%1--"));
|
||||||
boardSalts.insert(QUrl("http://danbooru.donmai.us"),
|
boardSalts.insert(QUrl("http://danbooru.donmai.us"),
|
||||||
QString("choujin-steiner--%1--"));
|
QString("choujin-steiner--%1--"));
|
||||||
|
|
||||||
return boardSalts;
|
return boardSalts;
|
||||||
}
|
}
|
||||||
|
@ -52,9 +52,9 @@ const QMap< QUrl, QString > initBoardSalts()
|
||||||
const QMap<QUrl, QString> DanbooruConnectWidget::boardSalts = initBoardSalts();
|
const QMap<QUrl, QString> DanbooruConnectWidget::boardSalts = initBoardSalts();
|
||||||
|
|
||||||
DanbooruConnectWidget::DanbooruConnectWidget(QVector< QUrl > urlList,
|
DanbooruConnectWidget::DanbooruConnectWidget(QVector< QUrl > urlList,
|
||||||
QWidget* parent):
|
QWidget *parent):
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
m_wallet(0)
|
m_wallet(0)
|
||||||
|
|
||||||
{
|
{
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
@ -74,13 +74,13 @@ DanbooruConnectWidget::DanbooruConnectWidget(QVector< QUrl > urlList,
|
||||||
|
|
||||||
danbooruUrlComboBox->clear();
|
danbooruUrlComboBox->clear();
|
||||||
|
|
||||||
for (auto item: urlList) {
|
for (auto item : urlList) {
|
||||||
danbooruUrlComboBox->insertUrl(urlList.indexOf(item), item);
|
danbooruUrlComboBox->insertUrl(urlList.indexOf(item), item);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_wallet = Wallet::openWallet(Wallet::NetworkWallet(), winid,
|
m_wallet = Wallet::openWallet(Wallet::NetworkWallet(), winid,
|
||||||
Wallet::Asynchronous
|
Wallet::Asynchronous
|
||||||
);
|
);
|
||||||
|
|
||||||
connect(m_wallet, &KWallet::Wallet::walletOpened, this, &DanbooruConnectWidget::checkWallet);
|
connect(m_wallet, &KWallet::Wallet::walletOpened, this, &DanbooruConnectWidget::checkWallet);
|
||||||
|
|
||||||
|
@ -122,7 +122,6 @@ void DanbooruConnectWidget::getWalletData()
|
||||||
|
|
||||||
if (m_wallet->hasEntry(key)) {
|
if (m_wallet->hasEntry(key)) {
|
||||||
|
|
||||||
|
|
||||||
if (m_wallet->readMap(key, valueMap) != 0) {
|
if (m_wallet->readMap(key, valueMap) != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -133,7 +132,6 @@ void DanbooruConnectWidget::getWalletData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DanbooruConnectWidget::toggleLineEdits(int state)
|
void DanbooruConnectWidget::toggleLineEdits(int state)
|
||||||
{
|
{
|
||||||
if (state == Qt::Unchecked) {
|
if (state == Qt::Unchecked) {
|
||||||
|
@ -145,7 +143,6 @@ void DanbooruConnectWidget::toggleLineEdits(int state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DanbooruConnectWidget::emitRejected()
|
void DanbooruConnectWidget::emitRejected()
|
||||||
{
|
{
|
||||||
Q_EMIT rejected();
|
Q_EMIT rejected();
|
||||||
|
@ -161,7 +158,6 @@ QString DanbooruConnectWidget::username() const
|
||||||
return m_username;
|
return m_username;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QString DanbooruConnectWidget::password() const
|
QString DanbooruConnectWidget::password() const
|
||||||
{
|
{
|
||||||
return m_password;
|
return m_password;
|
||||||
|
@ -178,7 +174,7 @@ void DanbooruConnectWidget::accept()
|
||||||
if (!m_username.isEmpty() && !m_password.isEmpty()) {
|
if (!m_username.isEmpty() && !m_password.isEmpty()) {
|
||||||
|
|
||||||
if (m_wallet && !m_wallet->hasEntry(m_boardUrl.url())) {
|
if (m_wallet && !m_wallet->hasEntry(m_boardUrl.url())) {
|
||||||
QMap<QString,QString> dataMap;
|
QMap<QString, QString> dataMap;
|
||||||
dataMap.insert(QLatin1String("username"), m_username);
|
dataMap.insert(QLatin1String("username"), m_username);
|
||||||
dataMap.insert(QLatin1String("password"), m_password);
|
dataMap.insert(QLatin1String("password"), m_password);
|
||||||
m_wallet->writeMap(m_boardUrl.url(), dataMap);
|
m_wallet->writeMap(m_boardUrl.url(), dataMap);
|
||||||
|
@ -186,16 +182,15 @@ void DanbooruConnectWidget::accept()
|
||||||
|
|
||||||
hashedPassword = boardSalts.value(m_boardUrl).arg(m_password);
|
hashedPassword = boardSalts.value(m_boardUrl).arg(m_password);
|
||||||
hashedPassword = QCryptographicHash::hash(hashedPassword.toUtf8(),
|
hashedPassword = QCryptographicHash::hash(hashedPassword.toUtf8(),
|
||||||
QCryptographicHash::Sha1
|
QCryptographicHash::Sha1
|
||||||
).toHex();
|
).toHex();
|
||||||
}
|
}
|
||||||
|
|
||||||
DanbooruService* service = new DanbooruService(m_boardUrl, m_username,
|
DanbooruService *service = new DanbooruService(m_boardUrl, m_username,
|
||||||
hashedPassword);
|
hashedPassword);
|
||||||
Q_EMIT(connectionEstablished(service));
|
Q_EMIT(connectionEstablished(service));
|
||||||
|
|
||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}; // namespace Danbooru
|
}; // namespace Danbooru
|
||||||
|
|
|
@ -28,46 +28,48 @@
|
||||||
|
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
namespace KWallet {
|
namespace KWallet
|
||||||
class Wallet;
|
{
|
||||||
|
class Wallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Danbooru {
|
namespace Danbooru
|
||||||
|
{
|
||||||
|
|
||||||
class DanbooruService;
|
class DanbooruService;
|
||||||
|
|
||||||
const QMap< QUrl, QString > initBoardSalts();
|
const QMap< QUrl, QString > initBoardSalts();
|
||||||
|
|
||||||
class DanbooruConnectWidget: public QWidget, public Ui::DanbooruConnectWidget {
|
class DanbooruConnectWidget: public QWidget, public Ui::DanbooruConnectWidget
|
||||||
Q_OBJECT
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DanbooruConnectWidget(QVector<QUrl> urlList,
|
explicit DanbooruConnectWidget(QVector<QUrl> urlList,
|
||||||
QWidget* parent = 0);
|
QWidget *parent = 0);
|
||||||
~DanbooruConnectWidget();
|
~DanbooruConnectWidget();
|
||||||
|
|
||||||
QString username() const;
|
QString username() const;
|
||||||
QString password() const;
|
QString password() const;
|
||||||
QUrl boardUrl() const;
|
QUrl boardUrl() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QUrl m_boardUrl;
|
QUrl m_boardUrl;
|
||||||
QString m_username;
|
QString m_username;
|
||||||
QString m_password;
|
QString m_password;
|
||||||
KWallet::Wallet* m_wallet;
|
KWallet::Wallet *m_wallet;
|
||||||
static const QMap<QUrl, QString> boardSalts;
|
static const QMap<QUrl, QString> boardSalts;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void connectionEstablished(DanbooruService* service);
|
void connectionEstablished(DanbooruService *service);
|
||||||
void rejected();
|
void rejected();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
private Q_SLOTS:
|
void checkWallet(bool);
|
||||||
void checkWallet(bool);
|
void getWalletData();
|
||||||
void getWalletData();
|
void toggleLineEdits(int state);
|
||||||
void toggleLineEdits(int state);
|
void emitRejected();
|
||||||
void emitRejected();
|
void accept();
|
||||||
void accept();
|
};
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Danbooru
|
} // namespace Danbooru
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
* @file danbooru.h
|
* @file danbooru.h
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
namespace Danbooru {
|
namespace Danbooru
|
||||||
|
{
|
||||||
|
|
||||||
}; // namespace Danbooru
|
}; // namespace Danbooru
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,11 @@
|
||||||
|
|
||||||
#include "danboorupool.h"
|
#include "danboorupool.h"
|
||||||
|
|
||||||
namespace Danbooru {
|
namespace Danbooru
|
||||||
|
{
|
||||||
|
|
||||||
DanbooruPool::DanbooruPool(const QVariantMap& postData, QObject* parent):
|
DanbooruPool::DanbooruPool(const QVariantMap &postData, QObject *parent):
|
||||||
QObject(parent), m_posts(QList<int>())
|
QObject(parent), m_posts(QList<int>())
|
||||||
{
|
{
|
||||||
m_id = postData.value("id").toInt();
|
m_id = postData.value("id").toInt();
|
||||||
m_name = postData.value("name").toString();
|
m_name = postData.value("name").toString();
|
||||||
|
@ -68,13 +69,12 @@ void DanbooruPool::addPosts(QList< int > posts)
|
||||||
m_posts.append(posts);
|
m_posts.append(posts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DanbooruPool::addPosts(const QStringList& posts)
|
void DanbooruPool::addPosts(const QStringList &posts)
|
||||||
{
|
{
|
||||||
|
|
||||||
for (auto post: posts) {
|
for (auto post : posts) {
|
||||||
m_posts.append(post.toInt());
|
m_posts.append(post.toInt());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Danbooru
|
} // namespace Danbooru
|
||||||
|
|
|
@ -37,74 +37,75 @@
|
||||||
#include <QtCore/QStringList>
|
#include <QtCore/QStringList>
|
||||||
#include <QtXml/QXmlStreamAttributes>
|
#include <QtXml/QXmlStreamAttributes>
|
||||||
|
|
||||||
namespace Danbooru {
|
namespace Danbooru
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Class representing a Danbooru pool.
|
* @brief Class representing a Danbooru pool.
|
||||||
*
|
*
|
||||||
* Pools are organized groups of images, often by a common theme, for
|
* Pools are organized groups of images, often by a common theme, for
|
||||||
* example taken from the same artbook. They are identified by unique IDs
|
* example taken from the same artbook. They are identified by unique IDs
|
||||||
* and are represented by a name, a description, and the posts they
|
* and are represented by a name, a description, and the posts they
|
||||||
* contain.
|
* contain.
|
||||||
*
|
*
|
||||||
* @author Luca Beltrame (lbeltrame@kde.org)
|
* @author Luca Beltrame (lbeltrame@kde.org)
|
||||||
*
|
*
|
||||||
* **/
|
* **/
|
||||||
class DanbooruPool : public QObject
|
class DanbooruPool : public QObject
|
||||||
{
|
{
|
||||||
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_id;
|
int m_id;
|
||||||
int m_postCount;
|
int m_postCount;
|
||||||
QString m_name;
|
QString m_name;
|
||||||
QString m_description;
|
QString m_description;
|
||||||
QList<int> m_posts;
|
QList<int> m_posts;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Construct a Danbooru pool from a QVariantMap.
|
* @brief Construct a Danbooru pool from a QVariantMap.
|
||||||
*
|
*
|
||||||
* This form is the easiest to use and should be used when dealing with
|
* This form is the easiest to use and should be used when dealing with
|
||||||
* responses in JSON format. Unfortunately most Danbooru
|
* responses in JSON format. Unfortunately most Danbooru
|
||||||
* implementations produce broken JSON for some responses.
|
* implementations produce broken JSON for some responses.
|
||||||
*
|
*
|
||||||
* @param postData A QVariantMap from parsed JSON representing the
|
* @param postData A QVariantMap from parsed JSON representing the
|
||||||
* data from a single pool.
|
* data from a single pool.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
DanbooruPool(const QVariantMap& postData, QObject* parent = 0);
|
DanbooruPool(const QVariantMap &postData, QObject *parent = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Construct a Danbooru pool from a QVariantMap.
|
* @brief Construct a Danbooru pool from a QVariantMap.
|
||||||
*
|
*
|
||||||
* This form is the easiest to use and should be used when dealing with
|
* This form is the easiest to use and should be used when dealing with
|
||||||
* responses in JSON format. Unfortunately most Danbooru
|
* responses in JSON format. Unfortunately most Danbooru
|
||||||
* implementations produce broken JSON for some responses.
|
* implementations produce broken JSON for some responses.
|
||||||
*
|
*
|
||||||
* @param postData A QXmlStreamAttributes instance holding the
|
* @param postData A QXmlStreamAttributes instance holding the
|
||||||
* attributes for the given pool.
|
* attributes for the given pool.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
DanbooruPool(const QXmlStreamAttributes& postData, QObject* parent=0);
|
DanbooruPool(const QXmlStreamAttributes &postData, QObject *parent = 0);
|
||||||
|
|
||||||
int id() const;
|
int id() const;
|
||||||
int postCount() const;
|
int postCount() const;
|
||||||
QString name() const;
|
QString name() const;
|
||||||
QString description() const;
|
QString description() const;
|
||||||
QList<int> posts() const;
|
QList<int> posts() const;
|
||||||
|
|
||||||
void addPost(int post);
|
void addPost(int post);
|
||||||
void addPosts(QList<int> posts);
|
void addPosts(QList<int> posts);
|
||||||
void addPosts(const QStringList& posts);
|
void addPosts(const QStringList &posts);
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace Danbooru
|
}; // namespace Danbooru
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(Danbooru::DanbooruPool*)
|
Q_DECLARE_METATYPE(Danbooru::DanbooruPool *)
|
||||||
|
|
||||||
#endif // DANBOORUPOOL_H
|
#endif // DANBOORUPOOL_H
|
||||||
|
|
|
@ -33,14 +33,13 @@
|
||||||
|
|
||||||
#include "danboorupost.h"
|
#include "danboorupost.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Danbooru
|
namespace Danbooru
|
||||||
{
|
{
|
||||||
|
|
||||||
const QMap<QString, DanbooruPost::Rating> DanbooruPost::RATING_MAP = initRatingMap();
|
const QMap<QString, DanbooruPost::Rating> DanbooruPost::RATING_MAP = initRatingMap();
|
||||||
|
|
||||||
DanbooruPost::DanbooruPost(QVariantMap postData, QPixmap pixmap,
|
DanbooruPost::DanbooruPost(QVariantMap postData, QPixmap pixmap,
|
||||||
QObject* parent):
|
QObject *parent):
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_pixmap(pixmap)
|
m_pixmap(pixmap)
|
||||||
{
|
{
|
||||||
|
@ -57,7 +56,7 @@ DanbooruPost::DanbooruPost(QVariantMap postData, QPixmap pixmap,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DanbooruPost::DanbooruPost(QXmlStreamAttributes& postData, QPixmap pixmap, QObject* parent):
|
DanbooruPost::DanbooruPost(QXmlStreamAttributes &postData, QPixmap pixmap, QObject *parent):
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_pixmap(pixmap)
|
m_pixmap(pixmap)
|
||||||
{
|
{
|
||||||
|
@ -73,12 +72,10 @@ DanbooruPost::DanbooruPost(QXmlStreamAttributes& postData, QPixmap pixmap, QObje
|
||||||
m_rating = RATING_MAP.value(postData.value("rating").toString());
|
m_rating = RATING_MAP.value(postData.value("rating").toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DanbooruPost::~DanbooruPost()
|
DanbooruPost::~DanbooruPost()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const QMap< QString, DanbooruPost::Rating > DanbooruPost::initRatingMap()
|
const QMap< QString, DanbooruPost::Rating > DanbooruPost::initRatingMap()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -91,13 +88,11 @@ const QMap< QString, DanbooruPost::Rating > DanbooruPost::initRatingMap()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DanbooruPost::operator==(const Danbooru::DanbooruPost &other)
|
||||||
bool DanbooruPost::operator==(const Danbooru::DanbooruPost& other)
|
|
||||||
{
|
{
|
||||||
return m_url == other.m_url && m_id == other.m_id;
|
return m_url == other.m_url && m_id == other.m_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DanbooruPost::setPixmap(const QPixmap &pixmap)
|
void DanbooruPost::setPixmap(const QPixmap &pixmap)
|
||||||
{
|
{
|
||||||
m_pixmap = pixmap;
|
m_pixmap = pixmap;
|
||||||
|
@ -155,7 +150,5 @@ Danbooru::DanbooruPost::Rating DanbooruPost::rating() const
|
||||||
return m_rating;
|
return m_rating;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Danbooru
|
} // namespace Danbooru
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,28 +45,28 @@
|
||||||
|
|
||||||
#include "danbooru.h"
|
#include "danbooru.h"
|
||||||
|
|
||||||
|
namespace Danbooru
|
||||||
|
{
|
||||||
|
|
||||||
namespace Danbooru {
|
/**
|
||||||
|
* @brief A class representing a Danbooru post.
|
||||||
/**
|
*
|
||||||
* @brief A class representing a Danbooru post.
|
* A Danbooru post is an object that models the posts present in a
|
||||||
*
|
* Danbooru board, that is an image with associated information.
|
||||||
* A Danbooru post is an object that models the posts present in a
|
*
|
||||||
* Danbooru board, that is an image with associated information.
|
* In particular, posts contain information on the id, size and dimensions
|
||||||
*
|
* of the image, its tags, "preview url" (URL to the thumbnail) and
|
||||||
* In particular, posts contain information on the id, size and dimensions
|
* file URL.
|
||||||
* of the image, its tags, "preview url" (URL to the thumbnail) and
|
*
|
||||||
* file URL.
|
* This is used directly by the DanbooruService class.
|
||||||
*
|
*
|
||||||
* This is used directly by the DanbooruService class.
|
* @author Luca Beltrame (lbeltrame@kde.org)
|
||||||
*
|
*
|
||||||
* @author Luca Beltrame (lbeltrame@kde.org)
|
* @see DanbooruService, DanbooruPool
|
||||||
*
|
*
|
||||||
* @see DanbooruService, DanbooruPool
|
**/
|
||||||
*
|
class DanbooruPost : public QObject
|
||||||
**/
|
{
|
||||||
class DanbooruPost : public QObject
|
|
||||||
{
|
|
||||||
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ namespace Danbooru {
|
||||||
Q_PROPERTY(QSet<QString> tags READ tags)
|
Q_PROPERTY(QSet<QString> tags READ tags)
|
||||||
Q_PROPERTY(QUrl thumbnailUrl READ thumbnailUrl)
|
Q_PROPERTY(QUrl thumbnailUrl READ thumbnailUrl)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Ratings for a Danbooru item
|
* @brief Ratings for a Danbooru item
|
||||||
|
@ -88,140 +88,136 @@ namespace Danbooru {
|
||||||
Safe = 1, /**< Safe for the general public **/
|
Safe = 1, /**< Safe for the general public **/
|
||||||
Questionable = 2, /**< Might contain hints of risqueness of violence **/
|
Questionable = 2, /**< Might contain hints of risqueness of violence **/
|
||||||
Explicit = 4 /**< Explicit material **/
|
Explicit = 4 /**< Explicit material **/
|
||||||
};
|
|
||||||
Q_DECLARE_FLAGS(Ratings, DanbooruPost::Rating)
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
QPixmap m_pixmap;
|
|
||||||
|
|
||||||
// basic features of a post
|
|
||||||
|
|
||||||
int m_id;
|
|
||||||
int m_height;
|
|
||||||
int m_width;
|
|
||||||
int m_size;
|
|
||||||
|
|
||||||
QUrl m_url;
|
|
||||||
QUrl m_thumbnailUrl;
|
|
||||||
QSet<QString> m_tags;
|
|
||||||
DanbooruPost::Rating m_rating;
|
|
||||||
|
|
||||||
static const QMap<QString, Rating> RATING_MAP;
|
|
||||||
|
|
||||||
// Private functions
|
|
||||||
|
|
||||||
static const QMap< QString, Rating > initRatingMap();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Construct a Danbooru post from a QVariantMap.
|
|
||||||
*
|
|
||||||
* This form is the easiest to use and should be used when dealing with
|
|
||||||
* responses in JSON format. Unfortunately most Danbooru
|
|
||||||
* implementations produce broken JSON for some responses.
|
|
||||||
*
|
|
||||||
* @param postData A QVariantMap from parsed JSON representing the
|
|
||||||
* data from a single post.
|
|
||||||
* @param pixmap A QPixmap pointer to the post thumbnail.
|
|
||||||
* @param parent A pointer to the parent QObject.
|
|
||||||
*
|
|
||||||
**/
|
|
||||||
explicit DanbooruPost(QVariantMap postData, QPixmap pixmap = QPixmap(),
|
|
||||||
QObject* parent = 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Construct a Danbooru post from XML attributes
|
|
||||||
*
|
|
||||||
* This is an overloaded function which uses XML attributes rather
|
|
||||||
* than JSON. It should be used in case the JSON responses aren't
|
|
||||||
* complete or broken (for example pools' posts in most Danbooru
|
|
||||||
* instances).
|
|
||||||
*
|
|
||||||
* @param postData A QXmlStreamAttributes instance holding the
|
|
||||||
* attributes for the given post.
|
|
||||||
* @param pixmap A QPixmap pointer to the post thumbnail.
|
|
||||||
* @param parent A pointer to the parent QObject.
|
|
||||||
*
|
|
||||||
**/
|
|
||||||
explicit DanbooruPost(QXmlStreamAttributes& postData,
|
|
||||||
QPixmap pixmap = QPixmap(), QObject* parent =0);
|
|
||||||
|
|
||||||
bool operator==(const DanbooruPost&);
|
|
||||||
|
|
||||||
~DanbooruPost();
|
|
||||||
|
|
||||||
// Post attributes
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The ID of the post.
|
|
||||||
**/
|
|
||||||
int id() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The height in pixels of the post's image.
|
|
||||||
**/
|
|
||||||
int height() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The width in pixels of the post's image.
|
|
||||||
**/
|
|
||||||
int width() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The size in bytes of the post's image.
|
|
||||||
**/
|
|
||||||
int size() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The URL to the post's image.
|
|
||||||
**/
|
|
||||||
const QUrl fileUrl() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The tags associated to the post.
|
|
||||||
**/
|
|
||||||
const QSet< QString > tags() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The URL to the post's thumbnail.
|
|
||||||
**/
|
|
||||||
const QUrl thumbnailUrl() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return A pointer to the thumbnail's pixmap.
|
|
||||||
**/
|
|
||||||
QPixmap pixmap() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The current post's rating.
|
|
||||||
**/
|
|
||||||
Rating rating() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the post's pixmap to a specific QPixmap instance's pointer.
|
|
||||||
*
|
|
||||||
**/
|
|
||||||
void setPixmap(const QPixmap& pixmap);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return A string representation of the post.
|
|
||||||
*
|
|
||||||
* **/
|
|
||||||
const QString toString();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Q_DECLARE_FLAGS(Ratings, DanbooruPost::Rating)
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(DanbooruPost::Ratings)
|
QPixmap m_pixmap;
|
||||||
|
|
||||||
|
// basic features of a post
|
||||||
|
|
||||||
|
int m_id;
|
||||||
|
int m_height;
|
||||||
|
int m_width;
|
||||||
|
int m_size;
|
||||||
|
|
||||||
|
QUrl m_url;
|
||||||
|
QUrl m_thumbnailUrl;
|
||||||
|
QSet<QString> m_tags;
|
||||||
|
DanbooruPost::Rating m_rating;
|
||||||
|
|
||||||
|
static const QMap<QString, Rating> RATING_MAP;
|
||||||
|
|
||||||
|
// Private functions
|
||||||
|
|
||||||
|
static const QMap< QString, Rating > initRatingMap();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct a Danbooru post from a QVariantMap.
|
||||||
|
*
|
||||||
|
* This form is the easiest to use and should be used when dealing with
|
||||||
|
* responses in JSON format. Unfortunately most Danbooru
|
||||||
|
* implementations produce broken JSON for some responses.
|
||||||
|
*
|
||||||
|
* @param postData A QVariantMap from parsed JSON representing the
|
||||||
|
* data from a single post.
|
||||||
|
* @param pixmap A QPixmap pointer to the post thumbnail.
|
||||||
|
* @param parent A pointer to the parent QObject.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
explicit DanbooruPost(QVariantMap postData, QPixmap pixmap = QPixmap(),
|
||||||
|
QObject *parent = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct a Danbooru post from XML attributes
|
||||||
|
*
|
||||||
|
* This is an overloaded function which uses XML attributes rather
|
||||||
|
* than JSON. It should be used in case the JSON responses aren't
|
||||||
|
* complete or broken (for example pools' posts in most Danbooru
|
||||||
|
* instances).
|
||||||
|
*
|
||||||
|
* @param postData A QXmlStreamAttributes instance holding the
|
||||||
|
* attributes for the given post.
|
||||||
|
* @param pixmap A QPixmap pointer to the post thumbnail.
|
||||||
|
* @param parent A pointer to the parent QObject.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
explicit DanbooruPost(QXmlStreamAttributes &postData,
|
||||||
|
QPixmap pixmap = QPixmap(), QObject *parent = 0);
|
||||||
|
|
||||||
|
bool operator==(const DanbooruPost &);
|
||||||
|
|
||||||
|
~DanbooruPost();
|
||||||
|
|
||||||
|
// Post attributes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The ID of the post.
|
||||||
|
**/
|
||||||
|
int id() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The height in pixels of the post's image.
|
||||||
|
**/
|
||||||
|
int height() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The width in pixels of the post's image.
|
||||||
|
**/
|
||||||
|
int width() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The size in bytes of the post's image.
|
||||||
|
**/
|
||||||
|
int size() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The URL to the post's image.
|
||||||
|
**/
|
||||||
|
const QUrl fileUrl() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The tags associated to the post.
|
||||||
|
**/
|
||||||
|
const QSet< QString > tags() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The URL to the post's thumbnail.
|
||||||
|
**/
|
||||||
|
const QUrl thumbnailUrl() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A pointer to the thumbnail's pixmap.
|
||||||
|
**/
|
||||||
|
QPixmap pixmap() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The current post's rating.
|
||||||
|
**/
|
||||||
|
Rating rating() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the post's pixmap to a specific QPixmap instance's pointer.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void setPixmap(const QPixmap &pixmap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A string representation of the post.
|
||||||
|
*
|
||||||
|
* **/
|
||||||
|
const QString toString();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(DanbooruPost::Ratings)
|
||||||
|
|
||||||
}; // namespace Danbooru
|
}; // namespace Danbooru
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(Danbooru::DanbooruPost*)
|
Q_DECLARE_METATYPE(Danbooru::DanbooruPost *)
|
||||||
|
|
||||||
#endif // DANBOORUPOST_H
|
#endif // DANBOORUPOST_H
|
||||||
|
|
||||||
|
|
|
@ -53,9 +53,9 @@ const QString DanbooruService::ARTIST_URL = "artist/index.json";
|
||||||
const QString DanbooruService::POOL_DATA_URL = "pool/show.xml";
|
const QString DanbooruService::POOL_DATA_URL = "pool/show.xml";
|
||||||
const QString DanbooruService::RELATED_TAG_URL = "tag/related.json";
|
const QString DanbooruService::RELATED_TAG_URL = "tag/related.json";
|
||||||
|
|
||||||
DanbooruService::DanbooruService(QUrl& boardUrl, QString username,
|
DanbooruService::DanbooruService(QUrl &boardUrl, QString username,
|
||||||
QString password, KImageCache* cache,
|
QString password, KImageCache *cache,
|
||||||
QObject* parent):
|
QObject *parent):
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_url(boardUrl),
|
m_url(boardUrl),
|
||||||
m_username(username),
|
m_username(username),
|
||||||
|
@ -71,7 +71,6 @@ DanbooruService::~DanbooruService()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DanbooruService::getPostList(int page, QStringList tags, int limit)
|
void DanbooruService::getPostList(int page, QStringList tags, int limit)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -89,7 +88,7 @@ void DanbooruService::getPostList(int page, QStringList tags, int limit)
|
||||||
|
|
||||||
// qDebug() << "Final constructed post URL" << danbooruUrl.url();
|
// qDebug() << "Final constructed post URL" << danbooruUrl.url();
|
||||||
|
|
||||||
KIO::StoredTransferJob* job = KIO::storedGet(danbooruUrl, KIO::NoReload,
|
KIO::StoredTransferJob *job = KIO::storedGet(danbooruUrl, KIO::NoReload,
|
||||||
KIO::HideProgressInfo);
|
KIO::HideProgressInfo);
|
||||||
|
|
||||||
// This job can use JSON data
|
// This job can use JSON data
|
||||||
|
@ -97,7 +96,6 @@ void DanbooruService::getPostList(int page, QStringList tags, int limit)
|
||||||
|
|
||||||
connect(job, &KIO::StoredTransferJob::result, this, &DanbooruService::processPostList);
|
connect(job, &KIO::StoredTransferJob::result, this, &DanbooruService::processPostList);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DanbooruService::getTagList(int limit, QString name)
|
void DanbooruService::getTagList(int limit, QString name)
|
||||||
|
@ -114,38 +112,38 @@ void DanbooruService::getTagList(int limit, QString name)
|
||||||
parameters);
|
parameters);
|
||||||
//qDebug() << "Final constructed tag URL" << danbooruUrl.url();
|
//qDebug() << "Final constructed tag URL" << danbooruUrl.url();
|
||||||
|
|
||||||
KIO::StoredTransferJob* job = KIO::storedGet(danbooruUrl, KIO::NoReload,
|
KIO::StoredTransferJob *job = KIO::storedGet(danbooruUrl, KIO::NoReload,
|
||||||
KIO::HideProgressInfo);
|
KIO::HideProgressInfo);
|
||||||
|
|
||||||
connect(job, &KIO::StoredTransferJob::result, [this](KJob* job) {
|
connect(job, &KIO::StoredTransferJob::result, [this](KJob * job) {
|
||||||
|
|
||||||
if (job->error()) {
|
|
||||||
Q_EMIT(downloadError(job->errorString()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
StoredTransferJob* jobResult = qobject_cast<StoredTransferJob*>(job);
|
|
||||||
QByteArray data = jobResult->data();
|
|
||||||
|
|
||||||
bool ok;
|
|
||||||
|
|
||||||
// Most Danbooru implementations return tags in wrong order when
|
|
||||||
// using JSON, so we have to fall back to XML
|
|
||||||
QList<QVariant> tagList = parseDanbooruResult(data, "tag", &ok);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
Q_EMIT(downloadError(QString("Unable to decode data")));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto element : tagList) {
|
|
||||||
QVariantMap map = element.toMap();
|
|
||||||
DanbooruTag* tag = new DanbooruTag(map);
|
|
||||||
Q_EMIT(tagDownloaded(tag));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (job->error()) {
|
||||||
|
Q_EMIT(downloadError(job->errorString()));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
StoredTransferJob *jobResult = qobject_cast<StoredTransferJob *>(job);
|
||||||
|
QByteArray data = jobResult->data();
|
||||||
|
|
||||||
|
bool ok;
|
||||||
|
|
||||||
|
// Most Danbooru implementations return tags in wrong order when
|
||||||
|
// using JSON, so we have to fall back to XML
|
||||||
|
QList<QVariant> tagList = parseDanbooruResult(data, "tag", &ok);
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
Q_EMIT(downloadError(QString("Unable to decode data")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto element : tagList) {
|
||||||
|
QVariantMap map = element.toMap();
|
||||||
|
DanbooruTag *tag = new DanbooruTag(map);
|
||||||
|
Q_EMIT(tagDownloaded(tag));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DanbooruService::getPool(int poolId, int page)
|
void DanbooruService::getPool(int poolId, int page)
|
||||||
|
@ -164,8 +162,7 @@ void DanbooruService::getPool(int poolId, int page)
|
||||||
|
|
||||||
//qDebug() << "Final constructed pool URL" << danbooruUrl.url();
|
//qDebug() << "Final constructed pool URL" << danbooruUrl.url();
|
||||||
|
|
||||||
|
KIO::StoredTransferJob *job = KIO::storedGet(danbooruUrl, KIO::NoReload,
|
||||||
KIO::StoredTransferJob* job = KIO::storedGet(danbooruUrl, KIO::NoReload,
|
|
||||||
KIO::HideProgressInfo);
|
KIO::HideProgressInfo);
|
||||||
|
|
||||||
//HACK: Most Danbooru implementations don't provide valid data on
|
//HACK: Most Danbooru implementations don't provide valid data on
|
||||||
|
@ -194,21 +191,21 @@ void DanbooruService::getPoolList(int page)
|
||||||
|
|
||||||
//qDebug() << "Final constructed pool list URL" << danbooruUrl.url();
|
//qDebug() << "Final constructed pool list URL" << danbooruUrl.url();
|
||||||
|
|
||||||
KIO::StoredTransferJob* job = KIO::storedGet(danbooruUrl, KIO::NoReload,
|
KIO::StoredTransferJob *job = KIO::storedGet(danbooruUrl, KIO::NoReload,
|
||||||
KIO::HideProgressInfo);
|
KIO::HideProgressInfo);
|
||||||
// This job can use JSON data
|
// This job can use JSON data
|
||||||
job->setProperty("needsXML", false);
|
job->setProperty("needsXML", false);
|
||||||
|
|
||||||
// connect(job, &KIO::StoredTransferJob::result, this, &DanbooruService::processPoolList);
|
// connect(job, &KIO::StoredTransferJob::result, this, &DanbooruService::processPoolList);
|
||||||
|
|
||||||
connect(job, &KIO::StoredTransferJob::result, [this] (KJob* job) {
|
connect(job, &KIO::StoredTransferJob::result, [this](KJob * job) {
|
||||||
|
|
||||||
if (job->error()) {
|
if (job->error()) {
|
||||||
Q_EMIT(downloadError(job->errorString()));
|
Q_EMIT(downloadError(job->errorString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
StoredTransferJob* jobResult = qobject_cast<StoredTransferJob*>(job);
|
StoredTransferJob *jobResult = qobject_cast<StoredTransferJob *>(job);
|
||||||
QByteArray data = jobResult->data();
|
QByteArray data = jobResult->data();
|
||||||
|
|
||||||
bool ok;
|
bool ok;
|
||||||
|
@ -222,7 +219,7 @@ void DanbooruService::getPoolList(int page)
|
||||||
for (auto element : poolList) {
|
for (auto element : poolList) {
|
||||||
QVariantMap map = element.toMap();
|
QVariantMap map = element.toMap();
|
||||||
|
|
||||||
DanbooruPool* pool = new DanbooruPool(map);
|
DanbooruPool *pool = new DanbooruPool(map);
|
||||||
Q_EMIT(poolDownloaded(pool));
|
Q_EMIT(poolDownloaded(pool));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,11 +227,11 @@ void DanbooruService::getPoolList(int page)
|
||||||
Q_EMIT(poolDownloadFinished());
|
Q_EMIT(poolDownloadFinished());
|
||||||
}
|
}
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DanbooruService::getRelatedTags(const QStringList& tags,
|
void DanbooruService::getRelatedTags(const QStringList &tags,
|
||||||
DanbooruTag::TagType tagType)
|
DanbooruTag::TagType tagType)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -265,19 +262,19 @@ void DanbooruService::getRelatedTags(const QStringList& tags,
|
||||||
|
|
||||||
//qDebug() << "Final constructed related tag URL" << danbooruUrl.url();
|
//qDebug() << "Final constructed related tag URL" << danbooruUrl.url();
|
||||||
|
|
||||||
StoredTransferJob* job = KIO::storedGet(
|
StoredTransferJob *job = KIO::storedGet(
|
||||||
danbooruUrl, KIO::NoReload,
|
danbooruUrl, KIO::NoReload,
|
||||||
KIO::HideProgressInfo
|
KIO::HideProgressInfo
|
||||||
);
|
);
|
||||||
|
|
||||||
connect(job, &StoredTransferJob::result, [this](KJob* job) {
|
connect(job, &StoredTransferJob::result, [this](KJob * job) {
|
||||||
|
|
||||||
if (job->error()) {
|
if (job->error()) {
|
||||||
Q_EMIT(downloadError(job->errorString()));
|
Q_EMIT(downloadError(job->errorString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
StoredTransferJob* jobResult = qobject_cast<StoredTransferJob*>(job);
|
StoredTransferJob *jobResult = qobject_cast<StoredTransferJob *>(job);
|
||||||
QByteArray data = jobResult->data();
|
QByteArray data = jobResult->data();
|
||||||
bool ok;
|
bool ok;
|
||||||
|
|
||||||
|
@ -314,13 +311,13 @@ void DanbooruService::getRelatedTags(const QStringList& tags,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getters / setters
|
// Getters / setters
|
||||||
|
|
||||||
void DanbooruService::setBlacklist(const QSet< QString >& blacklist)
|
void DanbooruService::setBlacklist(const QSet< QString > &blacklist)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!blacklist.isEmpty()) {
|
if (!blacklist.isEmpty()) {
|
||||||
|
@ -329,7 +326,6 @@ void DanbooruService::setBlacklist(const QSet< QString >& blacklist)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const QSet< QString > DanbooruService::blacklist() const
|
const QSet< QString > DanbooruService::blacklist() const
|
||||||
{
|
{
|
||||||
return m_blacklist;
|
return m_blacklist;
|
||||||
|
@ -384,7 +380,7 @@ const DanbooruPost::Ratings DanbooruService::maximumAllowedRating() const
|
||||||
|
|
||||||
// Slots
|
// Slots
|
||||||
|
|
||||||
void DanbooruService::processPostList(KJob* job)
|
void DanbooruService::processPostList(KJob *job)
|
||||||
{
|
{
|
||||||
|
|
||||||
// qDebug() << "Got post data OK";
|
// qDebug() << "Got post data OK";
|
||||||
|
@ -393,7 +389,7 @@ void DanbooruService::processPostList(KJob* job)
|
||||||
Q_EMIT(downloadError(job->errorString()));
|
Q_EMIT(downloadError(job->errorString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
StoredTransferJob* jobResult = qobject_cast<StoredTransferJob*>(job);
|
StoredTransferJob *jobResult = qobject_cast<StoredTransferJob *>(job);
|
||||||
|
|
||||||
if (jobResult == 0) {
|
if (jobResult == 0) {
|
||||||
Q_EMIT(downloadError(QString("Internal error")));
|
Q_EMIT(downloadError(QString("Internal error")));
|
||||||
|
@ -427,7 +423,7 @@ void DanbooruService::processPostList(KJob* job)
|
||||||
for (auto element : postList) {
|
for (auto element : postList) {
|
||||||
|
|
||||||
QVariantMap map = element.toMap();
|
QVariantMap map = element.toMap();
|
||||||
DanbooruPost* post = new DanbooruPost(map);
|
DanbooruPost *post = new DanbooruPost(map);
|
||||||
|
|
||||||
// Remove unwanted posts
|
// Remove unwanted posts
|
||||||
|
|
||||||
|
@ -453,11 +449,11 @@ void DanbooruService::processPostList(KJob* job)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
StoredTransferJob* pixmapJob = KIO::storedGet(post->thumbnailUrl(),
|
StoredTransferJob *pixmapJob = KIO::storedGet(post->thumbnailUrl(),
|
||||||
KIO::NoReload, KIO::HideProgressInfo
|
KIO::NoReload, KIO::HideProgressInfo
|
||||||
);
|
);
|
||||||
|
|
||||||
KIO::Scheduler::setJobPriority(static_cast<KIO::SimpleJob*>(job), 1);
|
KIO::Scheduler::setJobPriority(static_cast<KIO::SimpleJob *>(job), 1);
|
||||||
|
|
||||||
QVariant variant;
|
QVariant variant;
|
||||||
variant.setValue(post);
|
variant.setValue(post);
|
||||||
|
@ -467,23 +463,26 @@ void DanbooruService::processPostList(KJob* job)
|
||||||
|
|
||||||
pixmapJob->setProperty("danbooruPost", variant);
|
pixmapJob->setProperty("danbooruPost", variant);
|
||||||
|
|
||||||
connect(pixmapJob, &StoredTransferJob::result, [post, this, pix] (KJob* job) mutable {
|
connect(pixmapJob, &StoredTransferJob::result, [post, this, pix](KJob * job) mutable {
|
||||||
|
|
||||||
if (job->error()) {
|
if (job->error())
|
||||||
|
{
|
||||||
Q_EMIT(downloadError(job->errorString()));
|
Q_EMIT(downloadError(job->errorString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
StoredTransferJob* jobResult = qobject_cast<StoredTransferJob*>(job);
|
StoredTransferJob *jobResult = qobject_cast<StoredTransferJob *>(job);
|
||||||
|
|
||||||
if (!pix.loadFromData(jobResult->data())) {
|
if (!pix.loadFromData(jobResult->data()))
|
||||||
Q_EMIT(downloadError(QString("Pixmap data could not be loaded")));
|
{
|
||||||
return;
|
Q_EMIT(downloadError(QString("Pixmap data could not be loaded")));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
post->setPixmap(pix);
|
post->setPixmap(pix);
|
||||||
|
|
||||||
if (m_cache) {
|
if (m_cache)
|
||||||
|
{
|
||||||
//qDebug() << "Inserting item in cache";
|
//qDebug() << "Inserting item in cache";
|
||||||
m_cache->insertPixmap(post->thumbnailUrl().url(), pix);
|
m_cache->insertPixmap(post->thumbnailUrl().url(), pix);
|
||||||
}
|
}
|
||||||
|
@ -493,7 +492,8 @@ void DanbooruService::processPostList(KJob* job)
|
||||||
//qDebug() << "Current posts remaining" << m_currentPosts;
|
//qDebug() << "Current posts remaining" << m_currentPosts;
|
||||||
Q_EMIT(postDownloaded(post));
|
Q_EMIT(postDownloaded(post));
|
||||||
|
|
||||||
if (m_postsToFetch == 0) {
|
if (m_postsToFetch == 0)
|
||||||
|
{
|
||||||
qDebug() << "Post download finished";
|
qDebug() << "Post download finished";
|
||||||
Q_EMIT(postDownloadFinished());
|
Q_EMIT(postDownloadFinished());
|
||||||
}
|
}
|
||||||
|
@ -504,30 +504,26 @@ void DanbooruService::processPostList(KJob* job)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DanbooruService::processTagList(KJob* job)
|
void DanbooruService::processTagList(KJob *job)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DanbooruService::processRelatedTagList(KJob *job)
|
||||||
void DanbooruService::processRelatedTagList(KJob* job)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DanbooruService::processPoolList(KJob* job)
|
void DanbooruService::processPoolList(KJob *job)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
if (job->error()) {
|
if (job->error()) {
|
||||||
Q_EMIT(downloadError(job->errorString()));
|
Q_EMIT(downloadError(job->errorString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
StoredTransferJob* jobResult = qobject_cast<StoredTransferJob*>(job);
|
StoredTransferJob *jobResult = qobject_cast<StoredTransferJob *>(job);
|
||||||
|
|
||||||
if (jobResult == 0) {
|
if (jobResult == 0) {
|
||||||
Q_EMIT(downloadError(QString("Internal error")));
|
Q_EMIT(downloadError(QString("Internal error")));
|
||||||
|
@ -549,7 +545,7 @@ void DanbooruService::processPoolList(KJob* job)
|
||||||
for (auto element : poolList) {
|
for (auto element : poolList) {
|
||||||
QVariantMap map = element.toMap();
|
QVariantMap map = element.toMap();
|
||||||
|
|
||||||
DanbooruPool* pool = new DanbooruPool(map);
|
DanbooruPool *pool = new DanbooruPool(map);
|
||||||
Q_EMIT(poolDownloaded(pool));
|
Q_EMIT(poolDownloaded(pool));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,12 +554,12 @@ void DanbooruService::processPoolList(KJob* job)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DanbooruService::downloadAllTags(KJob* job)
|
void DanbooruService::downloadAllTags(KJob *job)
|
||||||
{
|
{
|
||||||
Q_UNUSED(job)
|
Q_UNUSED(job)
|
||||||
}
|
}
|
||||||
|
|
||||||
void DanbooruService::downloadThumbnail(KJob* job)
|
void DanbooruService::downloadThumbnail(KJob *job)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (job->error()) {
|
if (job->error()) {
|
||||||
|
@ -572,11 +568,11 @@ void DanbooruService::downloadThumbnail(KJob* job)
|
||||||
|
|
||||||
QVariant postData = job->property("danbooruPost");
|
QVariant postData = job->property("danbooruPost");
|
||||||
|
|
||||||
DanbooruPost* post = postData.value<DanbooruPost*>();
|
DanbooruPost *post = postData.value<DanbooruPost *>();
|
||||||
QPixmap pix;
|
QPixmap pix;
|
||||||
// QPixmap* pix = new QPixmap();
|
// QPixmap* pix = new QPixmap();
|
||||||
|
|
||||||
StoredTransferJob* jobResult = qobject_cast<StoredTransferJob*>(job);
|
StoredTransferJob *jobResult = qobject_cast<StoredTransferJob *>(job);
|
||||||
|
|
||||||
if (jobResult == 0) {
|
if (jobResult == 0) {
|
||||||
Q_EMIT(downloadError(QString("Internal error")));
|
Q_EMIT(downloadError(QString("Internal error")));
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#ifndef DANBOORUSERVICE_H
|
#ifndef DANBOORUSERVICE_H
|
||||||
#define DANBOORUSERVICE_H
|
#define DANBOORUSERVICE_H
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Classes to interact with Danbooru boards
|
* @brief Classes to interact with Danbooru boards
|
||||||
* @file danbooruservice.h
|
* @file danbooruservice.h
|
||||||
|
@ -56,214 +55,214 @@ class KJob;
|
||||||
|
|
||||||
using Danbooru::DanbooruTag;
|
using Danbooru::DanbooruTag;
|
||||||
|
|
||||||
namespace Danbooru {
|
namespace Danbooru
|
||||||
|
{
|
||||||
|
|
||||||
class DanbooruPool;
|
class DanbooruPool;
|
||||||
|
|
||||||
using KIO::StoredTransferJob;
|
using KIO::StoredTransferJob;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A class which provides a wrapper around Danbooru's RESTful API.
|
* @brief A class which provides a wrapper around Danbooru's RESTful API.
|
||||||
*
|
*
|
||||||
* This class provides access to Danbooru-based image boards
|
* This class provides access to Danbooru-based image boards
|
||||||
* by making the appropriate RESTful calls to the service and then
|
* by making the appropriate RESTful calls to the service and then
|
||||||
* retrieving and parsing the reuslts.
|
* retrieving and parsing the reuslts.
|
||||||
*
|
*
|
||||||
* @author Luca Beltrame (lbeltrame@kde.org)
|
* @author Luca Beltrame (lbeltrame@kde.org)
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
class DanbooruService : public QObject
|
class DanbooruService : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// URL fragments
|
// URL fragments
|
||||||
|
|
||||||
static const QString POST_URL;
|
static const QString POST_URL;
|
||||||
static const QString TAG_URL;
|
static const QString TAG_URL;
|
||||||
static const QString POOL_URL;
|
static const QString POOL_URL;
|
||||||
static const QString ARTIST_URL;
|
static const QString ARTIST_URL;
|
||||||
static const QString POOL_DATA_URL;
|
static const QString POOL_DATA_URL;
|
||||||
static const QString RELATED_TAG_URL;
|
static const QString RELATED_TAG_URL;
|
||||||
|
|
||||||
// member variables
|
// member variables
|
||||||
|
|
||||||
QUrl m_url;
|
QUrl m_url;
|
||||||
QString m_username;
|
QString m_username;
|
||||||
QString m_password;
|
QString m_password;
|
||||||
QSet<QString> m_blacklist;
|
QSet<QString> m_blacklist;
|
||||||
DanbooruPost::Ratings m_maxRating;
|
DanbooruPost::Ratings m_maxRating;
|
||||||
|
|
||||||
unsigned int m_postsToFetch; // To tell when to quit
|
unsigned int m_postsToFetch; // To tell when to quit
|
||||||
|
|
||||||
KImageCache* m_cache; // Pixmap cache
|
KImageCache *m_cache; // Pixmap cache
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Construct a default instance of the service.
|
* @brief Construct a default instance of the service.
|
||||||
*
|
*
|
||||||
* @param boardUrl The URL to connect to.
|
* @param boardUrl The URL to connect to.
|
||||||
* @param username Username to use (optional)
|
* @param username Username to use (optional)
|
||||||
* @param password Password to use (optional)
|
* @param password Password to use (optional)
|
||||||
* @param cache A pointer to a KImageCache instance to enable caching
|
* @param cache A pointer to a KImageCache instance to enable caching
|
||||||
* of downloaded pixmaps.
|
* of downloaded pixmaps.
|
||||||
* @param parent The parent QObject
|
* @param parent The parent QObject
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
DanbooruService(QUrl& boardUrl, QString username = QString(),
|
DanbooruService(QUrl &boardUrl, QString username = QString(),
|
||||||
QString password = QString(), KImageCache* cache = 0,
|
QString password = QString(), KImageCache *cache = 0,
|
||||||
QObject* parent = 0);
|
QObject *parent = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default destructor.
|
* Default destructor.
|
||||||
**/
|
**/
|
||||||
~DanbooruService();
|
~DanbooruService();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*@brief Get posts from a the board.
|
*@brief Get posts from a the board.
|
||||||
*
|
*
|
||||||
* @param page The page containing posts (default: 1)
|
* @param page The page containing posts (default: 1)
|
||||||
* @param tags The specific tags to query for (default: all tags)
|
* @param tags The specific tags to query for (default: all tags)
|
||||||
* @param limit The number of posts to fetch (maximum 100)
|
* @param limit The number of posts to fetch (maximum 100)
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
void getPostList(int page=1, QStringList tags=QStringList(),
|
void getPostList(int page = 1, QStringList tags = QStringList(),
|
||||||
int limit=100);
|
int limit = 100);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get a list of pools from the board.
|
* @brief Get a list of pools from the board.
|
||||||
*
|
*
|
||||||
* @param page The page to get pools from (default: 1)
|
* @param page The page to get pools from (default: 1)
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
void getPoolList(int page = 1);
|
void getPoolList(int page = 1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the posts associated with a specific pool ID.
|
* @brief Get the posts associated with a specific pool ID.
|
||||||
*
|
*
|
||||||
* @param poolId The ID of the pool to fetch posts from.
|
* @param poolId The ID of the pool to fetch posts from.
|
||||||
* @param page The page of the pool posts (if > 100)
|
* @param page The page of the pool posts (if > 100)
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
void getPool(int poolId, int page=1);
|
void getPool(int poolId, int page = 1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get a list of tags from the board
|
* @brief Get a list of tags from the board
|
||||||
*
|
*
|
||||||
* If name is supplied, a list of tags including the exact name of the
|
* If name is supplied, a list of tags including the exact name of the
|
||||||
* tag is fetched from Danbooru, otherwise the most recent tags are
|
* tag is fetched from Danbooru, otherwise the most recent tags are
|
||||||
* retrieved.
|
* retrieved.
|
||||||
*
|
*
|
||||||
* The tagDownloaded signal is emitted every time a tag has been
|
* The tagDownloaded signal is emitted every time a tag has been
|
||||||
* retrieved.
|
* retrieved.
|
||||||
*
|
*
|
||||||
* @param limit The number of tags to get.
|
* @param limit The number of tags to get.
|
||||||
* @param name The name of the tag to retrieve, or an empty string
|
* @param name The name of the tag to retrieve, or an empty string
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
void getTagList(int limit=10, QString name="");
|
void getTagList(int limit = 10, QString name = "");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get tags related to a specific, user supplied list.
|
* @brief Get tags related to a specific, user supplied list.
|
||||||
*
|
*
|
||||||
* @param tags The tags to query for related terms
|
* @param tags The tags to query for related terms
|
||||||
* @param tagType The type of tag to query for
|
* @param tagType The type of tag to query for
|
||||||
**/
|
**/
|
||||||
void getRelatedTags(const QStringList& tags, DanbooruTag::TagType tagType = DanbooruTag::General);
|
void getRelatedTags(const QStringList &tags, DanbooruTag::TagType tagType = DanbooruTag::General);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The currently allowed ratings when downloading posts.
|
* @return The currently allowed ratings when downloading posts.
|
||||||
**/
|
**/
|
||||||
const QStringList allowedRatings() const;
|
const QStringList allowedRatings() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The maximum allowed rating for a post.
|
* @return The maximum allowed rating for a post.
|
||||||
**/
|
**/
|
||||||
const DanbooruPost::Ratings maximumAllowedRating() const;
|
const DanbooruPost::Ratings maximumAllowedRating() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The currently blacklisted tags.
|
* @return The currently blacklisted tags.
|
||||||
**/
|
**/
|
||||||
const QSet<QString> blacklist() const;
|
const QSet<QString> blacklist() const;
|
||||||
|
|
||||||
void setBlacklist(const QSet<QString>& blacklist);
|
void setBlacklist(const QSet<QString> &blacklist);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the maximum allowed rating for the board.
|
* @brief Set the maximum allowed rating for the board.
|
||||||
*
|
*
|
||||||
* Posts whose rating is higher than the maximuk allowed will not be
|
* Posts whose rating is higher than the maximuk allowed will not be
|
||||||
* downloaded.
|
* downloaded.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
void setMaximumAllowedRating(DanbooruPost::Rating rating);
|
void setMaximumAllowedRating(DanbooruPost::Rating rating);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the tag blacklist.
|
* @brief Set the tag blacklist.
|
||||||
*
|
*
|
||||||
* If a tag is in the blacklist, posts tagged with it will not be downloaded.
|
* If a tag is in the blacklist, posts tagged with it will not be downloaded.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
void setBlackList(QStringList blacklist);
|
void setBlackList(QStringList blacklist);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void processPostList(KJob* job);
|
void processPostList(KJob *job);
|
||||||
void processPoolList(KJob* job);
|
void processPoolList(KJob *job);
|
||||||
void processTagList(KJob* job);
|
void processTagList(KJob *job);
|
||||||
void processRelatedTagList(KJob* job);
|
void processRelatedTagList(KJob *job);
|
||||||
void downloadThumbnail(KJob* job);
|
void downloadThumbnail(KJob *job);
|
||||||
void downloadAllTags(KJob* job);
|
void downloadAllTags(KJob *job);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted when there are no more posts to download.
|
* Emitted when there are no more posts to download.
|
||||||
*
|
*
|
||||||
* Connect to this signal to know when downloading is complete.
|
* Connect to this signal to know when downloading is complete.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
void postDownloadFinished();
|
void postDownloadFinished();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted when there are no more pools to download.
|
* Emitted when there are no more pools to download.
|
||||||
**/
|
**/
|
||||||
void poolDownloadFinished();
|
void poolDownloadFinished();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when a download error occurred.
|
||||||
|
*
|
||||||
|
* The parameter contains the error string.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void downloadError(QString error);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted when a download error occurred.
|
* Emitted when a post has been downloaded.
|
||||||
*
|
*
|
||||||
* The parameter contains the error string.
|
* The parameter contains a pointer to the post that has been
|
||||||
*
|
* downloaded.
|
||||||
**/
|
**/
|
||||||
void downloadError(QString error);
|
void postDownloaded(Danbooru::DanbooruPost *post);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted when a post has been downloaded.
|
* Emitted when a pool has been downloaded.
|
||||||
*
|
*
|
||||||
* The parameter contains a pointer to the post that has been
|
* The parameter contains a pointer to the pool that has been
|
||||||
* downloaded.
|
* downloaded.
|
||||||
**/
|
**/
|
||||||
void postDownloaded(Danbooru::DanbooruPost* post);
|
void poolDownloaded(Danbooru::DanbooruPool *pool);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted when a pool has been downloaded.
|
* Emitted when a tag has been downloaded.
|
||||||
*
|
*
|
||||||
* The parameter contains a pointer to the pool that has been
|
* The parameter contains a pointer to the tag that has been
|
||||||
* downloaded.
|
* downloaded.
|
||||||
**/
|
**/
|
||||||
void poolDownloaded(Danbooru::DanbooruPool* pool);
|
void tagDownloaded(Danbooru::DanbooruTag *tag);
|
||||||
|
|
||||||
/**
|
};
|
||||||
* Emitted when a tag has been downloaded.
|
|
||||||
*
|
|
||||||
* The parameter contains a pointer to the tag that has been
|
|
||||||
* downloaded.
|
|
||||||
**/
|
|
||||||
void tagDownloaded(Danbooru::DanbooruTag* tag);
|
|
||||||
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
#endif // DANBOORUSERVICE_H
|
#endif // DANBOORUSERVICE_H
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
namespace Danbooru
|
namespace Danbooru
|
||||||
{
|
{
|
||||||
|
|
||||||
DanbooruTag::DanbooruTag(const QVariantMap& postData, QObject* parent):
|
DanbooruTag::DanbooruTag(const QVariantMap &postData, QObject *parent):
|
||||||
QObject(parent)
|
QObject(parent)
|
||||||
{
|
{
|
||||||
m_id = postData.value("id").toInt();
|
m_id = postData.value("id").toInt();
|
||||||
|
@ -82,5 +82,4 @@ Danbooru::DanbooruTag::TagType DanbooruTag::type() const
|
||||||
return m_tagType;
|
return m_tagType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}; // namespace Danbooru
|
}; // namespace Danbooru
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef DANBOORUTAG_H
|
#ifndef DANBOORUTAG_H
|
||||||
#define DANBOORUTAG_H
|
#define DANBOORUTAG_H
|
||||||
|
|
||||||
|
@ -29,54 +28,55 @@
|
||||||
|
|
||||||
#include "danbooru.h"
|
#include "danbooru.h"
|
||||||
|
|
||||||
namespace Danbooru {
|
namespace Danbooru
|
||||||
|
{
|
||||||
|
|
||||||
class DanbooruTag : public QObject
|
class DanbooruTag : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Types of tags
|
* @brief Types of tags
|
||||||
*
|
*
|
||||||
* A Danbooru tag is not simply a string, but carries some (limited)
|
* A Danbooru tag is not simply a string, but carries some (limited)
|
||||||
* semantic information. In particular, tags are organized in what they
|
* semantic information. In particular, tags are organized in what they
|
||||||
* refer to, either something related to the image itself, or to the
|
* refer to, either something related to the image itself, or to the
|
||||||
* artist that drew it, or the copyrights associated to the image, or even
|
* artist that drew it, or the copyrights associated to the image, or even
|
||||||
* the characters that are represented in it.
|
* the characters that are represented in it.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
||||||
enum TagType {
|
enum TagType {
|
||||||
General = 1, /**< Generic tags **/
|
General = 1, /**< Generic tags **/
|
||||||
Artist = 2, /**< Tags related to artists **/
|
Artist = 2, /**< Tags related to artists **/
|
||||||
Copyright = 4, /**<Tags related to copyrights **/
|
Copyright = 4, /**<Tags related to copyrights **/
|
||||||
Character= 8, /**<Tags related to characters **/
|
Character = 8, /**<Tags related to characters **/
|
||||||
Unknown = 16 /**< Unknown tags **/
|
Unknown = 16 /**< Unknown tags **/
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
|
||||||
int m_id;
|
|
||||||
int m_count;
|
|
||||||
QString m_name;
|
|
||||||
bool m_ambiguous;
|
|
||||||
TagType m_tagType;
|
|
||||||
|
|
||||||
public:
|
private:
|
||||||
DanbooruTag(const QVariantMap& postData, QObject* parent=0);
|
int m_id;
|
||||||
int id() const;
|
int m_count;
|
||||||
int count() const;
|
QString m_name;
|
||||||
const QString name() const;
|
bool m_ambiguous;
|
||||||
bool ambiguous() const;
|
TagType m_tagType;
|
||||||
TagType type() const;
|
|
||||||
|
|
||||||
};
|
public:
|
||||||
|
DanbooruTag(const QVariantMap &postData, QObject *parent = 0);
|
||||||
|
int id() const;
|
||||||
|
int count() const;
|
||||||
|
const QString name() const;
|
||||||
|
bool ambiguous() const;
|
||||||
|
TagType type() const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_FLAGS(TagTypes, DanbooruTag::TagType)
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(TagTypes)
|
||||||
|
|
||||||
Q_DECLARE_FLAGS(TagTypes, DanbooruTag::TagType)
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(TagTypes)
|
|
||||||
|
|
||||||
}; // namespace Danbooru
|
}; // namespace Danbooru
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(Danbooru::DanbooruTag*)
|
Q_DECLARE_METATYPE(Danbooru::DanbooruTag *)
|
||||||
|
|
||||||
#endif // DANBOORUTAG_H
|
#endif // DANBOORUTAG_H
|
||||||
|
|
|
@ -34,156 +34,157 @@
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
namespace Danbooru {
|
namespace Danbooru
|
||||||
|
{
|
||||||
|
|
||||||
QUrl requestUrl(QUrl& url, const QString& path,
|
QUrl requestUrl(QUrl &url, const QString &path,
|
||||||
const QString& username, const QString& password,
|
const QString &username, const QString &password,
|
||||||
const dictMap& parameters, const QStringList& tags)
|
const dictMap ¶meters, const QStringList &tags)
|
||||||
{
|
{
|
||||||
|
|
||||||
QUrl danbooruUrl = QUrl(url);
|
QUrl danbooruUrl = QUrl(url);
|
||||||
danbooruUrl = danbooruUrl.adjusted(QUrl::StripTrailingSlash);
|
danbooruUrl = danbooruUrl.adjusted(QUrl::StripTrailingSlash);
|
||||||
danbooruUrl.setPath(danbooruUrl.path() + '/' + path);
|
danbooruUrl.setPath(danbooruUrl.path() + '/' + path);
|
||||||
|
|
||||||
// If we have parameters, add them
|
// If we have parameters, add them
|
||||||
|
|
||||||
if (!parameters.isEmpty()) {
|
if (!parameters.isEmpty()) {
|
||||||
|
|
||||||
for (auto key: parameters.keys()) {
|
|
||||||
danbooruUrl.addQueryItem(key, parameters.value(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
for (auto key : parameters.keys()) {
|
||||||
|
danbooruUrl.addQueryItem(key, parameters.value(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, let's add tags should we have them
|
|
||||||
|
|
||||||
if (!tags.isEmpty()) {
|
|
||||||
QByteArray encoded_tags = QUrl::toPercentEncoding(tags.join(" "));
|
|
||||||
danbooruUrl.addEncodedQueryItem("tags", encoded_tags);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!username.isEmpty() && !password.isEmpty()) {
|
|
||||||
danbooruUrl.setUserName(username);
|
|
||||||
danbooruUrl.setPassword(password);
|
|
||||||
}
|
|
||||||
|
|
||||||
return danbooruUrl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl requestUrl(QUrl& url, const QString& path, const QString& username,
|
// Now, let's add tags should we have them
|
||||||
const QString& password, const dictMap& parameters)
|
|
||||||
{
|
|
||||||
|
|
||||||
QUrl danbooruUrl = QUrl(url);
|
if (!tags.isEmpty()) {
|
||||||
danbooruUrl = danbooruUrl.adjusted(QUrl::StripTrailingSlash);
|
QByteArray encoded_tags = QUrl::toPercentEncoding(tags.join(" "));
|
||||||
danbooruUrl.setPath(danbooruUrl.path() + '/' + path);
|
danbooruUrl.addEncodedQueryItem("tags", encoded_tags);
|
||||||
|
|
||||||
// If we have parameters, add them
|
|
||||||
|
|
||||||
if (!parameters.isEmpty()) {
|
|
||||||
|
|
||||||
for (auto key: parameters.keys()) {
|
|
||||||
danbooruUrl.addQueryItem(key, parameters.value(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!username.isEmpty() && !password.isEmpty()) {
|
|
||||||
danbooruUrl.setUserName(username);
|
|
||||||
danbooruUrl.setPassword(password);
|
|
||||||
}
|
|
||||||
|
|
||||||
return danbooruUrl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl requestUrl(QUrl& url, const QString& path, const QString& username,
|
if (!username.isEmpty() && !password.isEmpty()) {
|
||||||
const QString& password)
|
danbooruUrl.setUserName(username);
|
||||||
{
|
danbooruUrl.setPassword(password);
|
||||||
QUrl danbooruUrl = QUrl(url);
|
|
||||||
danbooruUrl = danbooruUrl.adjusted(QUrl::StripTrailingSlash);
|
|
||||||
danbooruUrl.setPath(danbooruUrl.path() + '/' + path);
|
|
||||||
|
|
||||||
if (!username.isEmpty() && !password.isEmpty()) {
|
|
||||||
danbooruUrl.setUserName(username);
|
|
||||||
danbooruUrl.setPassword(password);
|
|
||||||
}
|
|
||||||
|
|
||||||
return danbooruUrl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QList< QVariant > parseDanbooruResult(QByteArray data, QString elementName,
|
return danbooruUrl;
|
||||||
bool* result)
|
}
|
||||||
{
|
|
||||||
|
|
||||||
QXmlStreamReader reader;
|
QUrl requestUrl(QUrl &url, const QString &path, const QString &username,
|
||||||
reader.addData(data);
|
const QString &password, const dictMap ¶meters)
|
||||||
|
{
|
||||||
|
|
||||||
QList<QVariant> postData;
|
QUrl danbooruUrl = QUrl(url);
|
||||||
|
danbooruUrl = danbooruUrl.adjusted(QUrl::StripTrailingSlash);
|
||||||
|
danbooruUrl.setPath(danbooruUrl.path() + '/' + path);
|
||||||
|
|
||||||
while(!reader.atEnd() && !reader.hasError()) {
|
// If we have parameters, add them
|
||||||
|
|
||||||
QXmlStreamReader::TokenType token = reader.readNext();
|
if (!parameters.isEmpty()) {
|
||||||
|
|
||||||
if (token == QXmlStreamReader::StartDocument) {
|
for (auto key : parameters.keys()) {
|
||||||
continue;
|
danbooruUrl.addQueryItem(key, parameters.value(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(token == QXmlStreamReader::StartElement &&
|
}
|
||||||
reader.name() == elementName) {
|
|
||||||
|
|
||||||
QVariantMap values;
|
if (!username.isEmpty() && !password.isEmpty()) {
|
||||||
|
danbooruUrl.setUserName(username);
|
||||||
|
danbooruUrl.setPassword(password);
|
||||||
|
}
|
||||||
|
|
||||||
QXmlStreamAttributes attributes = reader.attributes();
|
return danbooruUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl requestUrl(QUrl &url, const QString &path, const QString &username,
|
||||||
|
const QString &password)
|
||||||
|
{
|
||||||
|
QUrl danbooruUrl = QUrl(url);
|
||||||
|
danbooruUrl = danbooruUrl.adjusted(QUrl::StripTrailingSlash);
|
||||||
|
danbooruUrl.setPath(danbooruUrl.path() + '/' + path);
|
||||||
|
|
||||||
|
if (!username.isEmpty() && !password.isEmpty()) {
|
||||||
|
danbooruUrl.setUserName(username);
|
||||||
|
danbooruUrl.setPassword(password);
|
||||||
|
}
|
||||||
|
|
||||||
|
return danbooruUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList< QVariant > parseDanbooruResult(QByteArray data, QString elementName,
|
||||||
|
bool *result)
|
||||||
|
{
|
||||||
|
|
||||||
|
QXmlStreamReader reader;
|
||||||
|
reader.addData(data);
|
||||||
|
|
||||||
|
QList<QVariant> postData;
|
||||||
|
|
||||||
|
while (!reader.atEnd() && !reader.hasError()) {
|
||||||
|
|
||||||
|
QXmlStreamReader::TokenType token = reader.readNext();
|
||||||
|
|
||||||
|
if (token == QXmlStreamReader::StartDocument) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token == QXmlStreamReader::StartElement &&
|
||||||
|
reader.name() == elementName) {
|
||||||
|
|
||||||
|
QVariantMap values;
|
||||||
|
|
||||||
|
QXmlStreamAttributes attributes = reader.attributes();
|
||||||
|
|
||||||
// qDebug() << attributes;
|
// qDebug() << attributes;
|
||||||
|
|
||||||
for (auto attribute: attributes) {
|
for (auto attribute : attributes) {
|
||||||
values.insert(attribute.name().toString(),
|
values.insert(attribute.name().toString(),
|
||||||
attribute.value().toString());
|
attribute.value().toString());
|
||||||
}
|
|
||||||
|
|
||||||
if (values.isEmpty()) {
|
|
||||||
*result = false;
|
|
||||||
qWarning() << "No results found when parsing XML";
|
|
||||||
return QList<QVariant>();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant converted = QVariant(values);
|
|
||||||
|
|
||||||
postData.append(converted);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (values.isEmpty()) {
|
||||||
|
*result = false;
|
||||||
|
qWarning() << "No results found when parsing XML";
|
||||||
|
return QList<QVariant>();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant converted = QVariant(values);
|
||||||
|
|
||||||
|
postData.append(converted);
|
||||||
}
|
}
|
||||||
*result = true;
|
}
|
||||||
return postData;
|
*result = true;
|
||||||
|
return postData;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant parseDanbooruResult(QByteArray data, bool *result)
|
||||||
|
{
|
||||||
|
|
||||||
|
QJsonDocument parsed = QJsonDocument::fromJson(data);
|
||||||
|
|
||||||
|
if (parsed.isNull()) {
|
||||||
|
return QList<QVariant>();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant parseDanbooruResult(QByteArray data, bool* result)
|
QVariant postData = parsed.toVariant();
|
||||||
{
|
|
||||||
|
|
||||||
QJsonDocument parsed = QJsonDocument::fromJson(data);
|
*result = true;
|
||||||
|
|
||||||
if (parsed.isNull()) {
|
return postData;
|
||||||
return QList<QVariant>();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
QVariant postData = parsed.toVariant();
|
bool isPostBlacklisted(DanbooruPost *post, QSet<QString> blacklist, DanbooruPost::Ratings maxRating)
|
||||||
|
{
|
||||||
*result = true;
|
|
||||||
|
|
||||||
return postData;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool isPostBlacklisted(DanbooruPost *post, QSet<QString> blacklist, DanbooruPost::Ratings maxRating ) {
|
|
||||||
|
|
||||||
if (post->rating() > maxRating) {
|
if (post->rating() > maxRating) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto tag: post->tags()) {
|
for (auto tag : post->tags()) {
|
||||||
|
|
||||||
if (blacklist.contains(tag)) {
|
if (blacklist.contains(tag)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,90 +39,88 @@
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
||||||
namespace Danbooru {
|
namespace Danbooru
|
||||||
|
{
|
||||||
|
|
||||||
typedef QMap<QString,QString> dictMap;
|
typedef QMap<QString, QString> dictMap;
|
||||||
|
|
||||||
/** @brief Generate a request URL for a Danbooru board.
|
/** @brief Generate a request URL for a Danbooru board.
|
||||||
*
|
*
|
||||||
* Given an URL and an API path, this function builds a
|
* Given an URL and an API path, this function builds a
|
||||||
* proper URL which is used for the specific API operation.
|
* proper URL which is used for the specific API operation.
|
||||||
* The processing follows the "normal" way of encoding URLs.
|
* The processing follows the "normal" way of encoding URLs.
|
||||||
*
|
*
|
||||||
* @param url The board URL.
|
* @param url The board URL.
|
||||||
* @param path The API path of the call to use
|
* @param path The API path of the call to use
|
||||||
* @param username The username to supply (optional)
|
* @param username The username to supply (optional)
|
||||||
* @param password The password to use (optional)
|
* @param password The password to use (optional)
|
||||||
* @param parameters A map of key,values representing the parameters
|
* @param parameters A map of key,values representing the parameters
|
||||||
* to use.
|
* to use.
|
||||||
* @param tags The tags to supply (optional).
|
* @param tags The tags to supply (optional).
|
||||||
*
|
*
|
||||||
* @return A constructed URL to be used for a Danbooru API call.
|
* @return A constructed URL to be used for a Danbooru API call.
|
||||||
* @author Luca Beltrame (lbeltrame@kde.org)
|
* @author Luca Beltrame (lbeltrame@kde.org)
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
QUrl requestUrl(QUrl& url, const QString& path, const QString& username,
|
QUrl requestUrl(QUrl &url, const QString &path, const QString &username,
|
||||||
const QString& password, const dictMap& parameters,
|
const QString &password, const dictMap ¶meters,
|
||||||
const QStringList& tags);
|
const QStringList &tags);
|
||||||
|
|
||||||
|
/** @brief Generate a request URL for a Danbooru board.
|
||||||
|
*
|
||||||
|
* This is an overloaded function provided for convenience.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param url The board URL.
|
||||||
|
* @param path The API path of the call to use
|
||||||
|
* @param username The username to supply (optional)
|
||||||
|
* @param password The password to use (optional)
|
||||||
|
* @param parameters A map of key,values representing the parameters
|
||||||
|
* to use.
|
||||||
|
*
|
||||||
|
* @return A constructed URL to be used for a Danbooru API call.
|
||||||
|
* @author Luca Beltrame (lbeltrame@kde.org)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
QUrl requestUrl(QUrl &url, const QString &path, const QString &username,
|
||||||
|
const QString &password, const dictMap ¶meters);
|
||||||
|
|
||||||
/** @brief Generate a request URL for a Danbooru board.
|
/** @brief Generate a request URL for a Danbooru board.
|
||||||
*
|
*
|
||||||
* This is an overloaded function provided for convenience.
|
* This is an overloaded function provided for convenience.
|
||||||
*
|
*
|
||||||
*
|
* @param url The board URL.
|
||||||
* @param url The board URL.
|
* @param path The API path of the call to use
|
||||||
* @param path The API path of the call to use
|
* @param username The username to supply (optional)
|
||||||
* @param username The username to supply (optional)
|
* @param password The password to use (optional)
|
||||||
* @param password The password to use (optional)
|
*
|
||||||
* @param parameters A map of key,values representing the parameters
|
* @return A constructed URL to be used for a Danbooru API call.
|
||||||
* to use.
|
* @author Luca Beltrame (lbeltrame@kde.org)
|
||||||
*
|
*
|
||||||
* @return A constructed URL to be used for a Danbooru API call.
|
*
|
||||||
* @author Luca Beltrame (lbeltrame@kde.org)
|
**/
|
||||||
*
|
QUrl requestUrl(QUrl &url, const QString &path, const QString &username,
|
||||||
*
|
const QString &password);
|
||||||
**/
|
|
||||||
QUrl requestUrl(QUrl& url, const QString& path, const QString& username,
|
|
||||||
const QString& password, const dictMap& parameters);
|
|
||||||
|
|
||||||
|
QList<QVariant> parseDanbooruResult(QByteArray data, QString xlmElement,
|
||||||
|
bool *result);
|
||||||
|
QVariant parseDanbooruResult(QByteArray data, bool *result);
|
||||||
|
|
||||||
/** @brief Generate a request URL for a Danbooru board.
|
/**
|
||||||
*
|
* @brief Check if a post can be allowed.
|
||||||
* This is an overloaded function provided for convenience.
|
*
|
||||||
*
|
* This convenience function checks if a DanbooruPost is not allowed, either because it
|
||||||
* @param url The board URL.
|
* contains blacklisted tags, or because it has a higher rating than allowed.
|
||||||
* @param path The API path of the call to use
|
*
|
||||||
* @param username The username to supply (optional)
|
* @param post A DanbooruPost pointer.
|
||||||
* @param password The password to use (optional)
|
* @param blacklist A QSet containing unwanted tag names as QStrings.
|
||||||
*
|
* @param maxRating The maximum allowed rating expressed as a DanbooruPost::Ratings flag.
|
||||||
* @return A constructed URL to be used for a Danbooru API call.
|
* @return true if the post is unwanted, false otherwise.
|
||||||
* @author Luca Beltrame (lbeltrame@kde.org)
|
* @author Luca Beltrame (lbeltrame@kde.org)
|
||||||
*
|
*/
|
||||||
*
|
bool isPostBlacklisted(DanbooruPost *post, QSet<QString> blacklist, DanbooruPost::Ratings maxRating);
|
||||||
**/
|
|
||||||
QUrl requestUrl(QUrl& url, const QString& path, const QString& username,
|
|
||||||
const QString& password);
|
|
||||||
|
|
||||||
|
|
||||||
QList<QVariant> parseDanbooruResult(QByteArray data, QString xlmElement,
|
|
||||||
bool* result);
|
|
||||||
QVariant parseDanbooruResult(QByteArray data, bool* result);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if a post can be allowed.
|
|
||||||
*
|
|
||||||
* This convenience function checks if a DanbooruPost is not allowed, either because it
|
|
||||||
* contains blacklisted tags, or because it has a higher rating than allowed.
|
|
||||||
*
|
|
||||||
* @param post A DanbooruPost pointer.
|
|
||||||
* @param blacklist A QSet containing unwanted tag names as QStrings.
|
|
||||||
* @param maxRating The maximum allowed rating expressed as a DanbooruPost::Ratings flag.
|
|
||||||
* @return true if the post is unwanted, false otherwise.
|
|
||||||
* @author Luca Beltrame (lbeltrame@kde.org)
|
|
||||||
*/
|
|
||||||
bool isPostBlacklisted(DanbooruPost *post, QSet<QString> blacklist, DanbooruPost::Ratings maxRating );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif // UTILS_H
|
#endif // UTILS_H
|
||||||
|
|
25
src/main.cpp
25
src/main.cpp
|
@ -36,8 +36,8 @@ static const char version[] = "%{VERSION}";
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
K4AboutData about("danbooru_client", 0, ki18n("danbooru_client"), version, ki18n(description),
|
K4AboutData about("danbooru_client", 0, ki18n("danbooru_client"), version, ki18n(description),
|
||||||
K4AboutData::License_GPL, ki18n("(C) %{CURRENT_YEAR} %{AUTHOR}"), KLocalizedString(), 0, "%{EMAIL}");
|
K4AboutData::License_GPL, ki18n("(C) %{CURRENT_YEAR} %{AUTHOR}"), KLocalizedString(), 0, "%{EMAIL}");
|
||||||
about.addAuthor( ki18n("%{AUTHOR}"), KLocalizedString(), "%{EMAIL}" );
|
about.addAuthor(ki18n("%{AUTHOR}"), KLocalizedString(), "%{EMAIL}");
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
QCommandLineParser parser;
|
QCommandLineParser parser;
|
||||||
K4AboutData::setApplicationData(aboutData);
|
K4AboutData::setApplicationData(aboutData);
|
||||||
|
@ -48,33 +48,26 @@ int main(int argc, char **argv)
|
||||||
parser.process(app);
|
parser.process(app);
|
||||||
aboutData.processCommandLine(&parser);
|
aboutData.processCommandLine(&parser);
|
||||||
|
|
||||||
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("+[URL]"), i18n( "Document to open" )));
|
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("+[URL]"), i18n("Document to open")));
|
||||||
|
|
||||||
danbooru_client *widget = new danbooru_client;
|
danbooru_client *widget = new danbooru_client;
|
||||||
|
|
||||||
// see if we are starting with session management
|
// see if we are starting with session management
|
||||||
if (app.isSessionRestored())
|
if (app.isSessionRestored()) {
|
||||||
{
|
|
||||||
RESTORE(danbooru_client);
|
RESTORE(danbooru_client);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// no session.. just start up normally
|
// no session.. just start up normally
|
||||||
if (parser.positionalArguments().count() == 0)
|
if (parser.positionalArguments().count() == 0) {
|
||||||
{
|
|
||||||
//danbooru_client *widget = new danbooru_client;
|
//danbooru_client *widget = new danbooru_client;
|
||||||
widget->show();
|
widget->show();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (; i < parser.positionalArguments().count(); i++)
|
for (; i < parser.positionalArguments().count(); i++) {
|
||||||
{
|
|
||||||
//danbooru_client *widget = new danbooru_client;
|
//danbooru_client *widget = new danbooru_client;
|
||||||
widget->show();
|
widget->show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
|
|
|
@ -30,49 +30,47 @@
|
||||||
|
|
||||||
#include <KLocale>
|
#include <KLocale>
|
||||||
|
|
||||||
namespace Danbooru {
|
namespace Danbooru
|
||||||
|
{
|
||||||
|
|
||||||
DanbooruMainWindow::DanbooruMainWindow()
|
DanbooruMainWindow::DanbooruMainWindow()
|
||||||
: KXmlGuiWindow(),
|
: KXmlGuiWindow(),
|
||||||
m_view(new DanbooruClientView(this)),
|
m_view(new DanbooruClientView(this)),
|
||||||
m_service(0),
|
m_service(0),
|
||||||
m_model(new(DanbooruPostModel(this)))
|
m_model(new(DanbooruPostModel(this)))
|
||||||
{
|
{
|
||||||
// tell the KXmlGuiWindow that this is indeed the main widget
|
// tell the KXmlGuiWindow that this is indeed the main widget
|
||||||
setCentralWidget(m_view);
|
setCentralWidget(m_view);
|
||||||
|
|
||||||
// then, setup our actions
|
// then, setup our actions
|
||||||
setupActions();
|
setupActions();
|
||||||
|
|
||||||
// add a status bar
|
// add a status bar
|
||||||
statusBar()->show();
|
statusBar()->show();
|
||||||
|
|
||||||
// a call to KXmlGuiWindow::setupGUI() populates the GUI
|
// a call to KXmlGuiWindow::setupGUI() populates the GUI
|
||||||
// with actions, using KXMLGUI.
|
// with actions, using KXMLGUI.
|
||||||
// It also applies the saved mainwindow settings, if any, and ask the
|
// It also applies the saved mainwindow settings, if any, and ask the
|
||||||
// mainwindow to automatically save settings if changed: window size,
|
// mainwindow to automatically save settings if changed: window size,
|
||||||
// toolbar position, icon size, etc.
|
// toolbar position, icon size, etc.
|
||||||
setupGUI();
|
setupGUI();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
DanbooruMainWindow::~DanbooruMainWindow()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
DanbooruMainWindow::~DanbooruMainWindow()
|
void DanbooruMainWindow::setupActions()
|
||||||
{
|
{
|
||||||
}
|
|
||||||
|
|
||||||
void DanbooruMainWindow::setupActions()
|
QAction *connectAction = new QAction(
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QAction * connectAction = new QAction(
|
|
||||||
QIcon::fromTheme(QLatin1String("document-open-remote")),
|
QIcon::fromTheme(QLatin1String("document-open-remote")),
|
||||||
i18n("Connect..."),
|
i18n("Connect..."),
|
||||||
this);
|
this);
|
||||||
|
|
||||||
QAction * fetchAction = new QAction(QIcon::fromTheme(QLatin1String("download")),
|
QAction *fetchAction = new QAction(QIcon::fromTheme(QLatin1String("download")),
|
||||||
i18n("Download"), this);
|
i18n("Download"), this);
|
||||||
|
|
||||||
connectAction->setShortcut(KStandardShortcut::open());
|
connectAction->setShortcut(KStandardShortcut::open());
|
||||||
fetchAction->setShortcut(KStandardShortcut::find());
|
fetchAction->setShortcut(KStandardShortcut::find());
|
||||||
|
@ -86,29 +84,28 @@ namespace Danbooru {
|
||||||
connect(connectAction, &QAction::triggered, this, &DanbooruMainWindow::connectToBoard);
|
connect(connectAction, &QAction::triggered, this, &DanbooruMainWindow::connectToBoard);
|
||||||
connect(fetch, SIGNAL(triggered(bool)), this, SLOT(downloadPosts()));
|
connect(fetch, SIGNAL(triggered(bool)), this, SLOT(downloadPosts()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DanbooruMainWindow::connectToBoard()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!m_view) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DanbooruMainWindow::connectToBoard()
|
}
|
||||||
{
|
|
||||||
|
|
||||||
if (!m_view) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void DanbooruMainWindow::downloadPosts()
|
||||||
|
{
|
||||||
|
if (!m_service) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DanbooruMainWindow::downloadPosts()
|
void DanbooruMainWindow::optionsPreferences()
|
||||||
{
|
{
|
||||||
if (!m_service) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DanbooruMainWindow::optionsPreferences()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Danbooru
|
} // namespace Danbooru
|
||||||
|
|
||||||
|
|
|
@ -23,55 +23,54 @@
|
||||||
#ifndef DANBOORU_CLIENT_H
|
#ifndef DANBOORU_CLIENT_H
|
||||||
#define DANBOORU_CLIENT_H
|
#define DANBOORU_CLIENT_H
|
||||||
|
|
||||||
|
|
||||||
#include <KXmlGuiWindow>
|
#include <KXmlGuiWindow>
|
||||||
|
|
||||||
namespace Danbooru {
|
namespace Danbooru
|
||||||
|
{
|
||||||
|
|
||||||
class DanbooruClientView;
|
class DanbooruClientView;
|
||||||
class DanbooruService;
|
class DanbooruService;
|
||||||
class DanbooruPostModel;
|
class DanbooruPostModel;
|
||||||
class DanbooruConnectWidget;
|
class DanbooruConnectWidget;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class serves as the main window for danbooru_client. It handles the
|
||||||
|
* menus, toolbars and status bars.
|
||||||
|
*
|
||||||
|
* @short Main window class
|
||||||
|
* @author Luca Beltrame <lbeltrame@kde.org>
|
||||||
|
* @version 0.01
|
||||||
|
*/
|
||||||
|
class DanbooruMainWindow : public KXmlGuiWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Default Constructor
|
||||||
|
*/
|
||||||
|
DanbooruMainWindow();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class serves as the main window for danbooru_client. It handles the
|
* Default Destructor
|
||||||
* menus, toolbars and status bars.
|
|
||||||
*
|
|
||||||
* @short Main window class
|
|
||||||
* @author Luca Beltrame <lbeltrame@kde.org>
|
|
||||||
* @version 0.01
|
|
||||||
*/
|
*/
|
||||||
class DanbooruMainWindow : public KXmlGuiWindow
|
virtual ~DanbooruMainWindow();
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Default Constructor
|
|
||||||
*/
|
|
||||||
DanbooruMainWindow();
|
|
||||||
|
|
||||||
/**
|
private Q_SLOTS:
|
||||||
* Default Destructor
|
void connectToBoard();
|
||||||
*/
|
void downloadPosts();
|
||||||
virtual ~DanbooruMainWindow();
|
void optionsPreferences();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private:
|
||||||
void connectToBoard();
|
void setupActions();
|
||||||
void downloadPosts();
|
void setupConnections();
|
||||||
void optionsPreferences();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupActions();
|
DanbooruClientView *m_view;
|
||||||
void setupConnections();
|
DanbooruPostModel *m_model;
|
||||||
|
DanbooruService *m_service;
|
||||||
|
DanbooruConnectWidget *m_connectWidget;
|
||||||
|
|
||||||
private:
|
};
|
||||||
DanbooruClientView *m_view;
|
|
||||||
DanbooruPostModel* m_model;
|
|
||||||
DanbooruService* m_service;
|
|
||||||
DanbooruConnectWidget* m_connectWidget;
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
} // namespace Danbooru
|
} // namespace Danbooru
|
||||||
|
|
||||||
#endif // _DANBOORU_CLIENT_H_
|
#endif // _DANBOORU_CLIENT_H_
|
||||||
|
|
|
@ -39,223 +39,221 @@
|
||||||
#include <KIconLoader>
|
#include <KIconLoader>
|
||||||
#include <KFormat>
|
#include <KFormat>
|
||||||
|
|
||||||
|
namespace Danbooru
|
||||||
|
{
|
||||||
|
|
||||||
namespace Danbooru {
|
const int DanbooruPostDelegate::MARGIN = 5;
|
||||||
|
|
||||||
const int DanbooruPostDelegate::MARGIN = 5;
|
DanbooruPostDelegate::DanbooruPostDelegate(QListView *itemView): QStyledItemDelegate(itemView),
|
||||||
|
m_itemView(itemView)
|
||||||
|
{
|
||||||
|
|
||||||
DanbooruPostDelegate::DanbooruPostDelegate(QListView* itemView):QStyledItemDelegate(itemView),
|
// Get the sizes for the buttons
|
||||||
m_itemView(itemView)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Get the sizes for the buttons
|
const int iconSize = KIconLoader::global()->currentSize(
|
||||||
|
KIconLoader::Toolbar
|
||||||
|
);
|
||||||
|
|
||||||
const int iconSize = KIconLoader::global()->currentSize(
|
const QSize sz = itemView->style()->sizeFromContents(
|
||||||
KIconLoader::Toolbar
|
QStyle::CT_ToolButton, 0,
|
||||||
);
|
QSize(iconSize, iconSize));
|
||||||
|
|
||||||
const QSize sz = itemView->style()->sizeFromContents(
|
m_buttonSize = qMax(sz.width(), sz.height());
|
||||||
QStyle::CT_ToolButton, 0,
|
|
||||||
QSize(iconSize, iconSize));
|
|
||||||
|
|
||||||
m_buttonSize = qMax(sz.width(), sz.height());
|
m_downloadButton = new QPushButton(QIcon::fromTheme("download"),
|
||||||
|
QString(), itemView);
|
||||||
|
m_viewButton = new QPushButton(QIcon::fromTheme("view-preview"), QString(),
|
||||||
|
itemView);
|
||||||
|
|
||||||
m_downloadButton = new QPushButton(QIcon::fromTheme("download"),
|
m_downloadButton->hide();
|
||||||
QString(), itemView);
|
m_viewButton->hide();
|
||||||
m_viewButton = new QPushButton(QIcon::fromTheme("view-preview"), QString(),
|
|
||||||
itemView);
|
|
||||||
|
|
||||||
|
m_downloadButton->resize(m_buttonSize, m_buttonSize);
|
||||||
|
m_viewButton->resize(m_buttonSize, m_buttonSize);
|
||||||
|
m_downloadButton->setToolTip(i18n("Download image"));
|
||||||
|
m_viewButton->setToolTip(i18n("View image"));
|
||||||
|
|
||||||
|
// Signal-slot connections
|
||||||
|
|
||||||
|
connect(m_viewButton, &QPushButton::clicked, this, &DanbooruPostDelegate::viewButtonClicked);
|
||||||
|
connect(m_downloadButton, &QPushButton::clicked, this, &DanbooruPostDelegate::downloadButtonClicked);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DanbooruPostDelegate::paint(QPainter *painter,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!index.isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStyleOptionViewItemV4 opt(option);
|
||||||
|
|
||||||
|
// Pixmap
|
||||||
|
|
||||||
|
QStyle *style = QApplication::style();
|
||||||
|
|
||||||
|
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, 0);
|
||||||
|
painter->setRenderHint(QPainter::Antialiasing);
|
||||||
|
|
||||||
|
QPixmap pixmap = index.data(Qt::DecorationRole).value<QPixmap>();
|
||||||
|
|
||||||
|
if (pixmap.isNull()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect rect = opt.rect;
|
||||||
|
QFontMetrics metrics = opt.fontMetrics;
|
||||||
|
QRect textRect(rect.left() + MARGIN, rect.bottom() - 3 * metrics.height(),
|
||||||
|
rect.width(), 3 * metrics.height());
|
||||||
|
|
||||||
|
// Scaling is unavoidable to keep things in the right dimension
|
||||||
|
|
||||||
|
QPixmap scaled;
|
||||||
|
|
||||||
|
// Reserve enough space for the pixmap + the 3 lines of text:
|
||||||
|
// this prevents issues with images that have height > width
|
||||||
|
// (like in yande.re which keeps a lot of scans)
|
||||||
|
|
||||||
|
int maxHeight = rect.height() - 3 * metrics.height() - 2 * MARGIN;
|
||||||
|
|
||||||
|
scaled = pixmap.scaled(rect.width() - 2 * MARGIN,
|
||||||
|
maxHeight,
|
||||||
|
Qt::KeepAspectRatio,
|
||||||
|
Qt::SmoothTransformation);
|
||||||
|
|
||||||
|
QRect pixRect = scaled.rect();
|
||||||
|
pixRect.moveCenter(rect.center());
|
||||||
|
|
||||||
|
// move the pixmap up to accomodate some lines of text
|
||||||
|
|
||||||
|
pixRect.moveTo(pixRect.left(),
|
||||||
|
pixRect.top() - textRect.height() / 2);
|
||||||
|
pixRect.moveBottom(textRect.top() - MARGIN);
|
||||||
|
|
||||||
|
painter->drawPixmap(pixRect, scaled);
|
||||||
|
|
||||||
|
painter->save();
|
||||||
|
|
||||||
|
// Show buttons on mouseover
|
||||||
|
|
||||||
|
if (option.state & QStyle::State_MouseOver) {
|
||||||
|
|
||||||
|
// Get the bottom coordinate for the buttons
|
||||||
|
// TODO: Perhaps add some transition?
|
||||||
|
|
||||||
|
m_downloadButton->move(pixRect.topLeft());
|
||||||
|
m_viewButton->move(pixRect.bottomLeft() - QPoint(
|
||||||
|
0, m_viewButton->height() - 1.5 * MARGIN));
|
||||||
|
|
||||||
|
m_downloadButton->show();
|
||||||
|
m_viewButton->show();
|
||||||
|
|
||||||
|
} else if (!hoveredIndex().isValid()) {
|
||||||
m_downloadButton->hide();
|
m_downloadButton->hide();
|
||||||
m_viewButton->hide();
|
m_viewButton->hide();
|
||||||
|
|
||||||
m_downloadButton->resize(m_buttonSize, m_buttonSize);
|
|
||||||
m_viewButton->resize(m_buttonSize, m_buttonSize);
|
|
||||||
m_downloadButton->setToolTip(i18n("Download image"));
|
|
||||||
m_viewButton->setToolTip(i18n("View image"));
|
|
||||||
|
|
||||||
// Signal-slot connections
|
|
||||||
|
|
||||||
connect(m_viewButton, &QPushButton::clicked, this, &DanbooruPostDelegate::viewButtonClicked);
|
|
||||||
connect(m_downloadButton, &QPushButton::clicked, this, &DanbooruPostDelegate::downloadButtonClicked);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DanbooruPostDelegate::paint(QPainter* painter,
|
painter->restore();
|
||||||
const QStyleOptionViewItem& option,
|
|
||||||
const QModelIndex& index) const
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!index.isValid()) {
|
// Text
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStyleOptionViewItemV4 opt(option);
|
DanbooruPost *post = index.data().value<Danbooru::DanbooruPost *>();
|
||||||
|
|
||||||
// Pixmap
|
painter->save();
|
||||||
|
|
||||||
QStyle *style = QApplication::style();
|
int imageHeight = post->height();
|
||||||
|
int imageWidth = post->width();
|
||||||
|
|
||||||
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, 0);
|
KFormat format;
|
||||||
painter->setRenderHint(QPainter::Antialiasing);
|
|
||||||
|
|
||||||
QPixmap pixmap = index.data(Qt::DecorationRole).value<QPixmap>();
|
QString imageText = i18n(
|
||||||
|
"File size: %1",
|
||||||
|
format.formatByteSize(post->size()));
|
||||||
|
|
||||||
if (pixmap.isNull()) {
|
KLocalizedString sizestr = ki18np("1 pixel", "%1 pixels");
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect rect = opt.rect;
|
imageText += "\n";
|
||||||
QFontMetrics metrics = opt.fontMetrics;
|
imageText += i18n("Resolution: %1 x %2",
|
||||||
QRect textRect(rect.left() + MARGIN, rect.bottom() - 3 * metrics.height(),
|
sizestr.subs(imageWidth).toString(),
|
||||||
rect.width(), 3 * metrics.height());
|
sizestr.subs(imageHeight).toString());
|
||||||
|
imageText += "\n";
|
||||||
|
|
||||||
// Scaling is unavoidable to keep things in the right dimension
|
QString ratingString;
|
||||||
|
|
||||||
QPixmap scaled;
|
|
||||||
|
|
||||||
// Reserve enough space for the pixmap + the 3 lines of text:
|
|
||||||
// this prevents issues with images that have height > width
|
|
||||||
// (like in yande.re which keeps a lot of scans)
|
|
||||||
|
|
||||||
int maxHeight = rect.height() - 3 * metrics.height() - 2 * MARGIN;
|
|
||||||
|
|
||||||
scaled = pixmap.scaled(rect.width() - 2 * MARGIN,
|
|
||||||
maxHeight,
|
|
||||||
Qt::KeepAspectRatio,
|
|
||||||
Qt::SmoothTransformation);
|
|
||||||
|
|
||||||
|
|
||||||
QRect pixRect = scaled.rect();
|
|
||||||
pixRect.moveCenter(rect.center());
|
|
||||||
|
|
||||||
// move the pixmap up to accomodate some lines of text
|
|
||||||
|
|
||||||
pixRect.moveTo(pixRect.left(),
|
|
||||||
pixRect.top() - textRect.height() / 2);
|
|
||||||
pixRect.moveBottom(textRect.top() - MARGIN);
|
|
||||||
|
|
||||||
painter->drawPixmap(pixRect, scaled);
|
|
||||||
|
|
||||||
painter->save();
|
|
||||||
|
|
||||||
// Show buttons on mouseover
|
|
||||||
|
|
||||||
if (option.state & QStyle::State_MouseOver) {
|
|
||||||
|
|
||||||
// Get the bottom coordinate for the buttons
|
|
||||||
// TODO: Perhaps add some transition?
|
|
||||||
|
|
||||||
m_downloadButton->move(pixRect.topLeft());
|
|
||||||
m_viewButton->move(pixRect.bottomLeft() - QPoint(
|
|
||||||
0, m_viewButton->height() - 1.5 * MARGIN));
|
|
||||||
|
|
||||||
m_downloadButton->show();
|
|
||||||
m_viewButton->show();
|
|
||||||
|
|
||||||
} else if (!hoveredIndex().isValid()) {
|
|
||||||
m_downloadButton->hide();
|
|
||||||
m_viewButton->hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
painter->restore();
|
|
||||||
|
|
||||||
// Text
|
|
||||||
|
|
||||||
DanbooruPost* post = index.data().value<Danbooru::DanbooruPost*>();
|
|
||||||
|
|
||||||
painter->save();
|
|
||||||
|
|
||||||
int imageHeight = post->height();
|
|
||||||
int imageWidth = post->width();
|
|
||||||
|
|
||||||
KFormat format;
|
|
||||||
|
|
||||||
QString imageText = i18n(
|
|
||||||
"File size: %1",
|
|
||||||
format.formatByteSize(post->size()));
|
|
||||||
|
|
||||||
KLocalizedString sizestr = ki18np("1 pixel", "%1 pixels");
|
|
||||||
|
|
||||||
imageText += "\n";
|
|
||||||
imageText += i18n("Resolution: %1 x %2",
|
|
||||||
sizestr.subs(imageWidth).toString(),
|
|
||||||
sizestr.subs(imageHeight).toString());
|
|
||||||
imageText += "\n";
|
|
||||||
|
|
||||||
QString ratingString;
|
|
||||||
|
|
||||||
switch (post->rating()) {
|
|
||||||
case DanbooruPost::Safe:
|
|
||||||
ratingString = i18n("Safe");
|
|
||||||
break;
|
|
||||||
case DanbooruPost::Questionable:
|
|
||||||
ratingString = i18n("Questionable");
|
|
||||||
break;
|
|
||||||
case DanbooruPost::Explicit:
|
|
||||||
ratingString = i18n("Explicit");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ratingString = i18nc("Unknown post rating", "Unknown");
|
|
||||||
}
|
|
||||||
|
|
||||||
imageText += i18n("Rating: %1", ratingString);
|
|
||||||
|
|
||||||
painter->drawText(textRect, imageText);
|
|
||||||
painter->restore();
|
|
||||||
|
|
||||||
|
switch (post->rating()) {
|
||||||
|
case DanbooruPost::Safe:
|
||||||
|
ratingString = i18n("Safe");
|
||||||
|
break;
|
||||||
|
case DanbooruPost::Questionable:
|
||||||
|
ratingString = i18n("Questionable");
|
||||||
|
break;
|
||||||
|
case DanbooruPost::Explicit:
|
||||||
|
ratingString = i18n("Explicit");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ratingString = i18nc("Unknown post rating", "Unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize DanbooruPostDelegate::sizeHint(const QStyleOptionViewItem& option,
|
imageText += i18n("Rating: %1", ratingString);
|
||||||
const QModelIndex& index) const
|
|
||||||
{
|
|
||||||
|
|
||||||
Q_UNUSED(option)
|
painter->drawText(textRect, imageText);
|
||||||
|
painter->restore();
|
||||||
|
|
||||||
if (!index.isValid()) {
|
}
|
||||||
return QSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_itemView->gridSize();
|
QSize DanbooruPostDelegate::sizeHint(const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
|
||||||
|
Q_UNUSED(option)
|
||||||
|
|
||||||
|
if (!index.isValid()) {
|
||||||
|
return QSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex DanbooruPostDelegate::hoveredIndex() const
|
return m_itemView->gridSize();
|
||||||
{
|
|
||||||
const QPoint pos = m_itemView->viewport()->mapFromGlobal(QCursor::pos());
|
}
|
||||||
return m_itemView->indexAt(pos);
|
|
||||||
|
QModelIndex DanbooruPostDelegate::hoveredIndex() const
|
||||||
|
{
|
||||||
|
const QPoint pos = m_itemView->viewport()->mapFromGlobal(QCursor::pos());
|
||||||
|
return m_itemView->indexAt(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DanbooruPostDelegate::downloadButtonClicked()
|
||||||
|
{
|
||||||
|
QModelIndex index = hoveredIndex();
|
||||||
|
|
||||||
|
if (!index.isValid()) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DanbooruPostDelegate::downloadButtonClicked()
|
QVariant data = index.data(Qt::DisplayRole);
|
||||||
{
|
const DanbooruPost *post = data.value<DanbooruPost *>();
|
||||||
QModelIndex index = hoveredIndex();
|
|
||||||
|
|
||||||
if (!index.isValid()) {
|
if (post) {
|
||||||
return;
|
Q_EMIT(postDownloadRequested(post->fileUrl()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QVariant data = index.data(Qt::DisplayRole);
|
void DanbooruPostDelegate::viewButtonClicked()
|
||||||
const DanbooruPost* post = data.value<DanbooruPost*>();
|
{
|
||||||
|
|
||||||
if (post) {
|
QModelIndex index = hoveredIndex();
|
||||||
Q_EMIT(postDownloadRequested(post->fileUrl()));
|
|
||||||
}
|
if (!index.isValid()) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DanbooruPostDelegate::viewButtonClicked()
|
QVariant data = index.data(Qt::DisplayRole);
|
||||||
{
|
const DanbooruPost *post = data.value<DanbooruPost *>();
|
||||||
|
if (post) {
|
||||||
QModelIndex index = hoveredIndex();
|
Q_EMIT(postViewRequested(post->fileUrl()));
|
||||||
|
|
||||||
if (!index.isValid()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant data = index.data(Qt::DisplayRole);
|
|
||||||
const DanbooruPost* post = data.value<DanbooruPost*>();
|
|
||||||
if (post) {
|
|
||||||
Q_EMIT(postViewRequested(post->fileUrl()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Danbooru
|
} // namespace Danbooru
|
||||||
|
|
|
@ -37,67 +37,63 @@ class QListView;
|
||||||
class QPainter;
|
class QPainter;
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
|
|
||||||
|
namespace Danbooru
|
||||||
|
{
|
||||||
|
|
||||||
namespace Danbooru {
|
/**
|
||||||
|
* @brief Specific delegate for Danbooru items.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
class DanbooruPost;
|
||||||
* @brief Specific delegate for Danbooru items.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
class DanbooruPost;
|
class DanbooruPostDelegate : public QStyledItemDelegate
|
||||||
|
{
|
||||||
class DanbooruPostDelegate : public QStyledItemDelegate
|
|
||||||
{
|
|
||||||
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DanbooruPostDelegate(QListView* itemView);
|
DanbooruPostDelegate(QListView *itemView);
|
||||||
|
|
||||||
void paint(QPainter* painter, const QStyleOptionViewItem& option,
|
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||||
const QModelIndex& index) const;
|
const QModelIndex &index) const;
|
||||||
QSize sizeHint(const QStyleOptionViewItem& option,
|
QSize sizeHint(const QStyleOptionViewItem &option,
|
||||||
const QModelIndex& index) const;
|
const QModelIndex &index) const;
|
||||||
|
|
||||||
QModelIndex hoveredIndex() const;
|
QModelIndex hoveredIndex() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
QListView* m_itemView;
|
QListView *m_itemView;
|
||||||
QPushButton* m_downloadButton;
|
QPushButton *m_downloadButton;
|
||||||
QPushButton* m_viewButton;
|
QPushButton *m_viewButton;
|
||||||
|
|
||||||
int m_buttonSize;
|
int m_buttonSize;
|
||||||
static const int MARGIN;
|
static const int MARGIN;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Emitted when the view button is clicked.
|
* @brief Emitted when the view button is clicked.
|
||||||
*
|
*
|
||||||
* @param postUrl the URL to the full picture.
|
* @param postUrl the URL to the full picture.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void postViewRequested(QUrl postUrl);
|
void postViewRequested(QUrl postUrl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Emitted when the download button is clicked.
|
||||||
|
*
|
||||||
|
* @param postUrl the URL to the full picture.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void postDownloadRequested(QUrl postUrl);
|
||||||
|
|
||||||
/**
|
private Q_SLOTS:
|
||||||
* @brief Emitted when the download button is clicked.
|
void viewButtonClicked();
|
||||||
*
|
void downloadButtonClicked();
|
||||||
* @param postUrl the URL to the full picture.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void postDownloadRequested(QUrl postUrl);
|
|
||||||
|
|
||||||
|
};
|
||||||
private Q_SLOTS:
|
|
||||||
void viewButtonClicked();
|
|
||||||
void downloadButtonClicked();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Danbooru
|
} // namespace Danbooru
|
||||||
|
|
||||||
|
|
|
@ -30,88 +30,90 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
|
|
||||||
namespace Danbooru {
|
namespace Danbooru
|
||||||
|
{
|
||||||
|
|
||||||
DanbooruPostModel::DanbooruPostModel(QObject* parent): QAbstractListModel(parent)
|
DanbooruPostModel::DanbooruPostModel(QObject *parent): QAbstractListModel(parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DanbooruPostModel::~DanbooruPostModel()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!m_items.isEmpty()) {
|
||||||
|
qDeleteAll(m_items);
|
||||||
|
m_items.clear();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DanbooruPostModel::~DanbooruPostModel()
|
int DanbooruPostModel::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(parent)
|
||||||
|
return m_items.size();
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_items.isEmpty()) {
|
void DanbooruPostModel::addPost(Danbooru::DanbooruPost *post)
|
||||||
qDeleteAll(m_items);
|
{
|
||||||
m_items.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int DanbooruPostModel::rowCount(const QModelIndex& parent) const
|
beginInsertRows(QModelIndex(), m_items.size(), m_items.size());
|
||||||
{
|
m_items.append(post);
|
||||||
Q_UNUSED(parent)
|
endInsertRows();
|
||||||
return m_items.size();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void DanbooruPostModel::addPost(Danbooru::DanbooruPost* post)
|
QVariant DanbooruPostModel::data(const QModelIndex &index, int role) const
|
||||||
{
|
{
|
||||||
|
|
||||||
beginInsertRows(QModelIndex(), m_items.size(), m_items.size());
|
|
||||||
m_items.append(post);
|
|
||||||
endInsertRows();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant DanbooruPostModel::data(const QModelIndex& index, int role) const
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!index.isValid()) {
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index.row() >= m_items.size() || index.row() < 0) {
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_items.isEmpty()) {
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
DanbooruPost* post = m_items.at(index.row());
|
|
||||||
|
|
||||||
if (!post) {
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (role == Qt::DisplayRole) {
|
|
||||||
|
|
||||||
QVariant variant;
|
|
||||||
variant.setValue(post);
|
|
||||||
|
|
||||||
return variant;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (role == Qt::DecorationRole) {
|
|
||||||
const QPixmap pixmap = post->pixmap();
|
|
||||||
return pixmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (role == Qt::ToolTipRole) {
|
|
||||||
return post->fileUrl().fileName();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!index.isValid()) {
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DanbooruPostModel::clear() {
|
if (index.row() >= m_items.size() || index.row() < 0) {
|
||||||
|
return QVariant();
|
||||||
if (m_items.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
beginRemoveRows(QModelIndex(),0, m_items.size());
|
|
||||||
qDeleteAll(m_items);
|
|
||||||
m_items.clear();
|
|
||||||
endRemoveRows();
|
|
||||||
reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_items.isEmpty()) {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
DanbooruPost *post = m_items.at(index.row());
|
||||||
|
|
||||||
|
if (!post) {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
|
||||||
|
QVariant variant;
|
||||||
|
variant.setValue(post);
|
||||||
|
|
||||||
|
return variant;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (role == Qt::DecorationRole) {
|
||||||
|
const QPixmap pixmap = post->pixmap();
|
||||||
|
return pixmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (role == Qt::ToolTipRole) {
|
||||||
|
return post->fileUrl().fileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DanbooruPostModel::clear()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (m_items.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
beginRemoveRows(QModelIndex(), 0, m_items.size());
|
||||||
|
qDeleteAll(m_items);
|
||||||
|
m_items.clear();
|
||||||
|
endRemoveRows();
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,49 +32,49 @@
|
||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
namespace Danbooru {
|
namespace Danbooru
|
||||||
|
{
|
||||||
|
|
||||||
class DanbooruPost;
|
class DanbooruPost;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A model to represent DanbooruItems
|
* @brief A model to represent DanbooruItems
|
||||||
*
|
*
|
||||||
* Since items from a Danbooru service are sent by the service itself,
|
* Since items from a Danbooru service are sent by the service itself,
|
||||||
* there is no need for sorting or table-like structures: everything is
|
* there is no need for sorting or table-like structures: everything is
|
||||||
* represented as a flat list.
|
* represented as a flat list.
|
||||||
*
|
*
|
||||||
* Items are added through the addPost() slot.
|
* Items are added through the addPost() slot.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class DanbooruPostModel : public QAbstractListModel
|
class DanbooruPostModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DanbooruPostModel(QObject* parent=0);
|
DanbooruPostModel(QObject *parent = 0);
|
||||||
~DanbooruPostModel();
|
~DanbooruPostModel();
|
||||||
|
|
||||||
int rowCount(const QModelIndex& parent=QModelIndex()) const;
|
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
QVariant data(const QModelIndex& index, int role) const;
|
QVariant data(const QModelIndex &index, int role) const;
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVector<DanbooruPost*> m_items;
|
QVector<DanbooruPost *> m_items;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
/**
|
/**
|
||||||
* @brief Add a new post to the model
|
* @brief Add a new post to the model
|
||||||
*
|
*
|
||||||
* Connect to this slot when you want to add items to the model.
|
* Connect to this slot when you want to add items to the model.
|
||||||
*
|
*
|
||||||
* @param post A pointer to a DanbooruPost.
|
* @param post A pointer to a DanbooruPost.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void addPost(Danbooru::DanbooruPost* post);
|
void addPost(Danbooru::DanbooruPost *post);
|
||||||
|
|
||||||
};
|
};
|
||||||
}; // namespace Danbooru
|
}; // namespace Danbooru
|
||||||
|
|
||||||
|
|
||||||
#endif // DANBOORUPOSTMODEL_H
|
#endif // DANBOORUPOSTMODEL_H
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue