From: Robert Karolak Date: Mon, 29 Dec 2014 17:08:44 +0000 (+0100) Subject: [Messaging] findConversations implementation for email X-Git-Tag: submit/tizen_tv/20150603.064601~1^2~709^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8b62ae39f36cd84d75465ccbc85a3265e21098b9;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Messaging] findConversations implementation for email [Verification] Code compiles withouts errors Tested well in node console Change-Id: Ice89c877d5304a3c2535f222020a1b941319c761 Signed-off-by: Robert Karolak --- diff --git a/src/messaging/email_manager.cc b/src/messaging/email_manager.cc index 95351fd8..dfb868fe 100644 --- a/src/messaging/email_manager.cc +++ b/src/messaging/email_manager.cc @@ -1108,73 +1108,73 @@ void EmailManager::findMessages(FindMsgCallbackUserData* callback) callback = NULL; } -//void EmailManager::findConversations(ConversationCallbackData* callback) -//{ -// LoggerE("Entered"); -// -// if(!callback){ -// LoggerE("Callback is null"); -// return; -// } -// -// int convListCount = 0; -// try { -// std::lock_guard lock(m_mutex); -// std::vector conversationsInfo = -// MessagingDatabaseManager::getInstance().findEmailConversations(callback); -// convListCount = conversationsInfo.size(); -// LoggerD("Found %d conversations", convListCount); -// -// for (int i = 0; i < convListCount; ++i) { -// std::shared_ptr conversation = -// MessageConversation::convertEmailConversationToObject(conversationsInfo.at(i).id); -// conversation->setUnreadMessages(conversationsInfo.at(i).unreadMessages); -// callback->addConversation(conversation); -// } -// } catch (const BasePlatformException& err) { -// LoggerE("%s (%s)", (err.getName()).c_str(), (err.getMessage()).c_str()); -// callback->setError(err.getName(), err.getMessage()); -// } catch (...) { -// LoggerE("Conversation find failed"); -// callback->setError(JSWebAPIErrorFactory::UNKNOWN_ERROR, "Conversation find failed"); -// } -// -// //Complete task -// LoggerD("callback: %p error:%d conversations.size()=%d", callback, callback->isError(), -// callback->getConversations().size()); -// -// JSContextRef context = callback->getContext(); -// if (!GlobalContextManager::getInstance()->isAliveGlobalContext(context)) { -// LoggerE("context was closed"); -// delete callback; -// callback = NULL; -// return; -// } -// -// try { -// if (callback->isError()) { -// LoggerD("Calling error callback"); -// JSObjectRef errobj = JSWebAPIErrorFactory::makeErrorObject(context, -// callback->getErrorName(), -// callback->getErrorMessage()); -// callback->callErrorCallback(errobj); -// } else { -// LoggerD("Calling success callback"); -// callback->callSuccessCallback( -// MessagingUtil::vectorToJSObjectArray(context, -// callback->getConversations())); -// } -// } catch (const BasePlatformException& err) { -// LoggerE("Error while calling findConversations callback: %s (%s)", -// (err.getName()).c_str(), (err.getMessage()).c_str()); -// } catch (...) { -// LoggerE("Failed to call findConversations callback."); -// } -// -// delete callback; -// callback = NULL; -//} +void EmailManager::findConversations(ConversationCallbackData* callback) +{ + LoggerE("Entered"); + + if(!callback){ + LoggerE("Callback is null"); + return; + } + + int convListCount = 0; + try { + std::lock_guard lock(m_mutex); + std::vector conversationsInfo = + MessagingDatabaseManager::getInstance().findEmailConversations(callback); + convListCount = conversationsInfo.size(); + LoggerD("Found %d conversations", convListCount); + + for (int i = 0; i < convListCount; ++i) { + std::shared_ptr conversation = + MessageConversation::convertEmailConversationToObject(conversationsInfo.at(i).id); + conversation->setUnreadMessages(conversationsInfo.at(i).unreadMessages); + callback->addConversation(conversation); + } + + } catch (const PlatformException& err) { + LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); + callback->setError(err.name(), err.message()); + } catch (...) { + LoggerE("Conversation find failed"); + UnknownException ex("Conversation find failed"); + callback->setError(ex.name(), ex.message()); + } + + //Complete task + LoggerD("callback: %p error:%d conversations.size()=%d", callback, callback->isError(), + callback->getConversations().size()); + + try { + if (callback->isError()) { + LoggerD("Calling error callback"); + MessagingInstance::getInstance().PostMessage(callback->getJson()->serialize().c_str()); + } else { + LoggerD("Calling success callback"); + auto json = callback->getJson(); + picojson::object& obj = json->get(); + + std::vector response; + auto messages = callback->getConversations(); + std::for_each(messages.begin(), messages.end(), + [&response](std::shared_ptr &conversation) { + response.push_back(MessagingUtil::conversationToJson(conversation)); + } + ); + obj[JSON_DATA] = picojson::value(response); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + MessagingInstance::getInstance().PostMessage(json->serialize().c_str()); + } + } catch (const common::PlatformException& err) { + LoggerE("Error while calling findConversations callback: %s (%s)", + (err.name()).c_str(), (err.message()).c_str()); + } catch (...) { + LoggerE("Failed to call findConversations callback."); + } + + delete callback; + callback = NULL; +} long EmailManager::getUniqueOpId() { diff --git a/src/messaging/email_manager.h b/src/messaging/email_manager.h index 6fcd10de..d28a7685 100644 --- a/src/messaging/email_manager.h +++ b/src/messaging/email_manager.h @@ -63,7 +63,7 @@ public: void removeMessages(MessagesCallbackUserData* callback); void updateMessages(MessagesCallbackUserData* callback); void findMessages(FindMsgCallbackUserData* callback); -// void findConversations(ConversationCallbackData* callback); + void findConversations(ConversationCallbackData* callback); // void findFolders(FoldersCallbackData* callback); void removeConversations(ConversationCallbackData* callback); diff --git a/src/messaging/message_storage.h b/src/messaging/message_storage.h index b0a04b46..27ce421e 100644 --- a/src/messaging/message_storage.h +++ b/src/messaging/message_storage.h @@ -35,7 +35,7 @@ public: virtual void removeMessages(MessagesCallbackUserData* callback) = 0; virtual void updateMessages(MessagesCallbackUserData* callback) = 0; virtual void findMessages(FindMsgCallbackUserData* callback) = 0; - virtual void findConversations() = 0; + virtual void findConversations(ConversationCallbackData* callback) = 0; virtual void removeConversations(ConversationCallbackData* callback) = 0; virtual void findFolders() = 0; diff --git a/src/messaging/message_storage_email.cc b/src/messaging/message_storage_email.cc index f0878858..a907e74f 100644 --- a/src/messaging/message_storage_email.cc +++ b/src/messaging/message_storage_email.cc @@ -165,10 +165,33 @@ void MessageStorageEmail::findMessages(FindMsgCallbackUserData* callback) } } -void MessageStorageEmail::findConversations() +static gboolean findConversationsTask(void* data) { LoggerD("Entered"); - //TODO add implementation + + ConversationCallbackData *callback = static_cast(data); + EmailManager::getInstance().findConversations(callback); + + return FALSE; +} + +void MessageStorageEmail::findConversations(ConversationCallbackData* callback) +{ + LoggerD("Entered"); + + if (!callback) { + LoggerE("Callback is null"); + throw common::UnknownException("Callback is null"); + } + + callback->setAccountId(m_id); + callback->setMessageServiceType(m_msg_type); + guint id = g_idle_add(findConversationsTask, static_cast(callback)); + if (!id) { + LoggerE("g_idle_add failed"); + delete callback; + callback = NULL; + } } static gboolean removeConversationsTask(void* data) diff --git a/src/messaging/message_storage_email.h b/src/messaging/message_storage_email.h index 76bd6a38..1f85bbf5 100644 --- a/src/messaging/message_storage_email.h +++ b/src/messaging/message_storage_email.h @@ -19,7 +19,7 @@ public: virtual void removeMessages(MessagesCallbackUserData* callback); virtual void updateMessages(MessagesCallbackUserData* callback); virtual void findMessages(FindMsgCallbackUserData* callback); - virtual void findConversations(); + virtual void findConversations(ConversationCallbackData* callback); virtual void removeConversations(ConversationCallbackData* callback); virtual void findFolders(); }; diff --git a/src/messaging/messaging_api.js b/src/messaging/messaging_api.js index 1051c035..955fdcf6 100644 --- a/src/messaging/messaging_api.js +++ b/src/messaging/messaging_api.js @@ -783,6 +783,8 @@ MessageStorage.prototype.findMessages = function () { {name: 'offset', type: types_.UNSIGNED_LONG, optional: true, nullable: true} ]); + var self = this; + bridge.async({ cmd: 'MessageStorage_findMessages', args: { @@ -790,7 +792,7 @@ MessageStorage.prototype.findMessages = function () { sort: args.sort, limit: args.limit, offset: args.offset, - serviceId: this.service.id + type: self.service.type } }).then({ success: function (data) { @@ -887,13 +889,16 @@ MessageStorage.prototype.findConversations = function () { {name: 'offset', type: types_.UNSIGNED_LONG, optional: true, nullable: true} ]); + var self = this; + bridge.async({ cmd: 'MessageStorage_findConversations', args: { filter: args.filter, sort: args.sort, limit: args.limit, - offset: args.offset + offset: args.offset, + serviceId: self.service.id } }).then({ success: function (data) { @@ -901,7 +906,7 @@ MessageStorage.prototype.findConversations = function () { data.forEach(function (el) { conversations.push(new MessageConversation(el)); }); - args.successCallback.call(null, messages); + args.successCallback.call(null, conversations); }, error: function (e) { if (args.errorCallback) { diff --git a/src/messaging/messaging_database_manager.cc b/src/messaging/messaging_database_manager.cc index 7a62e1c9..a2af8c2d 100755 --- a/src/messaging/messaging_database_manager.cc +++ b/src/messaging/messaging_database_manager.cc @@ -33,6 +33,7 @@ #include "common/logger.h" #include "common/platform_exception.h" +#include "conversation_callback_data.h" #include "messaging_database_manager.h" #include "messaging_manager.h" @@ -809,65 +810,65 @@ std::pair MessagingDatabaseManager::findEmails( // freeTable(&results); // return conversationsIds; //} -// -//std::vector MessagingDatabaseManager::findEmailConversations( -// ConversationCallbackData* callback) -//{ -// LOGD("Entered"); -// std::ostringstream sqlWhereClause; -// int resultsCount; -// email_mail_data_t* results; -// std::map conversationsBag; -// std::vector conversationsInfo; -// -// // Adding filters query -// AbstractFilterPtr filter = callback->getFilter(); -// SortModePtr sortMode = callback->getSortMode(); -// long limit = callback->getLimit(); -// long offset = callback->getOffset(); -// MessageType msgType = callback->getMessageServiceType(); -// int accountId = callback->getAccountId(); -// -// sqlWhereClause << "WHERE " -// << m_email_conv_attr_map["serviceId"].sql_name << " = " << accountId << " AND " -// << addFilters(filter, sortMode, limit, offset, m_email_conv_attr_map, msgType); -// LOGD("%s", sqlWhereClause.str().c_str()); -// -// // Getting results from database -// msg_error_t err = email_query_mails(const_cast(sqlWhereClause.str().c_str()), -// &results, &resultsCount); -// if (EMAIL_ERROR_NONE != err) { -// LOGE("Getting mail list fail [%d]", err); -// -// if (EMAIL_ERROR_MAIL_NOT_FOUND == err) { -// resultsCount = 0; -// } else { -// throw UnknownException("Error while getting data from database."); -// } -// } -// -// // Assigning found emails to conversation -// for (int i = 0; i < resultsCount; ++i) { -// if (conversationsBag.find(results[i].thread_id) == conversationsBag.end()) { -// EmailConversationInfo info; -// info.id = results[i].thread_id; -// conversationsInfo.push_back(info); -// conversationsBag.insert(std::make_pair(results[i].thread_id, 0)); -// } -// -// if (!(static_cast(results[i].flags_seen_field))) { -// ++conversationsBag[results[i].thread_id]; -// } -// } -// -// for (std::vector::iterator it = conversationsInfo.begin(); -// it != conversationsInfo.end(); ++it) { -// (*it).unreadMessages = conversationsBag[(*it).id]; -// } -// -// email_free_mail_data(&results, resultsCount); -// return conversationsInfo; -//} + +std::vector MessagingDatabaseManager::findEmailConversations( + ConversationCallbackData* callback) +{ + LoggerD("Entered"); + std::ostringstream sqlWhereClause; + int resultsCount; + email_mail_data_t* results; + std::map conversationsBag; + std::vector conversationsInfo; + + // Adding filters query + AbstractFilterPtr filter = callback->getFilter(); + SortModePtr sortMode = callback->getSortMode(); + long limit = callback->getLimit(); + long offset = callback->getOffset(); + MessageType msgType = callback->getMessageServiceType(); + int accountId = callback->getAccountId(); + + sqlWhereClause << "WHERE " + << m_email_conv_attr_map["serviceId"].sql_name << " = " << accountId << " AND " + << addFilters(filter, sortMode, limit, offset, m_email_conv_attr_map, msgType); + LoggerD("%s", sqlWhereClause.str().c_str()); + + // Getting results from database + msg_error_t err = email_query_mails(const_cast(sqlWhereClause.str().c_str()), + &results, &resultsCount); + if (EMAIL_ERROR_NONE != err) { + LoggerE("Getting mail list fail [%d]", err); + + if (EMAIL_ERROR_MAIL_NOT_FOUND == err) { + resultsCount = 0; + } else { + throw UnknownException("Error while getting data from database."); + } + } + + // Assigning found emails to conversation + for (int i = 0; i < resultsCount; ++i) { + if (conversationsBag.find(results[i].thread_id) == conversationsBag.end()) { + EmailConversationInfo info; + info.id = results[i].thread_id; + conversationsInfo.push_back(info); + conversationsBag.insert(std::make_pair(results[i].thread_id, 0)); + } + + if (!(static_cast(results[i].flags_seen_field))) { + ++conversationsBag[results[i].thread_id]; + } + } + + for (std::vector::iterator it = conversationsInfo.begin(); + it != conversationsInfo.end(); ++it) { + (*it).unreadMessages = conversationsBag[(*it).id]; + } + + email_free_mail_data(&results, resultsCount); + return conversationsInfo; +} } // Messaging } // DeviceAPI diff --git a/src/messaging/messaging_database_manager.h b/src/messaging/messaging_database_manager.h index 1d9ecbef..0cbc431f 100755 --- a/src/messaging/messaging_database_manager.h +++ b/src/messaging/messaging_database_manager.h @@ -84,7 +84,7 @@ public: std::vector findShortMessages(FindMsgCallbackUserData* callback); std::pair findEmails(FindMsgCallbackUserData* callback); // std::vector findShortMessageConversations(ConversationCallbackData* callback); -// std::vector findEmailConversations(ConversationCallbackData* callback); + std::vector findEmailConversations(ConversationCallbackData* callback); private: MessagingDatabaseManager(); diff --git a/src/messaging/messaging_instance.cc b/src/messaging/messaging_instance.cc index bb39cb8f..c7df31d0 100644 --- a/src/messaging/messaging_instance.cc +++ b/src/messaging/messaging_instance.cc @@ -441,6 +441,31 @@ void MessagingInstance::MessageStorageFindConversations(const picojson::value& a picojson::object& out) { LoggerD("Entered"); + + picojson::object data = args.get(JSON_DATA).get(); + const double callbackId = args.get(JSON_CALLBACK_ID).get(); + + auto filter = MessagingUtil::jsonToAttributeFilter(data); + auto sortMode = MessagingUtil::jsonToSortMode(data); + long limit = static_cast + (MessagingUtil::getValueFromJSONObject(data, FIND_CONVERSATIONS_ARGS_LIMIT)); + long offset = static_cast + (MessagingUtil::getValueFromJSONObject(data, FIND_CONVERSATIONS_ARGS_OFFSET)); + int serviceId = static_cast(data.at(FUNCTIONS_HIDDEN_ARGS_SERVICE_ID).get()); + + ConversationCallbackData* callback = new ConversationCallbackData(); + callback->setFilter(filter); + callback->setLimit(limit); + callback->setOffset(offset); + callback->setAccountId(serviceId); + + auto json = std::shared_ptr(new picojson::value(picojson::object())); + picojson::object& obj = json->get(); + obj[JSON_CALLBACK_ID] = picojson::value(callbackId); + callback->setJson(json); + + auto storage = MessagingManager::getInstance().getMessageServiceEmail(serviceId)->getMsgStorage(); + storage->findConversations(callback); } void MessagingInstance::MessageStorageRemoveConversations(const picojson::value& args, diff --git a/src/messaging/messaging_util.cc b/src/messaging/messaging_util.cc index 39f44626..dccf1e70 100644 --- a/src/messaging/messaging_util.cc +++ b/src/messaging/messaging_util.cc @@ -318,6 +318,70 @@ picojson::value MessagingUtil::messageToJson(std::shared_ptr message) return v; } +picojson::value MessagingUtil::conversationToJson(std::shared_ptr conversation) +{ + picojson::object o; + + o[MESSAGE_CONVERSATION_ATTRIBUTE_ID] = picojson::value(std::to_string(conversation->getConversationId())); + + o[MESSAGE_CONVERSATION_ATTRIBUTE_TYPE] = + picojson::value(MessagingUtil::messageTypeToString(conversation->getType())); + + o[MESSAGE_CONVERSATION_ATTRIBUTE_TIMESTAMP] = + picojson::value(static_cast(conversation->getTimestamp())); + + o[MESSAGE_CONVERSATION_ATTRIBUTE_MESSAGE_COUNT] = + picojson::value(static_cast(conversation->getMessageCount())); + + o[MESSAGE_CONVERSATION_ATTRIBUTE_UNREAD_MESSAGES] = + picojson::value(static_cast(conversation->getUnreadMessages())); + + o[MESSAGE_CONVERSATION_ATTRIBUTE_PREVIEW] = + picojson::value(conversation->getPreview()); + + o[MESSAGE_CONVERSATION_ATTRIBUTE_IS_READ] = + picojson::value(conversation->getIsRead()); + + o[MESSAGE_CONVERSATION_ATTRIBUTE_FROM] = + picojson::value(conversation->getFrom()); + + o[MESSAGE_CONVERSATION_ATTRIBUTE_LAST_MESSAGE_ID] = + picojson::value(std::to_string(conversation->getLastMessageId())); + + std::vector array; + auto vectorToArray = [&array] (std::string& s)->void { + array.push_back(picojson::value(s)); + }; + + switch (conversation->getType()) { + case MessageType::SMS: + break; + case MessageType::MMS: + case MessageType::EMAIL: + + std::vector to = conversation->getTo(); + for_each(to.begin(), to.end(), vectorToArray); + o[MESSAGE_ATTRIBUTE_IN_RESPONSE_TO] = picojson::value(array); + array.clear(); + + std::vector cc = conversation->getCC(); + for_each(cc.begin(), cc.end(), vectorToArray); + o[MESSAGE_ATTRIBUTE_CC] = picojson::value(array); + array.clear(); + + std::vector bcc = conversation->getBCC(); + for_each(bcc.begin(), bcc.end(), vectorToArray); + o[MESSAGE_ATTRIBUTE_BCC] = picojson::value(array); + array.clear(); + + o[MESSAGE_ATTRIBUTE_SUBJECT] = picojson::value(conversation->getSubject()); + break; + } + + picojson::value v(o); + return v; +} + std::shared_ptr MessagingUtil::jsonToMessage(const picojson::value& json) { LoggerD("Entered"); diff --git a/src/messaging/messaging_util.h b/src/messaging/messaging_util.h index c008faf4..312ca29d 100644 --- a/src/messaging/messaging_util.h +++ b/src/messaging/messaging_util.h @@ -108,6 +108,7 @@ public: static picojson::value messageBodyToJson(std::shared_ptr body); static picojson::value messageToJson(std::shared_ptr message); + static picojson::value conversationToJson(std::shared_ptr conversation); static std::shared_ptr jsonToMessage(const picojson::value& json); static tizen::SortModePtr jsonToSortMode(const picojson::object& json); static tizen::AttributeFilterPtr jsonToAttributeFilter(const picojson::object& json);