save current code and try to fix #453
This commit is contained in:
parent
68be51b99f
commit
843b4312b2
@ -30,7 +30,7 @@
|
||||
<url type="donation">https://martinrotter.github.io/donate/</url>
|
||||
<content_rating type="oars-1.1" />
|
||||
<releases>
|
||||
<release version="3.9.2" date="2021-07-26"/>
|
||||
<release version="3.9.2" date="2021-07-27"/>
|
||||
</releases>
|
||||
<content_rating type="oars-1.0">
|
||||
<content_attribute id="violence-cartoon">none</content_attribute>
|
||||
|
@ -127,27 +127,27 @@ void FeedDownloader::updateOneFeed(Feed* feed) {
|
||||
QSqlDatabase database = is_main_thread ?
|
||||
qApp->database()->driver()->connection(metaObject()->className()) :
|
||||
qApp->database()->driver()->connection(QSL("feed_upd"));
|
||||
QHash<QString, QPair<ServiceRoot::BagOfMessages, QStringList>> stated_messages;
|
||||
QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>> stated_messages;
|
||||
QHash<QString, QStringList> tagged_messages;
|
||||
|
||||
if (feed->getParentServiceRoot()->wantsBaggedIdsOfExistingMessages()) {
|
||||
// This account has activated intelligent downloading of messages.
|
||||
// Prepare bags.
|
||||
stated_messages.insert(feed->customId(),
|
||||
{ ServiceRoot::BagOfMessages::Read,
|
||||
DatabaseQueries::bagOfMessages(database,
|
||||
ServiceRoot::BagOfMessages::Read,
|
||||
feed) });
|
||||
stated_messages.insert(feed->customId(),
|
||||
{ ServiceRoot::BagOfMessages::Unread,
|
||||
DatabaseQueries::bagOfMessages(database,
|
||||
ServiceRoot::BagOfMessages::Unread,
|
||||
feed) });
|
||||
stated_messages.insert(feed->customId(),
|
||||
{ ServiceRoot::BagOfMessages::Starred,
|
||||
DatabaseQueries::bagOfMessages(database,
|
||||
ServiceRoot::BagOfMessages::Starred,
|
||||
feed) });
|
||||
QHash<ServiceRoot::BagOfMessages, QStringList> per_feed_states;
|
||||
|
||||
per_feed_states.insert(ServiceRoot::BagOfMessages::Read,
|
||||
DatabaseQueries::bagOfMessages(database,
|
||||
ServiceRoot::BagOfMessages::Read,
|
||||
feed));
|
||||
per_feed_states.insert(ServiceRoot::BagOfMessages::Unread,
|
||||
DatabaseQueries::bagOfMessages(database,
|
||||
ServiceRoot::BagOfMessages::Unread,
|
||||
feed));
|
||||
per_feed_states.insert(ServiceRoot::BagOfMessages::Starred,
|
||||
DatabaseQueries::bagOfMessages(database,
|
||||
ServiceRoot::BagOfMessages::Starred,
|
||||
feed));
|
||||
stated_messages.insert(feed->customId(), per_feed_states);
|
||||
|
||||
tagged_messages = DatabaseQueries::bagsOfMessages(database,
|
||||
feed->getParentServiceRoot()->labelsNode()->labels());
|
||||
|
@ -39,9 +39,10 @@ MessagesModelSqlLayer::MessagesModelSqlLayer()
|
||||
<< MSG_DB_SCORE_INDEX;
|
||||
}
|
||||
|
||||
void MessagesModelSqlLayer::addSortState(int column, Qt::SortOrder order) {
|
||||
void MessagesModelSqlLayer::addSortState(int column, Qt::SortOrder order, bool ignore_multicolumn_sorting) {
|
||||
int existing = m_sortColumns.indexOf(column);
|
||||
bool is_ctrl_pressed = (QApplication::queryKeyboardModifiers() & Qt::ControlModifier) == Qt::ControlModifier;
|
||||
bool is_ctrl_pressed = (QApplication::queryKeyboardModifiers() &
|
||||
Qt::KeyboardModifier::ControlModifier) == Qt::KeyboardModifier::ControlModifier;
|
||||
|
||||
if (existing >= 0) {
|
||||
m_sortColumns.removeAt(existing);
|
||||
@ -55,14 +56,18 @@ void MessagesModelSqlLayer::addSortState(int column, Qt::SortOrder order) {
|
||||
m_sortOrders.removeAt(0);
|
||||
}
|
||||
|
||||
if (is_ctrl_pressed) {
|
||||
if (is_ctrl_pressed && !ignore_multicolumn_sorting) {
|
||||
// User is activating the multicolumn sort mode.
|
||||
m_sortColumns.append(column);
|
||||
m_sortOrders.append(order);
|
||||
|
||||
qDebugNN << "CTRL is pressed while sorting articles - sorting with multicolumn mode.";
|
||||
}
|
||||
else {
|
||||
m_sortColumns.prepend(column);
|
||||
m_sortOrders.prepend(order);
|
||||
|
||||
qDebugNN << "CTRL is NOT pressed while sorting articles - sorting with standard mode.";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ class MessagesModelSqlLayer {
|
||||
explicit MessagesModelSqlLayer();
|
||||
|
||||
// Adds this new state to queue of sort states.
|
||||
void addSortState(int column, Qt::SortOrder order);
|
||||
void addSortState(int column, Qt::SortOrder order, bool ignore_multicolumn_sorting);
|
||||
|
||||
// Sets SQL WHERE clause, without "WHERE" keyword.
|
||||
void setFilter(const QString& filter);
|
||||
|
@ -982,9 +982,10 @@ QStringList DatabaseQueries::bagOfMessages(const QSqlDatabase& db, ServiceRoot::
|
||||
|
||||
q.prepare(QSL("SELECT custom_id "
|
||||
"FROM Messages "
|
||||
"WHERE %1 AND account_id = :account_id;").arg(query));
|
||||
"WHERE %1 AND feed = :feed AND account_id = :account_id;").arg(query));
|
||||
|
||||
q.bindValue(QSL(":account_id"), feed->getParentServiceRoot()->accountId());
|
||||
q.bindValue(QSL(":feed"), feed->customId());
|
||||
q.exec();
|
||||
|
||||
while (q.next()) {
|
||||
@ -1277,22 +1278,20 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
//
|
||||
// 4) FOR ALL SERVICES: Message update is forced, we want to overwrite message as some arbitrary atribute was changed,
|
||||
// this particularly happens when manual message filter execution happens.
|
||||
if (/* 1 */ (!message.m_customId.isEmpty() && feed->getParentServiceRoot()->isSyncable() &&
|
||||
(message.m_created.toMSecsSinceEpoch() != date_existing_message ||
|
||||
message.m_isRead != is_read_existing_message ||
|
||||
message.m_isImportant != is_important_existing_message ||
|
||||
message.m_feedId != feed_id_existing_message ||
|
||||
message.m_title != title_existing_message ||
|
||||
message.m_contents != contents_existing_message)) ||
|
||||
bool cond_1 = !message.m_customId.isEmpty() && feed->getParentServiceRoot()->isSyncable() &&
|
||||
(message.m_created.toMSecsSinceEpoch() != date_existing_message ||
|
||||
message.m_isRead != is_read_existing_message ||
|
||||
message.m_isImportant != is_important_existing_message ||
|
||||
message.m_feedId != feed_id_existing_message ||
|
||||
message.m_title != title_existing_message ||
|
||||
message.m_contents != contents_existing_message);
|
||||
bool cond_2 = !message.m_customId.isEmpty() && !feed->getParentServiceRoot()->isSyncable() &&
|
||||
(message.m_title != title_existing_message ||
|
||||
message.m_contents != contents_existing_message);
|
||||
bool cond_3 = message.m_createdFromFeed && message.m_created.toMSecsSinceEpoch() != date_existing_message &&
|
||||
message.m_contents != contents_existing_message;
|
||||
|
||||
/* 2 */ (!message.m_customId.isEmpty() && !feed->getParentServiceRoot()->isSyncable() &&
|
||||
(message.m_title != title_existing_message ||
|
||||
message.m_contents != contents_existing_message)) ||
|
||||
|
||||
/* 3 */ (message.m_createdFromFeed && message.m_created.toMSecsSinceEpoch() != date_existing_message &&
|
||||
message.m_contents != contents_existing_message) ||
|
||||
|
||||
/* 4 */ force_update) {
|
||||
if (cond_1 || cond_2 || cond_3 || force_update) {
|
||||
// Message exists and is changed, update it.
|
||||
query_update.bindValue(QSL(":title"), unnulifyString(message.m_title));
|
||||
query_update.bindValue(QSL(":is_read"), int(message.m_isRead));
|
||||
|
@ -52,12 +52,15 @@ void MessagesView::reloadFontSettings() {
|
||||
m_sourceModel->setupFonts();
|
||||
}
|
||||
|
||||
void MessagesView::sort(int column, Qt::SortOrder order, bool repopulate_data, bool change_header, bool emit_changed_from_header) {
|
||||
void MessagesView::sort(int column, Qt::SortOrder order,
|
||||
bool repopulate_data, bool change_header,
|
||||
bool emit_changed_from_header,
|
||||
bool ignore_multicolumn_sorting) {
|
||||
if (change_header && !emit_changed_from_header) {
|
||||
header()->blockSignals(true);
|
||||
}
|
||||
|
||||
m_sourceModel->addSortState(column, order);
|
||||
m_sourceModel->addSortState(column, order, ignore_multicolumn_sorting);
|
||||
|
||||
if (repopulate_data) {
|
||||
m_sourceModel->repopulate();
|
||||
@ -94,7 +97,7 @@ void MessagesView::reloadSelections() {
|
||||
const Qt::SortOrder ord = header()->sortIndicatorOrder();
|
||||
|
||||
// Reload the model now.
|
||||
sort(col, ord, true, false, false);
|
||||
sort(col, ord, true, false, false, true);
|
||||
|
||||
// Now, we must find the same previously focused message.
|
||||
if (selected_message.m_id > 0) {
|
||||
@ -363,7 +366,7 @@ void MessagesView::loadItem(RootItem* item) {
|
||||
const Qt::SortOrder ord = header()->sortIndicatorOrder();
|
||||
|
||||
scrollToTop();
|
||||
sort(col, ord, false, true, false);
|
||||
sort(col, ord, false, true, false, true);
|
||||
m_sourceModel->loadMessages(item);
|
||||
|
||||
// Messages are loaded, make sure that previously
|
||||
@ -679,7 +682,7 @@ void MessagesView::adjustColumns() {
|
||||
|
||||
void MessagesView::onSortIndicatorChanged(int column, Qt::SortOrder order) {
|
||||
// Repopulate the shit.
|
||||
sort(column, order, true, false, false);
|
||||
sort(column, order, true, false, false, false);
|
||||
|
||||
emit currentMessageRemoved();
|
||||
}
|
||||
|
@ -80,7 +80,8 @@ class MessagesView : public QTreeView {
|
||||
void willReselectSameMessage();
|
||||
|
||||
private:
|
||||
void sort(int column, Qt::SortOrder order, bool repopulate_data, bool change_header, bool emit_changed_from_header);
|
||||
void sort(int column, Qt::SortOrder order, bool repopulate_data,
|
||||
bool change_header, bool emit_changed_from_header, bool ignore_multicolumn_sorting);
|
||||
|
||||
// Creates needed connections.
|
||||
void createConnections();
|
||||
|
@ -102,7 +102,7 @@ class ServiceRoot : public RootItem {
|
||||
// Throws exception subclassed from ApplicationException, preferably FeedFetchException
|
||||
// if any problems arise.
|
||||
virtual QList<Message> obtainNewMessages(const QList<Feed*>& feeds,
|
||||
const QHash<QString, QPair<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QStringList>& tagged_messages) = 0;
|
||||
|
||||
// This method should prepare messages for given "item" (download them maybe?)
|
||||
|
@ -73,7 +73,7 @@ void FeedlyServiceRoot::setCustomDatabaseData(const QVariantHash& data) {
|
||||
}
|
||||
|
||||
QList<Message> FeedlyServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
||||
const QHash<QString, QPair<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QStringList>& tagged_messages) {
|
||||
Q_UNUSED(stated_messages)
|
||||
Q_UNUSED(tagged_messages)
|
||||
|
@ -24,7 +24,7 @@ class FeedlyServiceRoot : public ServiceRoot, public CacheForServiceRoot {
|
||||
virtual QVariantHash customDatabaseData() const;
|
||||
virtual void setCustomDatabaseData(const QVariantHash& data);
|
||||
virtual QList<Message> obtainNewMessages(const QList<Feed*>& feeds,
|
||||
const QHash<QString, QPair<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QStringList>& tagged_messages);
|
||||
|
||||
FeedlyNetwork* network() const;
|
||||
|
@ -75,7 +75,7 @@ void GmailServiceRoot::setCustomDatabaseData(const QVariantHash& data) {
|
||||
}
|
||||
|
||||
QList<Message> GmailServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
||||
const QHash<QString, QPair<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QStringList>& tagged_messages) {
|
||||
Q_UNUSED(stated_messages)
|
||||
Q_UNUSED(tagged_messages)
|
||||
|
@ -32,7 +32,7 @@ class GmailServiceRoot : public ServiceRoot, public CacheForServiceRoot {
|
||||
virtual QVariantHash customDatabaseData() const;
|
||||
virtual void setCustomDatabaseData(const QVariantHash& data);
|
||||
virtual QList<Message> obtainNewMessages(const QList<Feed*>& feeds,
|
||||
const QHash<QString, QPair<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QStringList>& tagged_messages);
|
||||
|
||||
protected:
|
||||
|
@ -27,6 +27,8 @@
|
||||
#define GREADER_API_SUBSCRIPTION_LIST "reader/api/0/subscription/list?output=json"
|
||||
#define GREADER_API_STREAM_CONTENTS "reader/api/0/stream/contents/%1?output=json&n=%2"
|
||||
#define GREADER_API_EDIT_TAG "reader/api/0/edit-tag"
|
||||
#define GREADER_API_ITEM_IDS "reader/api/0/stream/items/ids?output=json&s=%1"
|
||||
#define GREADER_API_ITEM_CONTENTS "reader/api/0/stream/items/contents?output=json&n=%1"
|
||||
#define GREADER_API_TOKEN "reader/api/0/token"
|
||||
#define GREADER_API_USER_INFO "reader/api/0/user-info?output=json"
|
||||
|
||||
|
@ -120,6 +120,41 @@ QVariantHash GreaderNetwork::userInfo(const QNetworkProxy& proxy) {
|
||||
return QJsonDocument::fromJson(output).object().toVariantHash();
|
||||
}
|
||||
|
||||
QList<Message> GreaderNetwork::getMessagesIntelligently(ServiceRoot* root,
|
||||
const QString& stream_id,
|
||||
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||
const QHash<QString, QStringList>& tagged_messages,
|
||||
Feed::Status& error,
|
||||
const QNetworkProxy& proxy) {
|
||||
// 1. Get unread IDs for a feed.
|
||||
// 2. Get read IDs for a feed.
|
||||
// 3. Download messages/contents for missing or changed IDs.
|
||||
// 4. Download all starred messages and append those belonging to this feed.
|
||||
|
||||
auto remote_all_ids_list = itemIds(stream_id, false, proxy);
|
||||
auto remote_unread_ids_list = itemIds(stream_id, true, proxy);
|
||||
QSet<QString> remote_all_ids(remote_all_ids_list.begin(), remote_all_ids_list.end());
|
||||
|
||||
// 1.
|
||||
auto local_unread_ids_list = stated_messages.value(ServiceRoot::BagOfMessages::Unread);
|
||||
QSet<QString> remote_unread_ids(remote_unread_ids_list.begin(), remote_unread_ids_list.end());
|
||||
QSet<QString> local_unread_ids(local_unread_ids_list.begin(),
|
||||
local_unread_ids_list.end());
|
||||
|
||||
// 2.
|
||||
auto local_read_ids_list = stated_messages.value(ServiceRoot::BagOfMessages::Read);
|
||||
QSet<QString> remote_read_ids = remote_all_ids - remote_unread_ids;
|
||||
QSet<QString> local_read_ids(local_read_ids_list.begin(),
|
||||
local_read_ids_list.end());
|
||||
auto not_downloaded = remote_all_ids - local_read_ids - local_unread_ids;
|
||||
auto moved_unread = local_unread_ids.intersect(remote_read_ids);
|
||||
auto moved_read = local_read_ids.intersect(remote_unread_ids);
|
||||
auto to_download = not_downloaded + moved_read + moved_unread;
|
||||
QList<QString> to_download_list(to_download.begin(), to_download.end());
|
||||
|
||||
return itemContents(root, to_download_list, error, proxy);
|
||||
}
|
||||
|
||||
QNetworkReply::NetworkError GreaderNetwork::markMessagesRead(RootItem::ReadStatus status,
|
||||
const QStringList& msg_custom_ids,
|
||||
const QNetworkProxy& proxy) {
|
||||
@ -132,6 +167,115 @@ QNetworkReply::NetworkError GreaderNetwork::markMessagesStarred(RootItem::Import
|
||||
return editLabels(GREADER_API_FULL_STATE_IMPORTANT, importance == RootItem::Importance::Important, msg_custom_ids, proxy);
|
||||
}
|
||||
|
||||
QStringList GreaderNetwork::itemIds(const QString& stream_id, bool unread_only, const QNetworkProxy& proxy) {
|
||||
QString continuation;
|
||||
|
||||
if (!ensureLogin(proxy)) {
|
||||
throw ApplicationException(tr("login failed"));
|
||||
}
|
||||
|
||||
QStringList ids;
|
||||
|
||||
do {
|
||||
QString full_url = generateFullUrl(Operations::ItemIds).arg(m_service == GreaderServiceRoot::Service::TheOldReader
|
||||
? stream_id
|
||||
: QUrl::toPercentEncoding(stream_id));
|
||||
auto timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
|
||||
|
||||
if (unread_only) {
|
||||
full_url += QSL("&xt=%1").arg(GREADER_API_FULL_STATE_READ);
|
||||
}
|
||||
|
||||
if (!continuation.isEmpty()) {
|
||||
full_url += QSL("&c=%1").arg(continuation);
|
||||
}
|
||||
|
||||
QByteArray output_stream;
|
||||
auto result_stream = NetworkFactory::performNetworkOperation(full_url,
|
||||
timeout,
|
||||
{},
|
||||
output_stream,
|
||||
QNetworkAccessManager::Operation::GetOperation,
|
||||
{ authHeader() },
|
||||
false,
|
||||
{},
|
||||
{},
|
||||
proxy);
|
||||
|
||||
if (result_stream.first != QNetworkReply::NetworkError::NoError) {
|
||||
qCriticalNN << LOGSEC_GREADER
|
||||
<< "Cannot download item IDs for "
|
||||
<< QUOTE_NO_SPACE(stream_id)
|
||||
<< ", network error:"
|
||||
<< QUOTE_W_SPACE_DOT(result_stream.first);
|
||||
throw NetworkException(result_stream.first);
|
||||
}
|
||||
else {
|
||||
ids.append(decodeItemIds(output_stream, continuation));
|
||||
}
|
||||
}
|
||||
while (!continuation.isEmpty());
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
QList<Message> GreaderNetwork::itemContents(ServiceRoot* root, const QList<QString>& stream_ids,
|
||||
Feed::Status& error, const QNetworkProxy& proxy) {
|
||||
QString continuation;
|
||||
|
||||
if (!ensureLogin(proxy)) {
|
||||
error = Feed::Status::AuthError;
|
||||
return {};
|
||||
}
|
||||
|
||||
QList<Message> msgs;
|
||||
int target_msgs_size = 999;
|
||||
|
||||
do {
|
||||
QString full_url = generateFullUrl(Operations::ItemContents).arg(QString::number(target_msgs_size));
|
||||
auto timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
|
||||
|
||||
if (!continuation.isEmpty()) {
|
||||
full_url += QSL("&c=%1").arg(continuation);
|
||||
}
|
||||
|
||||
std::list inp = boolinq::from(stream_ids).select([this](const QString& id) {
|
||||
return QSL("i=%1").arg(m_service == GreaderServiceRoot::Service::TheOldReader
|
||||
? id
|
||||
: QUrl::toPercentEncoding(id));
|
||||
}).toStdList();
|
||||
QByteArray input = FROM_STD_LIST(QStringList, inp).join(QSL("&")).toUtf8();
|
||||
QByteArray output_stream;
|
||||
auto result_stream = NetworkFactory::performNetworkOperation(full_url,
|
||||
timeout,
|
||||
input,
|
||||
output_stream,
|
||||
QNetworkAccessManager::Operation::PostOperation,
|
||||
{ authHeader() },
|
||||
false,
|
||||
{},
|
||||
{},
|
||||
proxy);
|
||||
|
||||
if (result_stream.first != QNetworkReply::NetworkError::NoError) {
|
||||
qCriticalNN << LOGSEC_GREADER
|
||||
<< "Cannot download messages for "
|
||||
<< stream_ids
|
||||
<< ", network error:"
|
||||
<< QUOTE_W_SPACE_DOT(result_stream.first);
|
||||
error = Feed::Status::NetworkError;
|
||||
return {};
|
||||
}
|
||||
else {
|
||||
msgs.append(decodeStreamContents(root, output_stream, "", continuation));
|
||||
}
|
||||
}
|
||||
while (!continuation.isEmpty());
|
||||
|
||||
error = Feed::Status::Normal;
|
||||
return msgs;
|
||||
}
|
||||
|
||||
QList<Message> GreaderNetwork::streamContents(ServiceRoot* root, const QString& stream_id,
|
||||
Feed::Status& error, const QNetworkProxy& proxy) {
|
||||
QString continuation;
|
||||
@ -548,6 +692,21 @@ QString GreaderNetwork::simplifyStreamId(const QString& stream_id) const {
|
||||
return QString(stream_id).replace(QRegularExpression("\\/\\d+\\/"), QSL("/-/"));
|
||||
}
|
||||
|
||||
QStringList GreaderNetwork::decodeItemIds(const QString& stream_json_data, QString& continuation) {
|
||||
QStringList ids;
|
||||
QJsonDocument json_doc = QJsonDocument::fromJson(stream_json_data.toUtf8());
|
||||
QJsonArray json = json_doc.object()["itemRefs"].toArray();
|
||||
|
||||
continuation = json_doc.object()["continuation"].toString();
|
||||
ids.reserve(json.count());
|
||||
|
||||
for (const QJsonValue& id : json) {
|
||||
ids.append(id.toObject()["id"].toString());
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
QList<Message> GreaderNetwork::decodeStreamContents(ServiceRoot* root,
|
||||
const QString& stream_json_data,
|
||||
const QString& stream_id,
|
||||
@ -618,7 +777,9 @@ QList<Message> GreaderNetwork::decodeStreamContents(ServiceRoot* root,
|
||||
|
||||
message.m_contents = message_obj["summary"].toObject()["content"].toString();
|
||||
message.m_rawContents = QJsonDocument(message_obj).toJson(QJsonDocument::JsonFormat::Compact);
|
||||
message.m_feedId = stream_id;
|
||||
message.m_feedId = stream_id.isEmpty()
|
||||
? message_obj["origin"].toObject()["streamId"].toString()
|
||||
: stream_id;
|
||||
|
||||
messages.append(message);
|
||||
}
|
||||
@ -680,6 +841,12 @@ QString GreaderNetwork::generateFullUrl(GreaderNetwork::Operations operation) co
|
||||
case Operations::EditTag:
|
||||
return sanitizedBaseUrl() + GREADER_API_EDIT_TAG;
|
||||
|
||||
case Operations::ItemIds:
|
||||
return sanitizedBaseUrl() + GREADER_API_ITEM_IDS;
|
||||
|
||||
case Operations::ItemContents:
|
||||
return sanitizedBaseUrl() + GREADER_API_ITEM_CONTENTS;
|
||||
|
||||
default:
|
||||
return sanitizedBaseUrl();
|
||||
}
|
||||
|
@ -20,7 +20,9 @@ class GreaderNetwork : public QObject {
|
||||
StreamContents,
|
||||
EditTag,
|
||||
Token,
|
||||
UserInfo
|
||||
UserInfo,
|
||||
ItemIds,
|
||||
ItemContents
|
||||
};
|
||||
|
||||
explicit GreaderNetwork(QObject* parent = nullptr);
|
||||
@ -38,7 +40,19 @@ class GreaderNetwork : public QObject {
|
||||
|
||||
QVariantHash userInfo(const QNetworkProxy& proxy);
|
||||
|
||||
QList<Message> getMessagesIntelligently(ServiceRoot* root,
|
||||
const QString& stream_id,
|
||||
const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
|
||||
const QHash<QString, QStringList>& tagged_messages,
|
||||
Feed::Status& error,
|
||||
const QNetworkProxy& proxy);
|
||||
|
||||
QStringList itemIds(const QString& stream_id, bool unread_only, const QNetworkProxy& proxy);
|
||||
|
||||
// Stream contents for a feed/label/etc.
|
||||
QList<Message> itemContents(ServiceRoot* root, const QList<QString>& stream_ids,
|
||||
Feed::Status& error, const QNetworkProxy& proxy);
|
||||
|
||||
QList<Message> streamContents(ServiceRoot* root, const QString& stream_id,
|
||||
Feed::Status& error, const QNetworkProxy& proxy);
|
||||
|
||||
@ -78,6 +92,7 @@ class GreaderNetwork : public QObject {
|
||||
bool ensureLogin(const QNetworkProxy& proxy, QNetworkReply::NetworkError* output = nullptr);
|
||||
|
||||
QString simplifyStreamId(const QString& stream_id) const;
|
||||
QStringList decodeItemIds(const QString& stream_json_data, QString& continuation);
|
||||
QList<Message> decodeStreamContents(ServiceRoot* root, const QString& stream_json_data, const QString& stream_id, QString& continuation);
|
||||
RootItem* decodeTagsSubscriptions(const QString& categories, const QString& feeds, bool obtain_icons, const QNetworkProxy& proxy);
|
||||
QString sanitizedBaseUrl() const;
|
||||
|
@ -58,7 +58,7 @@ void GreaderServiceRoot::setCustomDatabaseData(const QVariantHash& data) {
|
||||
}
|
||||
|
||||
QList<Message> GreaderServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
||||
const QHash<QString, QPair<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QStringList>& tagged_messages) {
|
||||
Q_UNUSED(stated_messages)
|
||||
Q_UNUSED(tagged_messages)
|
||||
@ -68,7 +68,17 @@ QList<Message> GreaderServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
||||
for (Feed* feed : feeds) {
|
||||
Feed::Status error = Feed::Status::Normal;
|
||||
|
||||
messages << network()->streamContents(this, feed->customId(), error, networkProxy());
|
||||
if (true /* intelligent downloading */ ) {
|
||||
messages << network()->getMessagesIntelligently(this,
|
||||
feed->customId(),
|
||||
stated_messages.value(feed->customId()),
|
||||
tagged_messages,
|
||||
error,
|
||||
networkProxy());
|
||||
}
|
||||
else {
|
||||
messages << network()->streamContents(this, feed->customId(), error, networkProxy());
|
||||
}
|
||||
|
||||
if (error == Feed::Status::NetworkError || error == Feed::Status::AuthError) {
|
||||
throw FeedFetchException(error);
|
||||
|
@ -32,7 +32,7 @@ class GreaderServiceRoot : public ServiceRoot, public CacheForServiceRoot {
|
||||
virtual QVariantHash customDatabaseData() const;
|
||||
virtual void setCustomDatabaseData(const QVariantHash& data);
|
||||
virtual QList<Message> obtainNewMessages(const QList<Feed*>& feeds,
|
||||
const QHash<QString, QPair<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QStringList>& tagged_messages);
|
||||
virtual bool wantsBaggedIdsOfExistingMessages() const;
|
||||
|
||||
|
@ -57,7 +57,7 @@ void InoreaderServiceRoot::setCustomDatabaseData(const QVariantHash& data) {
|
||||
}
|
||||
|
||||
QList<Message> InoreaderServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
||||
const QHash<QString, QPair<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QStringList>& tagged_messages) {
|
||||
Q_UNUSED(stated_messages)
|
||||
Q_UNUSED(tagged_messages)
|
||||
|
@ -30,7 +30,7 @@ class InoreaderServiceRoot : public ServiceRoot, public CacheForServiceRoot {
|
||||
virtual QVariantHash customDatabaseData() const;
|
||||
virtual void setCustomDatabaseData(const QVariantHash& data);
|
||||
virtual QList<Message> obtainNewMessages(const QList<Feed*>& feeds,
|
||||
const QHash<QString, QPair<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QStringList>& tagged_messages);
|
||||
|
||||
protected:
|
||||
|
@ -151,7 +151,7 @@ void OwnCloudServiceRoot::setCustomDatabaseData(const QVariantHash& data) {
|
||||
}
|
||||
|
||||
QList<Message> OwnCloudServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
||||
const QHash<QString, QPair<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QStringList>& tagged_messages) {
|
||||
Q_UNUSED(stated_messages)
|
||||
Q_UNUSED(tagged_messages)
|
||||
|
@ -29,7 +29,7 @@ class OwnCloudServiceRoot : public ServiceRoot, public CacheForServiceRoot {
|
||||
virtual QVariantHash customDatabaseData() const;
|
||||
virtual void setCustomDatabaseData(const QVariantHash& data);
|
||||
virtual QList<Message> obtainNewMessages(const QList<Feed*>& feeds,
|
||||
const QHash<QString, QPair<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QStringList>& tagged_messages);
|
||||
|
||||
OwnCloudNetworkFactory* network() const;
|
||||
|
@ -145,7 +145,7 @@ Qt::ItemFlags StandardServiceRoot::additionalFlags() const {
|
||||
}
|
||||
|
||||
QList<Message> StandardServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
||||
const QHash<QString, QPair<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QStringList>& tagged_messages) {
|
||||
Q_UNUSED(stated_messages)
|
||||
Q_UNUSED(tagged_messages)
|
||||
|
@ -33,7 +33,7 @@ class StandardServiceRoot : public ServiceRoot {
|
||||
virtual bool supportsCategoryAdding() const;
|
||||
virtual Qt::ItemFlags additionalFlags() const;
|
||||
virtual QList<Message> obtainNewMessages(const QList<Feed*>& feeds,
|
||||
const QHash<QString, QPair<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QStringList>& tagged_messages);
|
||||
|
||||
QList<QAction*> serviceMenu();
|
||||
|
@ -215,7 +215,7 @@ void TtRssServiceRoot::setCustomDatabaseData(const QVariantHash& data) {
|
||||
}
|
||||
|
||||
QList<Message> TtRssServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
||||
const QHash<QString, QPair<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QStringList>& tagged_messages) {
|
||||
Q_UNUSED(stated_messages)
|
||||
Q_UNUSED(tagged_messages)
|
||||
|
@ -34,7 +34,7 @@ class TtRssServiceRoot : public ServiceRoot, public CacheForServiceRoot {
|
||||
virtual QVariantHash customDatabaseData() const;
|
||||
virtual void setCustomDatabaseData(const QVariantHash& data);
|
||||
virtual QList<Message> obtainNewMessages(const QList<Feed*>& feeds,
|
||||
const QHash<QString, QPair<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QStringList>& tagged_messages);
|
||||
|
||||
// Access to network.
|
||||
|
Loading…
x
Reference in New Issue
Block a user