2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 * @author Pawel Misiak (p.misiak@samsung.com)
27 #include <emf-types.h>
29 #include <dpl/log/log.h>
30 #include <dpl/assert.h>
31 #include <dpl/scoped_fclose.h>
32 #include <dpl/scoped_ptr.h>
33 #include <Commons/Exception.h>
34 #include <Commons/StringUtils.h>
35 #include <API/Messaging/MessageFactory.h>
36 #include <API/Messaging/EmailAccountInfo.h>
37 #include "Messaging.h"
39 #include "EmailService.h"
40 #include "EmailUtils.h"
41 #include "EmailConverter.h"
42 #include "MailSender.h"
44 #define LOG_ENTER LogDebug("---> ENTER");
45 #define LOG_EXIT LogDebug("---> EXIT");
48 using namespace WrtDeviceApis::Messaging;
49 using namespace WrtDeviceApis::Messaging::Api;
51 namespace WrtDeviceApis {
57 const Api::FolderType DEFAULT_FOLDER = Api::OUTBOX;
58 //const char* DEFAULT_FOLDER_NAME = EMF_OUTBOX_NAME;
60 const Api::FolderType DEFAULT_FOLDER = Api::DRAFTBOX;
61 //const char* DEFAULT_FOLDER_NAME = EMF_DRAFTBOX_NAME;
65 Email::Email(const string& id) : IMessage(Api::EMAIL, id)
70 if (getIdRef().empty()) {
73 // always read the message (after creation some of attributes change
77 catch (const Commons::PlatformException& ex) {
78 LogError("Exception: " << ex.DumpToString());
95 MailSender::getInstance().send(
96 Api::MessageFactory::convertToEmail(SharedFromThis())
102 void Email::sendCancel()
106 MailSender::getInstance().cancel(getIntId());
111 void Email::update(bool draftsOnly)
115 DPL::Mutex::ScopedLock mx(&m_updateMutex);
118 ThrowMsg(Commons::PlatformException, "Mail is NULL.");
121 if (!draftsOnly || (getCurrentFolder() == Api::DRAFTBOX)) {
129 LogWarning("Updating only read status. Folder: " << getCurrentFolder());
133 int error = email_update_message(getIntId(), m_mail.Get());
134 if (EMF_ERROR_NONE != error) {
135 LogWarning("Nothing to update or error. [" << error << "]");
141 int Email::getAccountId() const
146 void Email::readAllData()
151 void Email::moveToFolder(const Api::FolderType newFolder)
155 moveToFolder(EmailConverter::toMailboxName(newFolder));
160 void Email::moveToFolder(const string& newFolder)
164 int accountId = Messaging::getInstance().getEmailAccountId(getFromRef());
165 ScopedMailbox mailbox(
166 EmailService::createMailbox(accountId, newFolder.c_str())
169 int mailId = getIntId();
171 int error = email_move_mail_to_mailbox(&mailId, 1, mailbox.Get());
172 if (EMF_ERROR_NONE != error) {
174 Commons::PlatformException,
175 "Couldn't move mail to folder: " << newFolder << ". [" <<
180 void Email::copyToFolder(const FolderType newFolder)
184 copyToFolder(EmailConverter::toMailboxName(newFolder));
189 void Email::copyToFolder(const string& newFolder)
195 int accountId = Messaging::getInstance().getEmailAccountId(getFromRef());
197 ScopedMail mail(EmailService::cloneMail(m_mail.Get()));
198 ScopedMailbox mailbox(
199 EmailService::createMailbox(accountId, newFolder.c_str())
202 int mailId = EmailService::addMailToMailbox(mail.Get(), mailbox.Get());
203 // TODO Is following check necessary?
205 ThrowMsg(Commons::PlatformException, "Cloned mail didn't get new id.");
213 EmailService::deleteMail(m_accountId, getIntId());
220 EmailAccountInfo account = IMessaging::getInstance().getCurrentEmailAccount();
221 ScopedMail mail(EmailService::createMail(account));
222 ScopedMailbox mailbox(
223 EmailService::getMailboxByType(account.getIntId(),
224 EMF_MAILBOX_TYPE_DRAFT)
226 setId(convertId(EmailService::addMailToMailbox(mail.Get(), mailbox.Get())));
227 setFolderType(Api::DRAFTBOX);
236 EmailAccountInfo account = Messaging::getInstance().getCurrentEmailAccount();
238 m_mail.Reset(EmailService::readMail(account.getIntId(), getIntId()));
240 if (m_mail->head) { readHeader(); }
241 if (m_mail->body) { readBody(); }
242 if (m_mail->info) { readInfo(); }
245 EmailService::getMailboxByMailId(account.getIntId(), getIntId())
247 setFolderType(EmailConverter::toFolderType(m_mailbox->mailbox_type));
252 void Email::readHeader()
256 Assert(m_mail && m_mail->head && "Header is NULL.");
258 if (m_mail->head->subject) {
259 setSubject(m_mail->head->subject);
262 if (m_mail->head->to) {
263 appendToRecipients(EmailUtils::stripAddressLine(m_mail->head->to));
266 if (m_mail->head->cc) {
267 appendCcRecipients(EmailUtils::stripAddressLine(m_mail->head->cc));
270 if (m_mail->head->bcc) {
271 appendBccRecipients(EmailUtils::stripAddressLine(m_mail->head->bcc));
276 struct tm tmpTime = *(localtime(&rawtime));
277 tmpTime.tm_year = m_mail->head->datetime.year;
278 tmpTime.tm_mon = m_mail->head->datetime.month;
279 tmpTime.tm_mday = m_mail->head->datetime.day;
280 tmpTime.tm_hour = m_mail->head->datetime.hour;
281 tmpTime.tm_min = m_mail->head->datetime.minute;
282 tmpTime.tm_sec = m_mail->head->datetime.second;
284 setDateTime(tmpTime);
286 if (m_mail->head->from) {
288 from.setRecipients(m_mail->head->from);
289 setSourceAddress(from);
290 setSourceAddressValidity(true); //not needed to update in platform
296 void Email::readBody()
300 Assert(m_mail && m_mail->body && "Body is NULL.");
302 if (m_mail->body->plain) {
303 DPL::ScopedFClose file(::fopen(m_mail->body->plain, "r"));
305 ThrowMsg(Commons::PlatformException,
306 "Cannot read body file: " << m_mail->body->plain);
308 fseek(file.Get(), 0, SEEK_END);
309 long int size = ftell(file.Get());
310 fseek(file.Get(), 0, SEEK_SET);
311 DPL::ScopedPtr<char> data(new char[size + 1]);
312 memset(data.Get(), 0, size + 1);
313 fread(data.Get(), 1, size, file.Get());
317 if (m_mail->body->attachment && m_mail->body->attachment_num > 0) {
318 LogDebug("reading attachments");
319 emf_attachment_info_t* attach = m_mail->body->attachment;
320 for (int i = 0; i < m_mail->body->attachment_num; ++i) {
322 ThrowMsg(Commons::PlatformException,
323 "Attachment list shorter than expected.");
326 IAttachmentPtr tmpAtt = appendAttachment(attach->savename,
328 tmpAtt->rename(attach->name);
329 attach = attach->next;
331 catch (const Commons::Exception& ex) {
332 LogError("Error while trying to append attachment " <<
333 attach->savename << ": " << ex.DumpToString());
341 void Email::readInfo()
345 Assert(m_mail && m_mail->info && "Info is NULL.");
347 setReadStatus(m_mail->info->flags.seen == 1);
349 m_accountId = m_mail->info->account_id;
352 EmailConverter::toMessagePriority(
353 m_mail->info->extra_flags.priority
356 setSize(m_mail->info->rfc822_size);
361 void Email::updateBody()
365 if (isBodyValid()) { return; }
368 ThrowMsg(Commons::PlatformException, "Mail is NULL.");
372 ThrowMsg(Commons::PlatformException, "Body is NULL.");
374 if (!m_mail->body->plain) {
375 ThrowMsg(Commons::PlatformException, "Body file is NULL.");
378 ThrowMsg(Commons::PlatformException, "Info is NULL.");
381 FILE* f = fopen(m_mail->body->plain, "w");
383 fprintf(f, getBodyRef().c_str());
386 m_mail->info->body_downloaded = true;
387 setBodyValidity(true);
392 void Email::updateSubject()
396 if (isSubjectValid()) { return; }
398 LogDebug("update subject, msgId=" << getIdRef());
401 ThrowMsg(Commons::PlatformException, "Mail not allocated.");
405 m_mail->head = EmailService::alloc<emf_mail_head_t>();
408 m_mail->head->subject = Commons::String::strdup(getSubjectRef());
409 setSubjectValidity(true);
414 void Email::updateReadStatus()
418 if (isReadStatusValid()) { return; }
420 LogDebug("update read, msgId=" << getIdRef());
423 ThrowMsg(Commons::PlatformException, "Mail not allocated.");
427 EmailService::alloc<emf_mail_info_t>();
430 m_mail->info->flags.seen = isRead();
431 setReadStatusValidity(true);
436 void Email::updateRecipients()
440 if (getToValidity() && getCcValidity() && getBccValidity()) { return; }
443 ThrowMsg(Commons::PlatformException, "Mail is NULL.");
447 m_mail->head = EmailService::alloc<emf_mail_head_t>();
450 if (!getToValidity()) {
451 std::string addressLine = EmailUtils::formatAddressLine(getToRecipients());
452 if (m_mail->head->to) {
453 free(m_mail->head->to);
455 m_mail->head->to = Commons::String::strdup(addressLine);
459 if (!getCcValidity()) {
460 std::string addressLine = EmailUtils::formatAddressLine(getCcRecipients());
461 if (m_mail->head->cc) {
462 free(m_mail->head->cc);
464 m_mail->head->cc = Commons::String::strdup(addressLine);
468 if (!getBccValidity()) {
469 std::string addressLine = EmailUtils::formatAddressLine(
471 if (m_mail->head->bcc) {
472 free(m_mail->head->bcc);
474 m_mail->head->bcc = Commons::String::strdup(addressLine);
475 setBccValidity(true);
481 void Email::updateFrom()
485 if (getFromValidity()) { return; }
488 ThrowMsg(Commons::PlatformException, "Mail is NULL.");
492 EmailService::alloc<emf_mail_info_t>();
495 m_mail->info->account_id = Messaging::getInstance().getEmailAccountId(
497 // TODO Update m_mail->head->from as well
499 setFromValidity(true);
504 void Email::updateAttachments()
508 if (isAttachmentsValid()) { return; }
511 ThrowMsg(Commons::PlatformException, "Mail is NULL.");
514 emf_attachment_info_t* attachment = NULL;
516 LogDebug("update attachments, msgId=" << getIdRef());
519 m_mail->body = EmailService::alloc<emf_mail_body_t>();
521 m_mail->body->attachment_num = 0;
522 if (NULL != m_mail->body->attachment) {
523 EmailService::freeAttachment(m_mail->body->attachment);
524 m_mail->body->attachment = NULL;
528 std::size_t attachmentSize = getAttachmentsCount();
529 if (attachmentSize > 0) {
531 ThrowMsg(Commons::PlatformException, "Mail info is NULL.");
534 for (std::size_t i = 0; i < attachmentSize; ++i) {
535 IAttachmentPtr att = getAttachment(i);
540 LogDebug("updating attachment=" << att->getShortName());
542 attachment = EmailService::alloc<emf_attachment_info_t>();
543 attachment->name = Commons::String::strdup(att->getShortName());
544 attachment->savename = Commons::String::strdup(
547 attachment->downloaded = true;
548 attachment->next = NULL;
550 int error = email_add_attachment(m_mailbox.Get(),
553 if (EMF_ERROR_NONE != error) {
554 ThrowMsg(Commons::PlatformException,
555 "Error while adding attachment. [" << error << "]");
558 EmailService::freeAttachment(attachment);
561 setAttachmentsValidity(true);
564 Catch(Commons::PlatformException) {
565 EmailService::freeAttachment(attachment);
572 void Email::updatePriority()
576 if (isPriorityValid()) { return; }
579 ThrowMsg(Commons::PlatformException, "Mail not allocated.");
583 m_mail->info = EmailService::alloc<emf_mail_info_t>();
586 m_mail->info->extra_flags.priority = EmailConverter::toMailPriority(
588 setPriorityValid(true);
593 int Email::getIntId() const
595 return convertId(getIdRef());