summaryrefslogtreecommitdiff
path: root/fetchpostsaction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fetchpostsaction.cpp')
-rw-r--r--fetchpostsaction.cpp89
1 files changed, 74 insertions, 15 deletions
diff --git a/fetchpostsaction.cpp b/fetchpostsaction.cpp
index e38e423..1330f44 100644
--- a/fetchpostsaction.cpp
+++ b/fetchpostsaction.cpp
@@ -19,7 +19,15 @@ bool FetchPostsAction::isSupersetOf(Action *action) const
FetchPostsAction *other = qobject_cast<FetchPostsAction*>(action);
if (other) {
if (other->_topicId == _topicId) {
- if (_end == FetchAllPosts) {
+ if (_start == FetchUnreadPosts || other->_start == FetchUnreadPosts) {
+ if (_start == other->_start) {
+ // This action supersets if it fetches a larger number of posts
+ return _end >= other->_end;
+ } else {
+ // One fetches unread posts, the other does not.
+ return false;
+ }
+ } else if (_end == FetchAllPosts) {
// If this is fetching all posts, then this is a superset
// of every other action... except those that also fetch all.
return other->_end != FetchAllPosts;
@@ -37,15 +45,25 @@ bool FetchPostsAction::isSupersetOf(Action *action) const
void FetchPostsAction::execute()
{
- int end = _end;
- if (end == FetchAllPosts) {
- // Fetch posts in blocks of size 50.
- end = _start + MAX_TOPIC_PAGE_SIZE;
- // After finishing this action, a new one will be enqueued with the next 50.
+ if (_start == FetchUnreadPosts) {
+ Q_ASSERT(_end >= 0);
+ qDebug() << "Fetch unread posts" << _end;
+ _call = _board->service()->asyncCall("get_thread_by_unread",
+ QString::number(_topicId), _end);
+ } else {
+ Q_ASSERT(_start >= 0);
+ int end = _end;
+ if (end == FetchAllPosts) {
+ // Fetch posts in blocks of size 50.
+ end = _start + MAX_TOPIC_PAGE_SIZE;
+ // After finishing this action, a new one will be enqueued with the next 50.
+ }
+
+ qDebug() << "Fetch posts" << _start << end;
+ _call = _board->service()->asyncCall("get_thread",
+ QString::number(_topicId), _start, end);
}
- _call = _board->service()->asyncCall("get_thread",
- QString::number(_topicId), _start, end);
_call->setParent(this);
connect(_call, SIGNAL(finished(XmlRpcPendingCall*)), SLOT(handleFinishedCall()));
}
@@ -65,11 +83,37 @@ void FetchPostsAction::handleFinishedCall()
// Not fatal, just assume it's the one we requested
topic_id = _topicId;
}
- QString topic_title = unencodePostContent(map["topic_title"]);
+ const QString topic_title = unencodePostText(map["topic_title"]);
+ const int unread_position = map["position"].toInt() - 1;
+ const int total_post_num = map["total_post_num"].toInt();
+
+ int start;
+ if (_start == FetchUnreadPosts) {
+ // This requires some calculations
+ const int page_size = _end;
+ Q_ASSERT(page_size >= 0);
+ if (unread_position < 0) {
+ qWarning() << "Invalid unread position in reply";
+ posts.clear(); // Do not add any posts if this happens
+ }
+ const int unread_page = unread_position / page_size;
+ start = unread_page * page_size;
+ } else {
+ Q_ASSERT(_start >= 0);
+ start = _start;
+ }
+ if (start >= total_post_num) {
+ qDebug() << "No more posts";
+ if (!posts.isEmpty()) {
+ qDebug() << "Yet we got posts from the service!";
+ posts.clear(); // Sometimes
+ }
+ }
+ int position = start;
QSqlQuery query(db);
- query.prepare("INSERT OR REPLACE INTO posts (topic_id, post_id, post_title, post_content, post_author_id, post_author_name, can_edit, icon_url, post_time, last_update_time) "
- "VALUES (:topic_id, :post_id, :post_title, :post_content, :post_author_id, :post_author_name, :can_edit, :icon_url, :post_time, :last_update_time)");
+ query.prepare("INSERT OR REPLACE INTO posts (topic_id, post_id, post_title, post_content, post_author_id, post_author_name, can_edit, icon_url, post_time, position, last_update_time) "
+ "VALUES (:topic_id, :post_id, :post_title, :post_content, :post_author_id, :post_author_name, :can_edit, :icon_url, :post_time, :position, :last_update_time)");
foreach (const QVariant& post_v, posts) {
QVariantMap post = post_v.toMap();
@@ -89,8 +133,13 @@ void FetchPostsAction::handleFinishedCall()
query.bindValue(":can_edit", post["can_edit"].toBool() ? 1 : 0);
query.bindValue(":icon_url", post["icon_url"].toString());
query.bindValue(":post_time", post["post_time"].toDateTime());
+ query.bindValue(":position", position);
query.bindValue(":last_update_time", QDateTime::currentDateTime());
+ Q_ASSERT(position < total_post_num);
+
+ position++;
+
if (!query.exec()) {
qWarning() << "Failed to store topic info for:" << topic_id;
handleDatabaseError("storing topic info", query);
@@ -99,15 +148,25 @@ void FetchPostsAction::handleFinishedCall()
}
db.commit();
- if (posts.size() > 0) {
+
+ if (!posts.isEmpty()) {
+ Q_ASSERT(start >= 0);
+ Q_ASSERT(position - 1 >= start);
_board->notifyTopicPostsChanged(_topicId,
- _start, _start + posts.size() - 1);
+ start, position - 1);
+ }
+ if (_start == FetchUnreadPosts && unread_position >= 0) {
+ _board->notifyTopicPostsUnread(_topicId, unread_position);
}
if (_end == FetchAllPosts && posts.size() == MAX_TOPIC_PAGE_SIZE) {
// Ok, let's prepare to fetch the next block of posts because
// there are probably more of them
- int start = _start + MAX_TOPIC_PAGE_SIZE;
- _board->enqueueAction(new FetchPostsAction(_topicId, start, FetchAllPosts, _board));
+ Q_ASSERT(_start >= 0);
+ int next_start = start + MAX_TOPIC_PAGE_SIZE;
+ _board->enqueueAction(new FetchPostsAction(_topicId,
+ next_start,
+ FetchAllPosts,
+ _board));
}
} else {
qWarning() << "Could not fetch posts";