#include #include #include #include #include "board.h" #include "xmlrpcinterface.h" #include "xmlrpcreply.h" #include "fetchtopicsaction.h" FetchTopicsAction::FetchTopicsAction(int forumId, int start, int end, Board *board) : Action(board), _forumId(forumId), _start(start), _end(end) { } bool FetchTopicsAction::isSupersetOf(Action *action) const { FetchTopicsAction *other = qobject_cast(action); if (other) { if (other->_forumId == _forumId) { if (_start <= other->_start && _end >= other->_end) { return true; } } } return false; } void FetchTopicsAction::execute() { _call = _board->service()->asyncCall("get_topic", QString::number(_forumId), _start, _end); connect(_call, SIGNAL(finished(XmlRpcPendingCall*)), SLOT(handleFinishedCall())); } void FetchTopicsAction::handleFinishedCall() { XmlRpcReply result(_call); if (result.isValid()) { QVariantMap map = result; QVariantList topics = map["topics"].toList(); QSqlDatabase db = _board->database(); db.transaction(); QSqlQuery query(db); query.prepare("INSERT OR REPLACE INTO topics (forum_id, topic_id, topic_title, topic_author_id, topic_author_name, is_subscribed, is_closed, icon_url, last_reply_time, reply_number, new_post, last_update_time) " "VALUES (:forum_id, :topic_id, :topic_title, :topic_author_id, :topic_author_name, :is_subscribed, :is_closed, :icon_url, :last_reply_time, :reply_number, :new_post, :last_update_time)"); foreach (const QVariant& topic_v, topics) { QVariantMap topic = topic_v.toMap(); bool ok = false; int forum_id = topic["forum_id"].toInt(&ok); if (!ok) { // Not fatal, just use the one we expected. forum_id = _forumId; } int topic_id = topic["topic_id"].toInt(&ok); if (!ok) { qWarning() << "No topic_id in" << topic; continue; } query.bindValue(":forum_id", forum_id); query.bindValue(":topic_id", topic_id); query.bindValue(":topic_title", unencodeTopicText(topic["topic_title"])); query.bindValue(":topic_author_id", topic["topic_author_id"].toInt()); query.bindValue(":topic_author_name", unencodeTopicText(topic["topic_author_name"])); query.bindValue(":is_subscribed", topic["is_subscribed"].toBool() ? 1 : 0); query.bindValue(":is_closed", topic["is_closed"].toBool() ? 1 : 0); query.bindValue(":icon_url", topic["icon_url"].toString()); query.bindValue(":last_reply_time", topic["last_reply_time"].toDateTime()); query.bindValue(":reply_number", topic["reply_number"].toInt()); query.bindValue(":new_post", topic["new_post"].toBool() ? 1 : 0); query.bindValue(":last_update_time", QDateTime::currentDateTime()); if (!query.exec()) { qWarning() << "Failed to store topic info for:" << topic_id; handleDatabaseError("storing topic info", query); continue; } } db.commit(); if (topics.size() > 0) { _board->notifyForumTopicsChanged(_forumId, _start, _start + topics.size() - 1); } else { qWarning() << "Asked for topics, got none..."; } } else { qWarning() << "Could not fetch topics"; // TODO emit error ... } emit finished(this); _call->deleteLater(); } QString FetchTopicsAction::unencodeTopicText(const QVariant &v) { QByteArray ba = v.toByteArray(); return QString::fromUtf8(ba.constData(), ba.length()); }