[Messaging] findConversations implementation for email
authorRobert Karolak <r.karolak@samsung.com>
Mon, 29 Dec 2014 17:08:44 +0000 (18:08 +0100)
committerRobert Karolak <r.karolak@samsung.com>
Mon, 29 Dec 2014 17:12:38 +0000 (18:12 +0100)
[Verification] Code compiles withouts errors
Tested well in node console

Change-Id: Ice89c877d5304a3c2535f222020a1b941319c761
Signed-off-by: Robert Karolak <r.karolak@samsung.com>
src/messaging/email_manager.cc
src/messaging/email_manager.h
src/messaging/message_storage.h
src/messaging/message_storage_email.cc
src/messaging/message_storage_email.h
src/messaging/messaging_api.js
src/messaging/messaging_database_manager.cc
src/messaging/messaging_database_manager.h
src/messaging/messaging_instance.cc
src/messaging/messaging_util.cc
src/messaging/messaging_util.h

index 95351fd87e9e1d36f562a05c1c99808beaa47b4f..dfb868fecebd1786965a7347ebad80b1a4aaa413 100644 (file)
@@ -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<std::mutex> lock(m_mutex);
-//        std::vector<EmailConversationInfo> conversationsInfo =
-//                MessagingDatabaseManager::getInstance().findEmailConversations(callback);
-//        convListCount = conversationsInfo.size();
-//        LoggerD("Found %d conversations", convListCount);
-//
-//        for (int i = 0; i < convListCount; ++i) {
-//            std::shared_ptr<MessageConversation> 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<ConversationPtr,
-//                    JSMessageConversation>(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<std::mutex> lock(m_mutex);
+        std::vector<EmailConversationInfo> conversationsInfo =
+                MessagingDatabaseManager::getInstance().findEmailConversations(callback);
+        convListCount = conversationsInfo.size();
+        LoggerD("Found %d conversations", convListCount);
+
+        for (int i = 0; i < convListCount; ++i) {
+            std::shared_ptr<MessageConversation> 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<picojson::object>();
+
+            std::vector<picojson::value> response;
+            auto messages = callback->getConversations();
+            std::for_each(messages.begin(), messages.end(),
+                    [&response](std::shared_ptr<MessageConversation> &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()
 {
index 6fcd10deaef12514fc43f683a08b166cd9d9b0d1..d28a7685b8c8b223a443ddc9232986dff6dc6e05 100644 (file)
@@ -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);
 
index b0a04b469d044646163dfc403e0857ccc0f6a285..27ce421e737f23e479e7e7039e4ac4572610c10f 100644 (file)
@@ -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;
 
index f0878858689dffb3701d247cf282e45b0bd99cb1..a907e74f99b64acc943a1e59c1d00624479719d4 100644 (file)
@@ -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<ConversationCallbackData*>(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<void*>(callback));
+    if (!id) {
+        LoggerE("g_idle_add failed");
+        delete callback;
+        callback = NULL;
+    }
 }
 
 static gboolean removeConversationsTask(void* data)
index 76bd6a380c6caaa7ffae7b04f05119a69bb6aa0a..1f85bbf50842ee1e7ba3dc35c6e1d20965d887e2 100644 (file)
@@ -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();
 };
index 1051c035df720dc44d7dc91ecb414a6d6dc04325..955fdcf6e6a400156e064a5ac0a088732f42616c 100644 (file)
@@ -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) {
index 7a62e1c9bcfeed2fdaa4bc07cde6571a952f313a..a2af8c2d55356a470163f82c660cedc31b54b92c 100755 (executable)
@@ -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<int, email_mail_data_t*> MessagingDatabaseManager::findEmails(
 //    freeTable(&results);
 //    return conversationsIds;
 //}
-//
-//std::vector<EmailConversationInfo> MessagingDatabaseManager::findEmailConversations(
-//        ConversationCallbackData* callback)
-//{
-//    LOGD("Entered");
-//    std::ostringstream sqlWhereClause;
-//    int resultsCount;
-//    email_mail_data_t* results;
-//    std::map<int, int> conversationsBag;
-//    std::vector<EmailConversationInfo> 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<char*>(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<bool>(results[i].flags_seen_field))) {
-//            ++conversationsBag[results[i].thread_id];
-//        }
-//    }
-//
-//    for (std::vector<EmailConversationInfo>::iterator it = conversationsInfo.begin();
-//            it != conversationsInfo.end(); ++it) {
-//        (*it).unreadMessages = conversationsBag[(*it).id];
-//    }
-//
-//    email_free_mail_data(&results, resultsCount);
-//    return conversationsInfo;
-//}
+
+std::vector<EmailConversationInfo> MessagingDatabaseManager::findEmailConversations(
+        ConversationCallbackData* callback)
+{
+    LoggerD("Entered");
+    std::ostringstream sqlWhereClause;
+    int resultsCount;
+    email_mail_data_t* results;
+    std::map<int, int> conversationsBag;
+    std::vector<EmailConversationInfo> 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<char*>(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<bool>(results[i].flags_seen_field))) {
+            ++conversationsBag[results[i].thread_id];
+        }
+    }
+
+    for (std::vector<EmailConversationInfo>::iterator it = conversationsInfo.begin();
+            it != conversationsInfo.end(); ++it) {
+        (*it).unreadMessages = conversationsBag[(*it).id];
+    }
+
+    email_free_mail_data(&results, resultsCount);
+    return conversationsInfo;
+}
 
 } // Messaging
 } // DeviceAPI
