void MojoDatabase::ReserveIds(Signal::SlotRef slot, int count) { if (count > RESERVE_ID_MAX) count = RESERVE_ID_MAX; MojErr err = m_dbClient.reserveIds(slot, count); ErrorToException(err); }
void MojoDatabase::MoveDeletedEmailToTrash (Signal::SlotRef slot, const MojObject& emailId, const MojObject& trashFolderId) { MojObject email; MojErr err = email.put(PopEmailAdapter::ID, emailId); ErrorToException(err); err = email.put(EmailSchema::FOLDER_ID, trashFolderId); ErrorToException(err); err = email.put("_del", false); ErrorToException(err); MojLogInfo(PopClient::s_log, "Moving email '%s' to trash folder '%s'", AsJsonString(emailId).c_str(), AsJsonString(trashFolderId).c_str()); err = m_dbClient.merge(slot, email); ErrorToException(err); }
void MovePopEmailsCommand::RunImpl() { CommandTraceFunction(); try { if (!m_client.GetAccount().get()) { MojString err; err.format("Account is not loaded for '%s'", AsJsonString( m_client.GetAccountId()).c_str()); throw MailException(err.data(), __FILE__, __LINE__); } MojErr err = m_payload.getRequired("accountId", m_accountId); ErrorToException(err); m_activity = ActivityParser::GetActivityFromPayload(m_payload); if (m_activity.get()) { m_activity->SetSlots(m_activityUpdateSlot, m_activityErrorSlot); m_activity->Adopt(m_client); return; } else { GetEmailsToMove(); } } catch (const std::exception& ex) { m_msg->replyError(MojErrInternal, ex.what()); Failure(ex); } catch (...) { MailException ex("unknown exception", __FILE__, __LINE__); m_msg->replyError(MojErrInternal, ex.what()); Failure(ex); } }
void MockRequest::ReplySuccess(MojObject response) { MojErr err = response.put("returnValue", true); ErrorToException(err); Reply(response, MojErrNone); }
MojErr MovePopEmailsCommand::EmailsMovedResponse(MojObject& response, MojErr err) { try { ErrorToException(err); ActivityBuilder ab; m_client.GetActivityBuilderFactory()->BuildMoveEmailsWatch(ab); m_activity->UpdateAndComplete(m_client, ab.GetActivityObject()); m_msg->replySuccess(); if (m_inboxEmailsMoved.size() > 0) { // add the list of UIDs into UidCache GetUidCache(); } else { Complete(); } } catch (const std::exception& ex) { m_msg->replyError(MojErrInternal, ex.what()); Failure(ex); } catch (...) { m_msg->replyError(MojErrInternal); Failure(MailException("unknown exception", __FILE__, __LINE__)); } return MojErrNone; }
void SyncAccountCommand::RunImpl() { try { if (!m_client.GetAccount().get()) { MojString err; err.format("Account is not loaded for '%s'", AsJsonString( m_client.GetAccountId()).c_str()); throw MailException(err.data(), __FILE__, __LINE__); } m_account = m_client.GetAccount(); if(m_account->HasPassword()) { m_accountId = m_account->GetAccountId(); MojObject inboxFolderId = m_account->GetInboxFolderId(); MojLogInfo(m_log, "Creating command to sync inbox emails"); MojErr err = m_payload.put(EmailSchema::FOLDER_ID, inboxFolderId); ErrorToException(err); m_client.SyncFolder(m_payload); } else { MojLogInfo(m_log, "No password! Sync aborted!"); } Complete(); } catch (const std::exception& ex) { Failure(ex); } catch (...) { Failure(MailException("Unknown exception", __FILE__, __LINE__)); } }
void MojoDatabase::UpdateAccountInitialSync(Signal::SlotRef slot, const MojObject& accountId, bool sync) { //MojLogInfo(PopClient::s_log, "Updating account '%s' initialSynced to %d", AsJsonString(accountId).c_str(), sync); MojObject account; MojErr err = account.putBool(PopAccountAdapter::INITIAL_SYNC, sync); ErrorToException(err); MojDbQuery query; err = query.from(PopAccountAdapter::POP_ACCOUNT_KIND); ErrorToException(err); err = query.where(PopAccountAdapter::ACCOUNT_ID, MojDbQuery::OpEq, accountId); ErrorToException(err); err = m_dbClient.merge(slot, query, account); ErrorToException(err); }
MojRefCountedPtr<MojServiceRequest> BusClient::CreateRequest() { MojRefCountedPtr<MojServiceRequest> req; MojErr err = m_service->createRequest(req); ErrorToException(err); return req; }
MojErr AuthYahooCommand::GetYahooCookiesSlot(MojObject& response, MojErr err) { MojLogTrace(m_log); try { ResponseToException(response, err); MojObject object; err = response.getRequired("tCookie", m_tCookie); ErrorToException(err); err = response.getRequired("yCookie", m_yCookie); ErrorToException(err); } catch (const std::exception& e) { MojLogInfo(m_log, "Failed to retrieve Yahoo cookies, failing login: %s", e.what()); // FIXME: We should possibly try to decode and pass along a specific error SmtpSession::SmtpError error; error.errorCode = MailError::ACCOUNT_UNAVAILABLE; error.errorOnAccount = true; error.internalError = std::string("Unable to retrieve yahoo cookies: ") + e.what(); m_session.AuthYahooFailure(error); Complete(); return MojErrNone; } catch (...) { MojLogInfo(m_log, "Failed to retrieve Yahoo cookies, failing login: unknown exception"); // FIXME: We should possibly try to decode and pass along a specific error SmtpSession::SmtpError error; error.errorCode = MailError::ACCOUNT_UNAVAILABLE; error.errorOnAccount = true; error.internalError = "Unable to retrieve yahoo cookies: unknown exception"; m_session.AuthYahooFailure(error); Complete(); return MojErrNone; } m_state = State_SendingYCookie; WriteCommand(); return MojErrNone; }
void AccountFinderCommand::GetAccount() { CommandTraceFunction(); try { MojObject params; MojErr err = params.put("accountId", m_accountId); ErrorToException(err); err = m_client.CreateRequest()->send(m_getAccountSlot, "com.palm.service.accounts","getAccountInfo", params); ErrorToException(err); } catch (const std::exception& ex) { Failure(ex); } catch (...) { Failure(MailException("unknown exception", __FILE__, __LINE__)); } }
void BusClient::SendRequest(MojServiceRequest::ReplySignal::SlotRef handler, const MojChar* service, const MojChar* method, const MojObject& payload, MojUInt32 numReplies) { MojRefCountedPtr<MojServiceRequest> req = CreateRequest(); MojErr err = req->send(handler, service, method, payload, numReplies); ErrorToException(err); }
MojString ImapActivityFactory::FormatName(const char* name, const MojObject& accountId, const MojObject& folderId) { MojString formattedName; MojErr err = formattedName.format("%s/accountId=%s/folderId=%s", name, AsJsonString(accountId).c_str(), AsJsonString(folderId).c_str()); ErrorToException(err); return formattedName; }
MojErr PopAccountUpdateCommand::GetPasswordResponse(MojObject& response, MojErr err) { CommandTraceFunction(); try { // check the result first ErrorToException(err); MojObject credentials; err = response.getRequired("credentials", credentials); ErrorToException(err); MojString password; err = credentials.getRequired("password", password); ErrorToException(err); boost::shared_ptr<PopAccount> newPopAccount(new PopAccount()); PopAccountAdapter::GetPopAccountFromTransportObject(m_transportObj, *(newPopAccount.get())); newPopAccount->SetPassword(password.data()); boost::shared_ptr<PopAccount> oldPopAccount = m_client.GetAccount(); if (!oldPopAccount.get()) { m_callSyncFolderOnClient = true; } else if (newPopAccount->GetPort() != oldPopAccount->GetPort() || newPopAccount->GetEncryption() != oldPopAccount->GetEncryption() || newPopAccount->GetUsername() != oldPopAccount->GetUsername() || newPopAccount->GetSyncFrequencyMins() != oldPopAccount->GetSyncWindowDays() || newPopAccount->GetHostName() != oldPopAccount->GetHostName()) { m_callSyncFolderOnClient = true; } // Should be initial sync if the old account does not exist // or the old account is in initial sync state. newPopAccount->SetInitialSync(!oldPopAccount.get() || oldPopAccount->IsInitialSync()); m_client.SetAccount(newPopAccount); UpdateAccountWatchActivity(); } catch (const std::exception& ex) { Failure(ex); } catch (...) { Failure(MailException("unknown exception", __FILE__, __LINE__)); } return MojErrNone; }
void MojoDatabase::UpdateEmailParts(Signal::SlotRef slot, const MojObject& emailId, const MojObject& parts, bool autoDownload) { MojObject email; MojErr err = email.put(PopEmailAdapter::ID, emailId); ErrorToException(err); err = email.put(EmailSchema::PARTS, parts); ErrorToException(err); if ((!parts.undefined() && !parts.null() && parts.size() > 0) || !autoDownload) { err = email.put(PopEmailAdapter::DOWNLOADED, true); ErrorToException(err); } MojLogDebug(PopClient::s_log, "Updating email '%s' with parts: '%s'", AsJsonString(emailId).c_str(), AsJsonString(parts).c_str()); err = m_dbClient.merge(slot, email); ErrorToException(err); }
void MojoDatabase::GetEmails(Signal::SlotRef slot, const MojObject& folderId, MojInt32 limit) { MojDbQuery q; MojErr err = q.from(PopEmailAdapter::POP_EMAIL_KIND); ErrorToException(err); err = q.where(EmailSchema::FOLDER_ID, MojDbQuery::OpEq, folderId); ErrorToException(err); err = q.order(EmailSchema::TIMESTAMP); ErrorToException(err); q.limit(limit); q.desc(true); err = m_dbClient.find(slot, q); ErrorToException(err); }
void PopAccountUpdateCommand::GetPassword() { try { MojObject params; MojErr err = params.put("accountId", m_accountId); ErrorToException(err); err = params.putString("name", "common"); ErrorToException(err); err = m_client.CreateRequest()->send(m_getPasswordSlot, "com.palm.service.accounts","readCredentials", params); ErrorToException(err); } catch (const std::exception& ex) { Failure(ex); } catch (...) { Failure(MailException("unknown exception", __FILE__, __LINE__)); } }
void FileCacheClient::ExpireCacheObject(ReplySignal::SlotRef slot, const char* pathName) { MojErr err; MojObject payload; err = payload.putString("pathName", pathName); ErrorToException(err); m_busClient.SendRequest(slot, FILECACHE_SERVICE, "ExpireCacheObject", payload); }
MojErr PopAccountUpdateCommand::CreateActivityResponse(MojObject& response, MojErr err) { CommandTraceFunction(); try { ErrorToException(err); MojString json; err = response.toJson(json); ErrorToException(err); Sync(); } catch (const std::exception& ex) { Failure(ex); } catch (...) { Failure(MailException("unknown exception", __FILE__, __LINE__)); } return MojErrNone; }
void ScheduleRetryCommand::ScheduleRetry() { CommandTraceFunction(); ImapActivityFactory factory; ActivityBuilder ab; // Get current retry interval from account EmailAccount::RetryStatus retryStatus = m_client.GetAccount().GetRetry(); int interval = retryStatus.GetInterval(); if(interval < INITIAL_RETRY_SECONDS) { interval = INITIAL_RETRY_SECONDS; } else if(interval < SECOND_RETRY_SECONDS) { interval = SECOND_RETRY_SECONDS; } else if(interval >= MAX_RETRY_SECONDS) { interval = MAX_RETRY_SECONDS; } else { // TODO: only update this on actual retry? interval *= RETRY_MULTIPLIER; } // Update account just in case it wasn't within the limit retryStatus.SetInterval(interval); retryStatus.SetCount(retryStatus.GetCount() + 1); m_client.GetAccount().SetRetry(retryStatus); factory.BuildSyncRetry(ab, m_client.GetAccountId(), m_folderId, interval, m_reason); MojErr err; MojObject payload; err = payload.put("activity", ab.GetActivityObject()); ErrorToException(err); err = payload.put("start", true); ErrorToException(err); err = payload.put("replace", true); MojLogInfo(m_log, "scheduling retry in %.1f minutes for account %s", float(interval) / 60, m_client.GetAccountIdString().c_str()); m_client.SendRequest(m_scheduleRetrySlot, "com.palm.activitymanager", "create", payload); }
MojErr UpSyncSentEmailsCommand::GetSentFolderNameResponse(MojObject& response, MojErr err) { try { ErrorToException(err); MojObject folderObj; DatabaseAdapter::GetOneResult(response, folderObj); MojString sentFolderName; err = folderObj.getRequired(ImapFolderAdapter::SERVER_FOLDER_NAME, sentFolderName); ErrorToException(err); m_sentFolderName.assign(sentFolderName); GetSentEmails(); } CATCH_AS_FAILURE return MojErrNone; }
void SmtpAccountEnableCommand::CreateSmtpConfigWatch() { SmtpActivityFactory factory; ActivityBuilder ab; factory.BuildSmtpConfigWatch(ab, m_client.GetAccountId(), m_accountRev); // Create payload MojObject payload; MojErr err; err = payload.put("activity", ab.GetActivityObject()); ErrorToException(err); err = payload.put("start", true); ErrorToException(err); err = payload.put("replace", true); ErrorToException(err); m_client.SendRequest(m_createSmtpConfigWatchSlot, "com.palm.activitymanager", "create", payload); }
MojErr PopAccountUpdateCommand::GetAccountResponse(MojObject& response, MojErr err) { try { ErrorToException(err); MojObject results; err = response.getRequired(_T("results"), results); ErrorToException(err); if (results.size() > 0 && results.at(0, m_transportObj)) { GetPassword(); } } catch (const std::exception& ex) { Failure(ex); } catch (...) { Failure(MailException("unknown exception", __FILE__, __LINE__)); } return MojErrNone; }
void PopAccountUpdateCommand::RunImpl() { MojString json; MojErr err = m_payload.toJson(json); ErrorToException(err); MojLogDebug(m_log, "PopAccountUpdateCommand with payload %s", json.data()); m_accountId = m_client.GetAccountId(); m_activityBuilderFactory->SetAccountId(m_accountId); m_client.GetDatabaseInterface().GetAccount(m_getAccountSlot, m_accountId); }
void SaveEmailCommand::WriteToFileCache(MojObject &part, const MojString &pathName) { MojErr err; MojString content; err = part.getRequired("content", content); ErrorToException(err); // FIXME: make this async FILE *fp = fopen(pathName.data(), "w"); if(fp) { fwrite(content.data(), sizeof(MojChar), content.length(), fp); fclose(fp); } else { throw MailException("error opening file cache path", __FILE__, __LINE__); } // Cancel subscription to signal that we're done writing m_fileCacheInsertedSlot.cancel(); MojString type; err = part.getRequired(EmailSchema::Part::TYPE, type); ErrorToException(err); if (type == EmailSchema::Part::Type::BODY) { std::string previewText = PreviewTextGenerator::GeneratePreviewText(content.data(), MAX_SUMMARY_LENGTH, true); err = m_email.putString(EmailSchema::SUMMARY, previewText.c_str()); ErrorToException(err); } // Delete content field so it doesn't get written to the database bool wasDeleted; part.del("content", wasDeleted); // Next step if(m_partsIt == m_partsArray.arrayEnd()) PersistToDatabase(); // done else CreateNextCacheObject(); // more parts remaining return; }
void SmtpActivityFactory::BuildSmtpConfigWatch(ActivityBuilder& ab, const MojObject& accountId, MojInt64 rev) { MojErr err; MojString name; err = name.format(ACCOUNT_WATCH_ACTIVITY_FMT, AsJsonString(accountId).c_str()); ErrorToException(err); // description of watch MojString desc; err = desc.format("Watches SMTP config on account %s", AsJsonString(accountId).c_str()); ErrorToException(err); // activity to setup watch ab.SetName(name); ab.SetDescription(desc.data()); ab.SetPersist(true); ab.SetExplicit(true); ab.SetRequiresInternet(false); // trigger even if we don't have a network connection ab.SetImmediate(true, ActivityBuilder::PRIORITY_LOW); // setup trigger // NOTE: how to trigger only on SMTP config change? MojDbQuery trigger; err = trigger.from("com.palm.mail.account:1"); ErrorToException(err); err = trigger.where("accountId", MojDbQuery::OpEq, accountId); ErrorToException(err); if (rev > 0) { trigger.where("_revSmtp", MojDbQuery::OpGreaterThan, rev); } ab.SetDatabaseWatchTrigger(trigger); MojObject params; err = params.put("accountId", accountId); ErrorToException(err); ab.SetCallback(ACCOUNT_UPDATED_BUS_METHOD, params); ab.SetMetadata(params); }
void SaveEmailCommand::CreateNextCacheObject() { MojErr err; for(; m_partsIt != m_partsArray.arrayEnd(); ++m_partsIt) { MojObject& part = *m_partsIt; bool hasContent; MojString content; err = part.get("content", content, hasContent); ErrorToException(err); if(hasContent) { MojString cacheType; cacheType.assign("email"); bool hasDisplayName; MojString displayName; err = part.get("displayName", displayName, hasDisplayName); ErrorToException(err); MojString cacheFileName; if(hasDisplayName && displayName.length() > 0) { cacheFileName.assign(displayName); } else { // FIXME only for HTML parts cacheFileName.assign("body.html"); } MojLogDebug(m_log, "creating a file cache entry"); m_client.GetFileCacheClient().InsertCacheObject(m_fileCacheInsertedSlot, cacheType, cacheFileName, content.length(), EMAIL_FILECACHE_COST, EMAIL_NO_LIFE_TIME); // Exit method and wait for response return; } } // If this is the last part with content, persist to database now PersistToDatabase(); }
MojErr ScheduleRetryCommand::UpdateAccountResponse(MojObject& response, MojErr err) { CommandTraceFunction(); try { ErrorToException(err); Complete(); } CATCH_AS_FAILURE return MojErrNone; }
// Tell SMTP that the account has been updated; only if the credentials changed void PopAccountUpdateCommand::NotifySmtp() { CommandTraceFunction(); MojErr err; MojObject payload; err = payload.put("accountId", m_client.GetAccountId()); ErrorToException(err); m_client.SendRequest(m_notifySmtpSlot, "com.palm.smtp", "credentialsChanged", payload); }
MojErr ScheduleRetryCommand::ScheduleRetryResponse(MojObject& response, MojErr err) { CommandTraceFunction(); try { ErrorToException(err); CancelActivities(); } CATCH_AS_FAILURE return MojErrNone; }
void FileCacheClient::InsertCacheObject(ReplySignal::SlotRef slot, const char* typeName, const char* fileName, MojInt64 size, MojInt64 cost, MojInt64 lifetime) { MojErr err; MojObject payload; err = payload.putString("typeName", typeName); ErrorToException(err); err = payload.putString("fileName", fileName); ErrorToException(err); // Size must be >0 and larger than the actual content. // If the content is empty, we'll use 1 so FileCache doesn't complain. err = payload.put("size", size > 0 ? size : 1); ErrorToException(err); if(cost >= 0) { err = payload.put("cost", cost); ErrorToException(err); } if(lifetime >= 0) { err = payload.put("lifetime", lifetime); ErrorToException(err); } err = payload.put("subscribe", true); ErrorToException(err); m_busClient.SendRequest(slot, FILECACHE_SERVICE, "InsertCacheObject", payload, MojServiceRequest::Unlimited); }