Work on labels, huge changes in plugin-base code, also working sync-in common logic, working label obtaining for TT-RSS.
This commit is contained in:
parent
93721ac9e0
commit
ed56e7581b
12 changed files with 209 additions and 33 deletions
|
@ -205,7 +205,7 @@ void MessagePreviewer::updateLabels(bool only_clear) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_root.data() != nullptr) {
|
if (m_root.data() != nullptr && m_root.data()->getParentServiceRoot()->labelsNode()->labels().size() > 0) {
|
||||||
m_separator = m_toolBar->addSeparator();
|
m_separator = m_toolBar->addSeparator();
|
||||||
QSqlDatabase database = qApp->database()->connection(metaObject()->className());
|
QSqlDatabase database = qApp->database()->connection(metaObject()->className());
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ void MessagePreviewer::updateLabels(bool only_clear) {
|
||||||
btn_label->setCheckable(true);
|
btn_label->setCheckable(true);
|
||||||
btn_label->setIcon(Label::generateIcon(label->color()));
|
btn_label->setIcon(Label::generateIcon(label->color()));
|
||||||
btn_label->setAutoRaise(false);
|
btn_label->setAutoRaise(false);
|
||||||
btn_label->setText(label->title());
|
btn_label->setText(QSL(" ") + label->title());
|
||||||
btn_label->setToolButtonStyle(Qt::ToolButtonStyle::ToolButtonTextBesideIcon);
|
btn_label->setToolButtonStyle(Qt::ToolButtonStyle::ToolButtonTextBesideIcon);
|
||||||
btn_label->setChecked(DatabaseQueries::isLabelAssignedToMessage(database, label, m_message));
|
btn_label->setChecked(DatabaseQueries::isLabelAssignedToMessage(database, label, m_message));
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ void MessagesView::setupAppearance() {
|
||||||
header()->setDefaultSectionSize(MESSAGES_VIEW_DEFAULT_COL);
|
header()->setDefaultSectionSize(MESSAGES_VIEW_DEFAULT_COL);
|
||||||
header()->setMinimumSectionSize(MESSAGES_VIEW_MINIMUM_COL);
|
header()->setMinimumSectionSize(MESSAGES_VIEW_MINIMUM_COL);
|
||||||
header()->setCascadingSectionResizes(false);
|
header()->setCascadingSectionResizes(false);
|
||||||
header()->setStretchLastSection(true);
|
header()->setStretchLastSection(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::focusInEvent(QFocusEvent* event) {
|
void MessagesView::focusInEvent(QFocusEvent* event) {
|
||||||
|
|
|
@ -60,6 +60,8 @@ void DatabaseCleaner::purgeDatabaseData(const CleanerOrders& which_data) {
|
||||||
emit purgeProgress(progress, tr("Starred messages purged..."));
|
emit purgeProgress(progress, tr("Starred messages purged..."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result &= DatabaseQueries::purgeLeftoverLabelAssignments(database);
|
||||||
|
|
||||||
if (which_data.m_shrinkDatabase) {
|
if (which_data.m_shrinkDatabase) {
|
||||||
progress += difference;
|
progress += difference;
|
||||||
emit purgeProgress(progress, tr("Shrinking database file..."));
|
emit purgeProgress(progress, tr("Shrinking database file..."));
|
||||||
|
|
|
@ -156,7 +156,9 @@ bool DatabaseQueries::createLabel(const QSqlDatabase& db, Label* label, int acco
|
||||||
|
|
||||||
// NOTE: This custom ID in this object will be probably
|
// NOTE: This custom ID in this object will be probably
|
||||||
// overwritten in online-synchronized labels.
|
// overwritten in online-synchronized labels.
|
||||||
label->setCustomId(QString::number(label->id()));
|
if (label->customId().isEmpty()) {
|
||||||
|
label->setCustomId(QString::number(label->id()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fixup missing custom IDs.
|
// Fixup missing custom IDs.
|
||||||
|
@ -988,7 +990,9 @@ bool DatabaseQueries::deleteAccount(const QSqlDatabase& db, int account_id) {
|
||||||
<< QSL("DELETE FROM Feeds WHERE account_id = :account_id;")
|
<< QSL("DELETE FROM Feeds WHERE account_id = :account_id;")
|
||||||
<< QSL("DELETE FROM Categories WHERE account_id = :account_id;")
|
<< QSL("DELETE FROM Categories WHERE account_id = :account_id;")
|
||||||
<< QSL("DELETE FROM MessageFiltersInFeeds WHERE account_id = :account_id;")
|
<< QSL("DELETE FROM MessageFiltersInFeeds WHERE account_id = :account_id;")
|
||||||
<< QSL("DELETE FROM Accounts WHERE id = :account_id;");
|
<< QSL("DELETE FROM Accounts WHERE id = :account_id;")
|
||||||
|
<< QSL("DELETE FROM LabelsInMessages WHERE account_id = :account_id;")
|
||||||
|
<< QSL("DELETE FROM Labels WHERE account_id = :account_id;");
|
||||||
|
|
||||||
for (const QString& q : queries) {
|
for (const QString& q : queries) {
|
||||||
query.prepare(q);
|
query.prepare(q);
|
||||||
|
@ -1029,6 +1033,17 @@ bool DatabaseQueries::deleteAccountData(const QSqlDatabase& db, int account_id,
|
||||||
q.bindValue(QSL(":account_id"), account_id);
|
q.bindValue(QSL(":account_id"), account_id);
|
||||||
result &= q.exec();
|
result &= q.exec();
|
||||||
|
|
||||||
|
if (delete_messages_too) {
|
||||||
|
// If we delete message, make sure to delete message/label assignments too.
|
||||||
|
q.prepare(QSL("DELETE FROM LabelsInMessages WHERE account_id = :account_id;"));
|
||||||
|
q.bindValue(QSL(":account_id"), account_id);
|
||||||
|
result &= q.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
q.prepare(QSL("DELETE FROM Labels WHERE account_id = :account_id;"));
|
||||||
|
q.bindValue(QSL(":account_id"), account_id);
|
||||||
|
result &= q.exec();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1118,8 +1133,8 @@ bool DatabaseQueries::purgeLeftoverMessages(const QSqlDatabase& db, int account_
|
||||||
QSqlQuery q(db);
|
QSqlQuery q(db);
|
||||||
|
|
||||||
q.setForwardOnly(true);
|
q.setForwardOnly(true);
|
||||||
q.prepare(
|
q.prepare(QSL("DELETE FROM Messages "
|
||||||
QSL("DELETE FROM Messages WHERE account_id = :account_id AND feed NOT IN (SELECT custom_id FROM Feeds WHERE account_id = :account_id);"));
|
"WHERE account_id = :account_id AND feed NOT IN (SELECT custom_id FROM Feeds WHERE account_id = :account_id);"));
|
||||||
q.bindValue(QSL(":account_id"), account_id);
|
q.bindValue(QSL(":account_id"), account_id);
|
||||||
|
|
||||||
if (!q.exec()) {
|
if (!q.exec()) {
|
||||||
|
@ -1134,6 +1149,52 @@ bool DatabaseQueries::purgeLeftoverMessages(const QSqlDatabase& db, int account_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DatabaseQueries::purgeLeftoverLabelAssignments(const QSqlDatabase& db, int account_id) {
|
||||||
|
QSqlQuery q(db);
|
||||||
|
bool succ = false;
|
||||||
|
|
||||||
|
if (account_id <= 0) {
|
||||||
|
succ = q.exec(QSL("DELETE FROM LabelsInMessages "
|
||||||
|
"WHERE NOT EXISTS (SELECT * FROM Messages WHERE Messages.account_id = LabelsInMessages.account_id AND Messages.custom_id = LabelsInMessages.message);"))
|
||||||
|
&&
|
||||||
|
q.exec(QSL("DELETE FROM LabelsInMessages "
|
||||||
|
"WHERE NOT EXISTS (SELECT * FROM Labels WHERE Labels.account_id = LabelsInMessages.account_id AND Labels.custom_id = LabelsInMessages.label);"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
q.prepare(QSL("DELETE FROM LabelsInMessages "
|
||||||
|
"WHERE account_id = :account_id AND "
|
||||||
|
" (message NOT IN (SELECT custom_id FROM Messages WHERE account_id = :account_id) OR "
|
||||||
|
" label NOT IN (SELECT custom_id FROM Labels WHERE account_id = :account_id));"));
|
||||||
|
q.bindValue(QSL(":account_id"), account_id);
|
||||||
|
succ = q.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!succ) {
|
||||||
|
auto xx = q.lastError().text();
|
||||||
|
|
||||||
|
qWarningNN << LOGSEC_DB
|
||||||
|
<< "Removing of leftover label assignments failed: '"
|
||||||
|
<< q.lastError().text()
|
||||||
|
<< "'.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return succ;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DatabaseQueries::purgeLabelsAndLabelAssignments(const QSqlDatabase& db, int account_id) {
|
||||||
|
QSqlQuery q(db);
|
||||||
|
|
||||||
|
q.prepare(QSL("DELETE FROM LabelsInMessages WHERE account_id = :account_id;"));
|
||||||
|
q.bindValue(QSL(":account_id"), account_id);
|
||||||
|
auto succ = q.exec();
|
||||||
|
|
||||||
|
q.prepare(QSL("DELETE FROM Labels WHERE account_id = :account_id;"));
|
||||||
|
q.bindValue(QSL(":account_id"), account_id);
|
||||||
|
succ &= q.exec();
|
||||||
|
|
||||||
|
return succ;
|
||||||
|
}
|
||||||
|
|
||||||
bool DatabaseQueries::storeAccountTree(const QSqlDatabase& db, RootItem* tree_root, int account_id) {
|
bool DatabaseQueries::storeAccountTree(const QSqlDatabase& db, RootItem* tree_root, int account_id) {
|
||||||
QSqlQuery query_category(db);
|
QSqlQuery query_category(db);
|
||||||
QSqlQuery query_feed(db);
|
QSqlQuery query_feed(db);
|
||||||
|
@ -1179,6 +1240,16 @@ bool DatabaseQueries::storeAccountTree(const QSqlDatabase& db, RootItem* tree_ro
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (child->kind() == RootItem::Kind::Labels) {
|
||||||
|
// Add all labels.
|
||||||
|
for (RootItem* lbl : child->childItems()) {
|
||||||
|
Label* label = lbl->toLabel();
|
||||||
|
|
||||||
|
if (!createLabel(db, label, account_id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -47,6 +47,11 @@ class DatabaseQueries {
|
||||||
static bool purgeMessagesFromBin(const QSqlDatabase& db, bool clear_only_read, int account_id);
|
static bool purgeMessagesFromBin(const QSqlDatabase& db, bool clear_only_read, int account_id);
|
||||||
static bool purgeLeftoverMessages(const QSqlDatabase& db, int account_id);
|
static bool purgeLeftoverMessages(const QSqlDatabase& db, int account_id);
|
||||||
|
|
||||||
|
// Purges message/label assignments where source message or label does not exist.
|
||||||
|
// If account ID smaller than 0 is passed, then do this for all accounts.
|
||||||
|
static bool purgeLeftoverLabelAssignments(const QSqlDatabase& db, int account_id = -1);
|
||||||
|
static bool purgeLabelsAndLabelAssignments(const QSqlDatabase& db, int account_id);
|
||||||
|
|
||||||
// Counts of unread/all messages.
|
// Counts of unread/all messages.
|
||||||
static QMap<QString, QPair<int, int>> getMessageCountsForCategory(const QSqlDatabase& db, const QString& custom_id,
|
static QMap<QString, QPair<int, int>> getMessageCountsForCategory(const QSqlDatabase& db, const QString& custom_id,
|
||||||
int account_id, bool only_total_counts,
|
int account_id, bool only_total_counts,
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "miscellaneous/iconfactory.h"
|
#include "miscellaneous/iconfactory.h"
|
||||||
#include "services/abstract/category.h"
|
#include "services/abstract/category.h"
|
||||||
#include "services/abstract/feed.h"
|
#include "services/abstract/feed.h"
|
||||||
|
#include "services/abstract/label.h"
|
||||||
#include "services/abstract/recyclebin.h"
|
#include "services/abstract/recyclebin.h"
|
||||||
#include "services/abstract/serviceroot.h"
|
#include "services/abstract/serviceroot.h"
|
||||||
|
|
||||||
|
@ -14,7 +15,7 @@
|
||||||
|
|
||||||
RootItem::RootItem(RootItem* parent_item)
|
RootItem::RootItem(RootItem* parent_item)
|
||||||
: QObject(nullptr), m_kind(RootItem::Kind::Root), m_id(NO_PARENT_CATEGORY), m_customId(QL1S("")),
|
: QObject(nullptr), m_kind(RootItem::Kind::Root), m_id(NO_PARENT_CATEGORY), m_customId(QL1S("")),
|
||||||
m_title(QString()), m_description(QString()), m_keepOnTop(false), m_parentItem(parent_item) {}
|
m_title(QString()), m_description(QString()), m_keepOnTop(false), m_childItems(QList<RootItem*>()), m_parentItem(parent_item) {}
|
||||||
|
|
||||||
RootItem::RootItem(const RootItem& other) : RootItem(nullptr) {
|
RootItem::RootItem(const RootItem& other) : RootItem(nullptr) {
|
||||||
setTitle(other.title());
|
setTitle(other.title());
|
||||||
|
@ -479,6 +480,10 @@ Feed* RootItem::toFeed() const {
|
||||||
return dynamic_cast<Feed*>(const_cast<RootItem*>(this));
|
return dynamic_cast<Feed*>(const_cast<RootItem*>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label* RootItem::toLabel() const {
|
||||||
|
return dynamic_cast<Label*>(const_cast<RootItem*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
ServiceRoot* RootItem::toServiceRoot() const {
|
ServiceRoot* RootItem::toServiceRoot() const {
|
||||||
return dynamic_cast<ServiceRoot*>(const_cast<RootItem*>(this));
|
return dynamic_cast<ServiceRoot*>(const_cast<RootItem*>(this));
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
class Category;
|
class Category;
|
||||||
class Feed;
|
class Feed;
|
||||||
|
class Label;
|
||||||
class ServiceRoot;
|
class ServiceRoot;
|
||||||
class QAction;
|
class QAction;
|
||||||
|
|
||||||
|
@ -173,6 +174,7 @@ class RSSGUARD_DLLSPEC RootItem : public QObject {
|
||||||
// Converters
|
// Converters
|
||||||
Category* toCategory() const;
|
Category* toCategory() const;
|
||||||
Feed* toFeed() const;
|
Feed* toFeed() const;
|
||||||
|
Label* toLabel() const;
|
||||||
ServiceRoot* toServiceRoot() const;
|
ServiceRoot* toServiceRoot() const;
|
||||||
|
|
||||||
bool keepOnTop() const;
|
bool keepOnTop() const;
|
||||||
|
|
|
@ -141,8 +141,8 @@ void ServiceRoot::updateCounts(bool including_total_count) {
|
||||||
|
|
||||||
void ServiceRoot::completelyRemoveAllData() {
|
void ServiceRoot::completelyRemoveAllData() {
|
||||||
// Purge old data from SQL and clean all model items.
|
// Purge old data from SQL and clean all model items.
|
||||||
removeOldAccountFromDatabase(true);
|
|
||||||
cleanAllItemsFromModel();
|
cleanAllItemsFromModel();
|
||||||
|
removeOldAccountFromDatabase(true);
|
||||||
updateCounts(true);
|
updateCounts(true);
|
||||||
itemChanged(QList<RootItem*>() << this);
|
itemChanged(QList<RootItem*>() << this);
|
||||||
requestReloadMessageList(true);
|
requestReloadMessageList(true);
|
||||||
|
@ -156,10 +156,18 @@ void ServiceRoot::removeOldAccountFromDatabase(bool including_messages) {
|
||||||
|
|
||||||
void ServiceRoot::cleanAllItemsFromModel() {
|
void ServiceRoot::cleanAllItemsFromModel() {
|
||||||
for (RootItem* top_level_item : childItems()) {
|
for (RootItem* top_level_item : childItems()) {
|
||||||
if (top_level_item->kind() != RootItem::Kind::Bin && top_level_item->kind() != RootItem::Kind::Important) {
|
if (top_level_item->kind() != RootItem::Kind::Bin &&
|
||||||
|
top_level_item->kind() != RootItem::Kind::Important &&
|
||||||
|
top_level_item->kind() != RootItem::Kind::Labels) {
|
||||||
requestItemRemoval(top_level_item);
|
requestItemRemoval(top_level_item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (labelsNode() != nullptr) {
|
||||||
|
for (RootItem* lbl : labelsNode()->childItems()) {
|
||||||
|
requestItemRemoval(lbl);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServiceRoot::cleanFeeds(QList<Feed*> items, bool clean_read_only) {
|
bool ServiceRoot::cleanFeeds(QList<Feed*> items, bool clean_read_only) {
|
||||||
|
@ -199,23 +207,6 @@ bool ServiceRoot::cleanFeeds(QList<Feed*> items, bool clean_read_only) {
|
||||||
|
|
||||||
void ServiceRoot::storeNewFeedTree(RootItem* root) {
|
void ServiceRoot::storeNewFeedTree(RootItem* root) {
|
||||||
DatabaseQueries::storeAccountTree(qApp->database()->connection(metaObject()->className()), root, accountId());
|
DatabaseQueries::storeAccountTree(qApp->database()->connection(metaObject()->className()), root, accountId());
|
||||||
|
|
||||||
/*if (DatabaseQueries::storeAccountTree(database, root, accountId())) {
|
|
||||||
RecycleBin* bin = recycleBin();
|
|
||||||
|
|
||||||
if (bin != nullptr && !childItems().contains(bin)) {
|
|
||||||
// As the last item, add recycle bin, which is needed.
|
|
||||||
appendChild(bin);
|
|
||||||
bin->updateCounts(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImportantNode* imp = importantNode();
|
|
||||||
|
|
||||||
if (imp != nullptr && !childItems().contains(imp)) {
|
|
||||||
appendChild(imp);
|
|
||||||
imp->updateCounts(true);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServiceRoot::removeLeftOverMessages() {
|
void ServiceRoot::removeLeftOverMessages() {
|
||||||
|
@ -230,6 +221,12 @@ void ServiceRoot::removeLeftOverMessageFilterAssignments() {
|
||||||
DatabaseQueries::purgeLeftoverMessageFilterAssignments(database, accountId());
|
DatabaseQueries::purgeLeftoverMessageFilterAssignments(database, accountId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServiceRoot::removeLeftOverMessageLabelAssignments() {
|
||||||
|
QSqlDatabase database = qApp->database()->connection(metaObject()->className());
|
||||||
|
|
||||||
|
DatabaseQueries::purgeLeftoverLabelAssignments(database, accountId());
|
||||||
|
}
|
||||||
|
|
||||||
QList<Message> ServiceRoot::undeletedMessages() const {
|
QList<Message> ServiceRoot::undeletedMessages() const {
|
||||||
QSqlDatabase database = qApp->database()->connection(metaObject()->className());
|
QSqlDatabase database = qApp->database()->connection(metaObject()->className());
|
||||||
|
|
||||||
|
@ -345,10 +342,22 @@ void ServiceRoot::syncIn() {
|
||||||
// so remove left over messages and filter assignments.
|
// so remove left over messages and filter assignments.
|
||||||
removeLeftOverMessages();
|
removeLeftOverMessages();
|
||||||
removeLeftOverMessageFilterAssignments();
|
removeLeftOverMessageFilterAssignments();
|
||||||
|
removeLeftOverMessageLabelAssignments();
|
||||||
|
|
||||||
for (RootItem* top_level_item : new_tree->childItems()) {
|
for (RootItem* top_level_item : new_tree->childItems()) {
|
||||||
top_level_item->setParent(nullptr);
|
if (top_level_item->kind() != Kind::Labels) {
|
||||||
requestItemReassignment(top_level_item, this);
|
top_level_item->setParent(nullptr);
|
||||||
|
requestItemReassignment(top_level_item, this);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// It seems that some labels got synced-in.
|
||||||
|
if (labelsNode() != nullptr) {
|
||||||
|
for (RootItem* new_lbl : top_level_item->childItems()) {
|
||||||
|
new_lbl->setParent(nullptr);
|
||||||
|
requestItemReassignment(new_lbl, labelsNode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new_tree->clearChildren();
|
new_tree->clearChildren();
|
||||||
|
|
|
@ -191,6 +191,11 @@ class ServiceRoot : public RootItem {
|
||||||
// from another machine and then performs sync-in on this machine.
|
// from another machine and then performs sync-in on this machine.
|
||||||
void removeLeftOverMessageFilterAssignments();
|
void removeLeftOverMessageFilterAssignments();
|
||||||
|
|
||||||
|
// Removes all labels/message assignments which are
|
||||||
|
// assigned to non-existing messages or which are
|
||||||
|
// assigned from non-existing labels.
|
||||||
|
void removeLeftOverMessageLabelAssignments();
|
||||||
|
|
||||||
QStringList textualFeedUrls(const QList<Feed*>& feeds) const;
|
QStringList textualFeedUrls(const QList<Feed*>& feeds) const;
|
||||||
QStringList textualFeedIds(const QList<Feed*>& feeds) const;
|
QStringList textualFeedIds(const QList<Feed*>& feeds) const;
|
||||||
QStringList customIDsOfMessages(const QList<ImportanceChange>& changes);
|
QStringList customIDsOfMessages(const QList<ImportanceChange>& changes);
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "miscellaneous/textfactory.h"
|
#include "miscellaneous/textfactory.h"
|
||||||
#include "network-web/networkfactory.h"
|
#include "network-web/networkfactory.h"
|
||||||
#include "services/abstract/category.h"
|
#include "services/abstract/category.h"
|
||||||
|
#include "services/abstract/label.h"
|
||||||
#include "services/abstract/rootitem.h"
|
#include "services/abstract/rootitem.h"
|
||||||
#include "services/tt-rss/definitions.h"
|
#include "services/tt-rss/definitions.h"
|
||||||
#include "services/tt-rss/ttrssfeed.h"
|
#include "services/tt-rss/ttrssfeed.h"
|
||||||
|
@ -150,6 +151,47 @@ TtRssResponse TtRssNetworkFactory::logout() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TtRssGetLabelsResponse TtRssNetworkFactory::getLabels() {
|
||||||
|
QJsonObject json;
|
||||||
|
|
||||||
|
json["op"] = QSL("getLabels");
|
||||||
|
json["sid"] = m_sessionId;
|
||||||
|
|
||||||
|
const int timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
|
||||||
|
QByteArray result_raw;
|
||||||
|
QList<QPair<QByteArray, QByteArray>> headers;
|
||||||
|
|
||||||
|
headers << QPair<QByteArray, QByteArray>(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON);
|
||||||
|
headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword);
|
||||||
|
|
||||||
|
NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl, timeout,
|
||||||
|
QJsonDocument(json).toJson(QJsonDocument::Compact),
|
||||||
|
result_raw,
|
||||||
|
QNetworkAccessManager::PostOperation,
|
||||||
|
headers);
|
||||||
|
TtRssGetLabelsResponse result(QString::fromUtf8(result_raw));
|
||||||
|
|
||||||
|
if (result.isNotLoggedIn()) {
|
||||||
|
// We are not logged in.
|
||||||
|
login();
|
||||||
|
json["sid"] = m_sessionId;
|
||||||
|
network_reply = NetworkFactory::performNetworkOperation(m_fullUrl, timeout, QJsonDocument(json).toJson(QJsonDocument::Compact),
|
||||||
|
result_raw,
|
||||||
|
QNetworkAccessManager::PostOperation,
|
||||||
|
headers);
|
||||||
|
result = TtRssGetLabelsResponse(QString::fromUtf8(result_raw));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (network_reply.first != QNetworkReply::NoError) {
|
||||||
|
qWarningNN << LOGSEC_TTRSS
|
||||||
|
<< "getLabels failed with error:"
|
||||||
|
<< QUOTE_W_SPACE_DOT(network_reply.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lastError = network_reply.first;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
TtRssGetFeedsCategoriesResponse TtRssNetworkFactory::getFeedsCategories() {
|
TtRssGetFeedsCategoriesResponse TtRssNetworkFactory::getFeedsCategories() {
|
||||||
QJsonObject json;
|
QJsonObject json;
|
||||||
|
|
||||||
|
@ -497,6 +539,7 @@ bool TtRssResponse::hasError() const {
|
||||||
TtRssGetFeedsCategoriesResponse::TtRssGetFeedsCategoriesResponse(const QString& raw_content) : TtRssResponse(raw_content) {}
|
TtRssGetFeedsCategoriesResponse::TtRssGetFeedsCategoriesResponse(const QString& raw_content) : TtRssResponse(raw_content) {}
|
||||||
|
|
||||||
TtRssGetFeedsCategoriesResponse::~TtRssGetFeedsCategoriesResponse() = default;
|
TtRssGetFeedsCategoriesResponse::~TtRssGetFeedsCategoriesResponse() = default;
|
||||||
|
|
||||||
RootItem* TtRssGetFeedsCategoriesResponse::feedsCategories(bool obtain_icons, QString base_address) const {
|
RootItem* TtRssGetFeedsCategoriesResponse::feedsCategories(bool obtain_icons, QString base_address) const {
|
||||||
auto* parent = new RootItem();
|
auto* parent = new RootItem();
|
||||||
|
|
||||||
|
@ -675,3 +718,19 @@ QString TtRssUnsubscribeFeedResponse::code() const {
|
||||||
|
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TtRssGetLabelsResponse::TtRssGetLabelsResponse(const QString& raw_content) : TtRssResponse(raw_content) {}
|
||||||
|
|
||||||
|
QList<RootItem*> TtRssGetLabelsResponse::labels() const {
|
||||||
|
QList<RootItem*> labels;
|
||||||
|
|
||||||
|
for (const QJsonValue& lbl_val : m_rawContent["content"].toArray()) {
|
||||||
|
QJsonObject lbl_obj = lbl_val.toObject();
|
||||||
|
Label* lbl = new Label(lbl_obj["caption"].toString(), QColor(lbl_obj["fg_color"].toString()));
|
||||||
|
|
||||||
|
lbl->setCustomId(QString::number(lbl_obj["id"].toInt()));
|
||||||
|
labels.append(lbl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return labels;
|
||||||
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
class RootItem;
|
class RootItem;
|
||||||
|
|
||||||
class TtRssFeed;
|
class TtRssFeed;
|
||||||
|
class Label;
|
||||||
|
|
||||||
class TtRssResponse {
|
class TtRssResponse {
|
||||||
public:
|
public:
|
||||||
|
@ -41,6 +41,13 @@ class TtRssLoginResponse : public TtRssResponse {
|
||||||
QString sessionId() const;
|
QString sessionId() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TtRssGetLabelsResponse : public TtRssResponse {
|
||||||
|
public:
|
||||||
|
explicit TtRssGetLabelsResponse(const QString& raw_content = QString());
|
||||||
|
|
||||||
|
QList<RootItem*> labels() const;
|
||||||
|
};
|
||||||
|
|
||||||
class TtRssGetFeedsCategoriesResponse : public TtRssResponse {
|
class TtRssGetFeedsCategoriesResponse : public TtRssResponse {
|
||||||
public:
|
public:
|
||||||
explicit TtRssGetFeedsCategoriesResponse(const QString& raw_content = QString());
|
explicit TtRssGetFeedsCategoriesResponse(const QString& raw_content = QString());
|
||||||
|
@ -139,6 +146,9 @@ class TtRssNetworkFactory {
|
||||||
// Logs user out.
|
// Logs user out.
|
||||||
TtRssResponse logout();
|
TtRssResponse logout();
|
||||||
|
|
||||||
|
// Gets list of labels from the server.
|
||||||
|
TtRssGetLabelsResponse getLabels();
|
||||||
|
|
||||||
// Gets feeds from the server.
|
// Gets feeds from the server.
|
||||||
TtRssGetFeedsCategoriesResponse getFeedsCategories();
|
TtRssGetFeedsCategoriesResponse getFeedsCategories();
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "miscellaneous/textfactory.h"
|
#include "miscellaneous/textfactory.h"
|
||||||
#include "network-web/networkfactory.h"
|
#include "network-web/networkfactory.h"
|
||||||
#include "services/abstract/importantnode.h"
|
#include "services/abstract/importantnode.h"
|
||||||
|
#include "services/abstract/labelsnode.h"
|
||||||
#include "services/abstract/recyclebin.h"
|
#include "services/abstract/recyclebin.h"
|
||||||
#include "services/tt-rss/definitions.h"
|
#include "services/tt-rss/definitions.h"
|
||||||
#include "services/tt-rss/gui/formeditttrssaccount.h"
|
#include "services/tt-rss/gui/formeditttrssaccount.h"
|
||||||
|
@ -36,7 +37,7 @@ void TtRssServiceRoot::start(bool freshly_activated) {
|
||||||
loadFromDatabase();
|
loadFromDatabase();
|
||||||
loadCacheFromFile(accountId());
|
loadCacheFromFile(accountId());
|
||||||
|
|
||||||
if (childCount() <= 2) {
|
if (childCount() <= 3) {
|
||||||
syncIn();
|
syncIn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,10 +223,17 @@ void TtRssServiceRoot::updateTitle() {
|
||||||
}
|
}
|
||||||
|
|
||||||
RootItem* TtRssServiceRoot::obtainNewTreeForSyncIn() const {
|
RootItem* TtRssServiceRoot::obtainNewTreeForSyncIn() const {
|
||||||
TtRssGetFeedsCategoriesResponse feed_cats_response = m_network->getFeedsCategories();
|
TtRssGetFeedsCategoriesResponse feed_cats = m_network->getFeedsCategories();
|
||||||
|
TtRssGetLabelsResponse labels = m_network->getLabels();
|
||||||
|
|
||||||
if (m_network->lastError() == QNetworkReply::NoError) {
|
if (m_network->lastError() == QNetworkReply::NoError) {
|
||||||
return feed_cats_response.feedsCategories(true, m_network->url());
|
auto* tree = feed_cats.feedsCategories(true, m_network->url());
|
||||||
|
auto* lblroot = new LabelsNode(tree);
|
||||||
|
|
||||||
|
lblroot->setChildItems(labels.labels());
|
||||||
|
tree->appendChild(lblroot);
|
||||||
|
|
||||||
|
return tree;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
Loading…
Add table
Reference in a new issue