index 1d9ecbef8f1646e47178775517c3d9db4a95bf42..0cbc431f35d2a3d57a118765b3f8d8e24700bd8f 100755 (executable)
@@ -84,7 +84,7 @@ public:
     std::vector<int> findShortMessages(FindMsgCallbackUserData* callback);
     std::pair<int, email_mail_data_t*> findEmails(FindMsgCallbackUserData* callback);
 //    std::vector<int> findShortMessageConversations(ConversationCallbackData* callback);
-//    std::vector<EmailConversationInfo> findEmailConversations(ConversationCallbackData* callback);
+    std::vector<EmailConversationInfo> findEmailConversations(ConversationCallbackData* callback);
 
 private:
     MessagingDatabaseManager();
index bb39cb8fac992cb0efc746fe80520ee1cd0c1b0e..c7df31d07471b50856ac487cf2a0111712a979db 100644 (file)
@@ -441,6 +441,31 @@ void MessagingInstance::MessageStorageFindConversations(const picojson::value& a
         picojson::object& out)
 {
     LoggerD("Entered");
+
+    picojson::object data = args.get(JSON_DATA).get<picojson::object>();
+    const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
+
+    auto filter = MessagingUtil::jsonToAttributeFilter(data);
+    auto sortMode = MessagingUtil::jsonToSortMode(data);
+    long limit = static_cast<long>
+            (MessagingUtil::getValueFromJSONObject<double>(data, FIND_CONVERSATIONS_ARGS_LIMIT));
+    long offset = static_cast<long>
+            (MessagingUtil::getValueFromJSONObject<double>(data, FIND_CONVERSATIONS_ARGS_OFFSET));
+    int serviceId = static_cast<int>(data.at(FUNCTIONS_HIDDEN_ARGS_SERVICE_ID).get<double>());
+
+    ConversationCallbackData* callback = new ConversationCallbackData();
+    callback->setFilter(filter);
+    callback->setLimit(limit);
+    callback->setOffset(offset);
+    callback->setAccountId(serviceId);
+
+    auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
+    picojson::object& obj = json->get<picojson::object>();
+    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,
index 39f4462625e4173a1e9d0f45c99d0e7459c10e35..dccf1e701ceca0aec32ad94f3d5ae8a306482222 100644 (file)
@@ -318,6 +318,70 @@ picojson::value MessagingUtil::messageToJson(std::shared_ptr<Message> message)
     return v;
 }
 
+picojson::value MessagingUtil::conversationToJson(std::shared_ptr<MessageConversation> 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<double>(conversation->getTimestamp()));
+
+    o[MESSAGE_CONVERSATION_ATTRIBUTE_MESSAGE_COUNT] =
+            picojson::value(static_cast<double>(conversation->getMessageCount()));
+
+    o[MESSAGE_CONVERSATION_ATTRIBUTE_UNREAD_MESSAGES] =
+            picojson::value(static_cast<double>(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<picojson::value> 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<std::string> to = conversation->getTo();
+            for_each(to.begin(), to.end(), vectorToArray);
+            o[MESSAGE_ATTRIBUTE_IN_RESPONSE_TO] = picojson::value(array);
+            array.clear();
+
+            std::vector<std::string> cc = conversation->getCC();
+            for_each(cc.begin(), cc.end(), vectorToArray);
+            o[MESSAGE_ATTRIBUTE_CC] = picojson::value(array);
+            array.clear();
+
+            std::vector<std::string> 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<Message> MessagingUtil::jsonToMessage(const picojson::value& json)
 {
     LoggerD("Entered");
index c008faf4d081555af641345afc626d8d35a8d303..312ca29d61d94c1f6312aa80a698608f9d102899 100644 (file)
@@ -108,6 +108,7 @@ public:
 
     static picojson::value messageBodyToJson(std::shared_ptr<MessageBody> body);
     static picojson::value messageToJson(std::shared_ptr<Message> message);
+    static picojson::value conversationToJson(std::shared_ptr<MessageConversation> conversation);
     static std::shared_ptr<Message> jsonToMessage(const picojson::value& json);
     static tizen::SortModePtr jsonToSortMode(const picojson::object& json);
     static tizen::AttributeFilterPtr jsonToAttributeFilter(const picojson::object& json);