diff options
Diffstat (limited to 'fetchpostsaction.cpp')
-rw-r--r-- | fetchpostsaction.cpp | 89 |
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"; |